2009-09-23 12 views
7

Mam działanie, które rozszerza ExpandableListActivity. Używam SimpleCursorTreeAdapter do wypełnienia ExpandableListView. Mój układ zawiera widok listy i pusty widok. Przy uruchomieniu aplikacji ExpandableListActivity automatycznie wybiera odpowiedni widok do wyświetlenia.Jak zaktualizować widok listy rozwijanej, gdy dane adaptera ulegną zmianie

Moje kroki:

  1. uruchamia aplikację, nie ma żadnych danych. (pusty widok na ekranie)
  2. Wstaw niektóre dane do bazy danych.
  3. Call adapter.notifyDataSetChanged(); Ale pusty widok nadal znajduje się na ekranie i nie ma żadnego elementu w widoku listy.

Potem uruchom ponownie aplikację:

    pojawia widok
  1. Lista

    . Rozwiń wszystkie grupy i przewiń do dołu.
  2. Klikam na pozycję na liście. Pojawia się nowa aktywność.
  3. Kliknij przycisk Wstecz. Wszystkie grupy są zwinięte, a my jesteśmy na górze ekranu. Pozycja przewijania i grupy rozwinięte nie są pamiętane.
  4. Usuń wszystkie dane z db i call adapter.notifyDataSetChanged();
  5. Widoki dla dzieci zniknęły, ale grupy najwyższego poziomu są nadal widoczne.

Pytania:

  1. Co mogę zrobić, aby zastąpić pusty widoku z widoku listy?
  2. Co mogę zrobić, aby zapisać stan grup i przewinąć pozycję widoku listy?

Testowane na SDK: 1.5r3, 1.6r1

Kod:

public class MainActivity extends ExpandableListActivity { 

    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     dbHelper = new DBOpenHelper(this); 

     rubricsDbAdapter = new RubricsDBAdapter(dbHelper); 
     rubricsDbAdapter.open(); 

     itemsDbAdapter = new ItemsDBAdapter(dbHelper); 
     itemsDbAdapter.open(); 

     rubricsCursor = rubricsDbAdapter.getAllItemsCursor(); 
     startManagingCursor(rubricsCursor); 

     // Cache the ID column index 
     rubricIdColumnIndex = rubricsCursor.getColumnIndexOrThrow(RubricsDBAdapter.KEY_ID); 

     // Set up our adapter 
     mAdapter = new MyExpandableListAdapter(rubricsCursor, 
       this, 
       android.R.layout.simple_expandable_list_item_1, 
       android.R.layout.simple_expandable_list_item_1, 
       new String[] {RubricsDBAdapter.KEY_NAME}, 
       new int[] {android.R.id.text1}, 
       new String[] {ItemsDBAdapter.KEY_NAME}, 
       new int[] {android.R.id.text1}); 

     setListAdapter(mAdapter); 
    } 

    public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { 
     Intent i = new Intent(this, ItemViewActivity.class); 
     i.putExtra(ItemsDBAdapter.KEY_ID, id); 
     startActivity(i); 

     return super.onChildClick(parent, v, groupPosition, childPosition, id); 
    } 

    private void updateMyData() { 
     int i; 
     int k; 
     long rubricId; 

     for (i = 1; i <= 5; i++) { 
      rubricId = rubricsDbAdapter.insert("rubric " + i); 
      for (k = 1; k <= 5; k++) { 
       itemsDbAdapter.insert("item " + i + "-" + k, rubricId); 
      } 
     } 

     mAdapter.notifyDataSetChanged(); 
    } 

    private void deleteMyData() { 
     rubricsDbAdapter.deleteAll(); 
     itemsDbAdapter.deleteAll(); 

     mAdapter.notifyDataSetChanged(); 
    } 

    public class MyExpandableListAdapter extends SimpleCursorTreeAdapter 
    { 
     public MyExpandableListAdapter(Cursor cursor, Context context, int groupLayout, 
       int childLayout, String[] groupFrom, int[] groupTo, String[] childrenFrom, 
       int[] childrenTo) { 
      super(context, cursor, groupLayout, groupFrom, groupTo, childLayout, childrenFrom, 
        childrenTo); 
     } 

     @Override 
     protected Cursor getChildrenCursor(Cursor notebookCursor) { 
      // Given the group, we return a cursor for all the children within that group 
      long id = notebookCursor.getLong(rubricIdColumnIndex); 

      Cursor itemsCursor = itemsDbAdapter.getRubricItemsCursor(id); 
      startManagingCursor(itemsCursor); 
      return itemsCursor; 
     } 

    } 
} 
+0

pokazać nam realizację MyExpandableListAdapter, proszę. – Matthias

+0

Realizacja jest właśnie tutaj. Przewiń w dół do dołu kodu. Poza tym zdałem sobie sprawę, że muszę ponowić kwerendę moje rubryki kursor ręcznie. Więc prawo kod będzie: rubricsCursor.requery(); mAdapter.notifyDataSetChanged(); Ale drugie pytanie jest nadal mnie martwi. –

+0

Nie mogę wyjaśnić, jak bardzo ten blok kodu pomógł mi dzisiaj. Nie wiem, co bym zrobił bez tego. Stukrotne dzięki! – dfetter88

Odpowiedz

4

Więc odpowiedź brzmi:

  1. połączeń cursor.requery() przed wywołaniem adaptera notifyDataSetChanged() metoda.
  2. Zapisywanie stanów grup w działaniu onPause() i przywracanie w metodzie onResume().
2

Re: Pytanie nr 2 ...

Dlaczego nie można po prostu zadzwonić View.invalidateViews() i View.requestLayout() w tej kolejności?

Jeśli masz już ustawiony adapter do widoku, to nie powinieneś go wymagać, prawda? Przez unieważnienie widoku i zażądanie układu nie utracisz żadnego ze stanów widoku.

Na przykład w swojej metodzie "onResume" unieważnij widok listy, wywołując np. "Lv.invalidateViews()". Następnie wywołaj "lv.requestLayout()".

Twój „onCreate” metoda powinna nadal być odpowiedzialne za ustanowienie i adaptery łączące adapter do widzenia. Aby połączyć się z zasilacza, należy rozważyć użycie „lv.setListAdapter()” zamiast były tak, że nie brudząc z innymi widokami na ekranie.

Powiązane problemy