2010-05-26 9 views
9

Ho implementato Indexer di sezione per una classe Adapter che estende BaseAdapter. Ora per il primo avvio, Section Indexer mostra correttamente una sovrapposizione. Ma quando il contenuto dell'elenco viene aggiornato, la sezione Overlay non viene aggiornata e fornisce ArrayOutOfBoundException. Per una correzione ciò che ho fatto è stato fatto listview.setFastScrollEnabled (false); aggiornare i contenuti dell'adattatore; e quindi listview.setFastScrollEnabled (true); Ora, ciò che accade è che l'overlay viene aggiornato, ma l'Overlay viene visualizzato nella parte superiore sinistra della listview. Come posso risolvere questo problema.La sovrapposizione di Indexer sezione non si aggiorna quando i cambiamenti dei dati dell'adattatore

+0

Ho avuto lo stesso problema, nessuna soluzione alternativa - Android 1.5 – tomash

+0

Ho riempito un bug 9054 http://code.google.com/p/android/issues/detail?id=9054 – tomash

risposta

1

una piccola soluzione che è stata suggerita da lee.wilmot è

private void jiggleGrid() { 

      int newWidth = flag(FLAG_THUMB_PLUS) ? 
FrameLayout.LayoutParams.FILL_PARENT : 
        grid.getWidth() - 1; 

      FrameLayout.LayoutParams l = new FrameLayout.LayoutParams(
          newWidth, 
          FrameLayout.LayoutParams.FILL_PARENT 
     ); 

      grid.setLayoutParams(l); 

      toggleFlag(FLAG_THUMB_PLUS); 
    } 

bandiera e toggleFlag sono alcune funzioni.

Chiamare questo metodo dopo aver impostato setFastScrollEnabled(true);. Ha funzionato per me ....

+0

potresti per favore mostrare quale sembra il layout? Intendo la definizione XML. La soluzione alternativa non funziona per me. – tomash

+0

ciò che è FLAG_THUMB_PLUS sarebbe davvero fantastico da sapere – cV2

+0

Questa soluzione non funziona se la larghezza è impostata su FILL_PARENT. Se si implementa questo e quindi si dice, cambia l'orientamento, la larghezza viene impostata in modo errato. –

8

ho pensato di condividere una versione ready-made della soluzione precedente per un ListActivity:

private boolean FLAG_THUMB_PLUS = false; 
private void jiggleWidth() { 

    ListView view = getListView(); 
    if (view.getWidth() <= 0) 
     return; 

    int newWidth = FLAG_THUMB_PLUS ? view.getWidth() - 1 : view.getWidth() + 1; 
    ViewGroup.LayoutParams params = view.getLayoutParams(); 
    params.width = newWidth; 
    view.setLayoutParams(params); 

    FLAG_THUMB_PLUS = !FLAG_THUMB_PLUS; 
} 

funziona per me.

+0

THANKS THANKS GRAZIE :) – cV2

+0

Questa soluzione non funziona se la larghezza è impostata su FILL_PARENT. Se si implementa questo e quindi si dice, cambia l'orientamento, la larghezza viene impostata in modo errato. –

+0

salvagente. Grazie – kevinl

0

Le soluzioni sopra indicate sono accettate, ad eccezione del caso in cui la larghezza è impostata su FILL_PARENT. Per farli lavorare per questo caso si dovrebbe ignorare onSizeChanged come questo

@Override 
protected void onSizeChanged (int w, int h, int oldw, int oldh) 
{ 
    super.onSizeChanged(w , h , oldw , oldh); 
    if (mInstance.getLayoutParams().width != FrameLayout.LayoutParams.FILL_PARENT) 
    { 
     mInstance.post(new Runnable() 
     { 
      @Override 
      public void run() 
      { 
       mInstance.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT , FrameLayout.LayoutParams.FILL_PARENT)); 
      } 
     }); 
    } 
} 

Con queste dimensioni modifica sarà ok dopo aver cambiato l'orientamento dello schermo.

5

Per farlo funzionare in tutti i casi (in particolare con il layout FILL_PARENT e la modifica dell'orientamento), anziché utilizzare direttamente un oggetto ListView, utilizzare questa classe e chiamare invalidateSectionIndexer() dopo aver modificato l'adattatore.

class MyListView extends ListView { 
    public MyListView(Context context) { 
     super(context); 
    } 

    public void invalidateSectionIndexer() { 
     // 1. this invalidates the Section Indexer 
     super.setFastScrollEnabled(false); 
     // Your adapter might be wrapped, e.g. when adding headers/footers. 
     ListAdapter adapter = getAdapter(); 
     BaseAdapter baseAdapter = (adapter instanceof WrapperListAdapter) ? 
       (BaseAdapter) ((WrapperListAdapter) adapter).getWrappedAdapter() : 
       (BaseAdapter) adapter; 
     baseAdapter.notifyDataSetChanged(); 
     super.setFastScrollEnabled(true); 

     // 2. This fixes the android bug of section overlay not positioned correctly. 
     int width = getWidth(); 
     int height = getHeight(); 
     super.onSizeChanged(width, height, width, height); 
    } 
} 
0

ho avuto problema simile utilizzando ResourceCursorAdapter. L'indicizzatore di sezione non si aggiornava dopo l'impostazione del nuovo adattatore per l'elenco o il metodo swapCursor() per l'aggiornamento del cursore. Ho provato tutte le soluzioni pubblicate su StackOverflow senza alcun successo. Solo una soluzione alternativa che ho trovato è che è necessario staccare/collegare il frammento che si desidera aggiornare (è necessario attivare il metodo onCreateView() di frammento in cui si costruisce l'interfaccia utente) dopo l'aggiornamento del Cursore (non CursorAdapter .. necessario aggiornare/impostare l'adattatore in onCreateView()). Questo ha funzionato per me. Ecco il codice che uso per ricollegare il frammento.

fragmentManager.beginTransaction().detach(frag).attach(frag).commitAllowingStateLoss(); 

Si può anche provare a rimuovere listView corrispondente dal layout e che aggiungerlo al layout di nuovo ma ho avuto alcuni problemi con questo approccio.

Problemi correlati