2011-02-25 13 views
14

Busco para emular la funcionalidad de la aplicación de música más reciente, a saber, el pequeño cursor que aparece, que le permite a uno para desplazarse súper rápido al artista/álbum/pista que están buscando:Crear fácil desplazamiento alfabético en ListView?

"Super Scrolling" Regular Scrolling

¿Hay algún método para habilitar una funcionalidad como esta en un ListView en el SDK de Android?

+1

Tenga en cuenta de este error: http://code.google.com/p/android/issues/detail?id=9054 – tomash

+0

Gracias por eso. Célebre. –

+0

Estoy haciendo algo similar AQUÍ http://stackoverflow.com/questions/10224233/alphabetindexer-with-custom-adapter-managed-by-loadermanager – toobsco42

Respuesta

14

Tener su adaptador lista implementar SectionIndexer. La aplicación de música también hace uso de AlphabetIndexer para hacer algo del trabajo pesado. También use setFastScrollEnabled(true) en el ListView real para habilitar esto.

Editar: Si no está utilizando un CursorAdapter, no podrá utilizar AlphabetIndexer. Es posible que intente buscar en la implementación here y ver lo difícil que sería para adaptarla a trabajar con un ArrayAdapter.

+0

Ok, dulce, pero ¿cómo implemento 'SectionIndexer'? Como mi adaptador de lista es 'ArrayAdapter', ¿cómo puedo obtener un cursor para que pase al' AlphabetIndexer'? Tengo datos bastante simples que solo necesito agrupar alfabéticamente por nombre, de ahí el deseo de usar 'AlphabetIndexer'. –

+0

Perfecto, gracias. Examinaré la implementación de la interfaz 'SectionIndexer' en mi adaptador y proporcionaré mis secciones. –

+1

código de muestra: tenga en cuenta http: //www.anddev.org/tutusing_alphabetindexer_for_fastscrolling_listview-t10282.html – DroidBot

2

para recoger los detalles acerca de los elementos que se muestran en una vista de lista, puede hacer esto:

@Override 
     public void onScroll(AbsListView view, int firstVisibleItem, 
       int visibleItemCount, int totalItemCount) { 

      albumButton.setText(songs.get(firstVisibleItem).getAlbum()); 

     } 

No es esto un poco más simple? Aquí, 'canciones' es una matriz de objetos Song. Incluso puede obtener el último elemento visible agregando firstVisibleItem + visibleItemCount. Encontré que esta técnica es muy útil. Entonces obtendrías la primera letra de cada canción. Supongo que el cuadro gris que contiene la letra en la aplicación de música que ha publicado es una especie de cuadro de diálogo.

De todos modos, espero que esto ayude. Soy consciente de que llego tarde, pero esto es para las personas futuras

4

Aquí está la subclase de ArrayAdapter que estoy usando. Tenga en cuenta que la objects que pase en que ya ha sido ordenados alfabéticamente, con Collections.sort(objects).

class SectionIndexingArrayAdapter<T> extends ArrayAdapter<T> implements 
     SectionIndexer { 

    HashMap<String, Integer> sectionsMap = new HashMap<String, Integer>(); 
    ArrayList<String> sectionsList = new ArrayList<String>(); 

    ArrayList<Integer> sectionForPosition = new ArrayList<Integer>(); 
    ArrayList<Integer> positionForSection = new ArrayList<Integer>(); 

    public SectionIndexingArrayAdapter(Context context, int textViewResourceId, 
      List<T> objects) { 
     super(context, textViewResourceId, objects); 

     // Note that List<T> objects has already been sorted alphabetically 
     // e.g. with Collections.sort(objects) **before** being passed to 
     // this constructor. 

     // Figure out what the sections should be (one section per unique 
     // initial letter, to accommodate letters that might be missing, 
     // or characters like ,) 
     for (int i = 0; i < objects.size(); i++) { 
      String objectString = objects.get(i).toString(); 
      if (objectString.length() > 0) { 
       String firstLetter = objectString.substring(0, 1).toUpperCase(); 
       if (!sectionsMap.containsKey(firstLetter)) { 
        sectionsMap.put(firstLetter, sectionsMap.size()); 
        sectionsList.add(firstLetter); 
       } 
      } 
     } 

     // Calculate the section for each position in the list. 
     for (int i = 0; i < objects.size(); i++) { 
      String objectString = objects.get(i).toString(); 
      if (objectString.length() > 0) { 
       String firstLetter = objectString.substring(0, 1).toUpperCase(); 
       if (sectionsMap.containsKey(firstLetter)) { 
        sectionForPosition.add(sectionsMap.get(firstLetter)); 
       } else 
        sectionForPosition.add(0); 
      } else 
       sectionForPosition.add(0); 
     } 

     // Calculate the first position where each section begins. 
     for (int i = 0; i < sectionsMap.size(); i++) 
      positionForSection.add(0); 
     for (int i = 0; i < sectionsMap.size(); i++) { 
      for (int j = 0; j < objects.size(); j++) { 
       Integer section = sectionForPosition.get(j); 
       if (section == i) { 
        positionForSection.set(i, j); 
        break; 
       } 
      } 
     } 
    } 

    // The interface methods. 

    public int getPositionForSection(int section) { 
     return positionForSection.get(section); 
    } 

    public int getSectionForPosition(int position) { 
     return sectionForPosition.get(position); 
    } 

    public Object[] getSections() { 
     return sectionsList.toArray(); 
    } 
} 
+0

¡Este método funciona genial! El único problema que tengo es que tengo una lista extremadamente larga ... y lleva mucho tiempo obtener todos los encabezados ... etc ... Intenté ejecutar esos bucles en una AsyncTask ... pero solo congeló todo ... ¿Sugerencias? – DeNitE

0

He encontrado una gran solución here ... funciona muy bien con una lista enorme ... agradable y rápido ... no hay tiempo de carga.

@Override 
public int getPositionForSection(int section) 
{ 
    log.info("Get position for section"); 

    for (int i = 0; i < this.getCount(); i++) 
    { 
     if (this.getItem(i).length() > 0) 
     { 
      String item = this.getItem(i).toUpperCase(); 
      if (item.charAt(0) == sections.charAt(section)) 
      { 
       return i; 
      } 
     } 
    } 
    return 0; 
} 

@Override 
public int getSectionForPosition(int arg0) 
{ 
    log.info("Get section"); 

    return 0; 
} 

@Override 
public Object[] getSections() 
{ 
    log.info("Get sections"); 

    String[] sectionsArr = new String[sections.length()]; 

    for (int i = 0; i < sections.length(); i++) 
    { 
     sectionsArr[i] = "" + sections.charAt(i); 
    } 
    return sectionsArr; 
} 
Cuestiones relacionadas