2013-03-05 14 views
5

Mam obecnie do czynienia z głupim problemem. Mam listview z niestandardowym adapterem (rozszerzenie CursorAdapter).Jak zarządzać usuwaniem elementu na CursorAdapterie

Wyświetla niestandardowy widok z różnymi przyciskami (udostępnij, jak, usuń). W przypadku przycisku kasowania ma ostrzeżenie, aby potwierdzić usunięcie przedmiotu. Gdy użytkownik potwierdzi, element zostanie usunięty z bazy danych. Wszystko działa dobrze, aż tutaj.

Moje pytanie brzmi: jak mogę skutecznie zaktualizować mój listview z moim nowym zestawem danych?

Bardzo dziękuję za pomoc.

Kod:

public class CommentCursorAdapter extends CursorAdapter{ 
    (...) 
    @Override 
    public void bindView(View view, Context arg1, Cursor cursor) { 
    (...) 
     holder.list_item_comment_discard_btn.setOnClickListener(new OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      final String _id = v.getTag().toString(); 
      AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); 
      builder.setTitle("Delete"); 
      builder.setMessage("Do you want to delete "+_id); 
      builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int id) { 
        // User clicked OK button 
        DBAdapter dba = new DBAdapter(mActivity); 
        dba.open(); 
        dba.remove(_id); 
        Log.i("TAAG", "removed: "+_id); 
        dba.close();  

       // How to update the listview ??          
       } 
      }); 
      builder.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() { 
       public void onClick(DialogInterface dialog, int id) { 
        // User cancelled the dialog 
       } 
      }); 

      AlertDialog d = builder.create(); 
      d.show(); 
     } 
     }); 
     holder.list_item_comment_discard_btn.setTag(_id); 
     (...) 
    } 
    (...) 
} 

Odpowiedz

9

Jeśli używasz LoaderManager do zarządzania cyklem życia kursorów (to jest właściwy sposób to zrobić) trzeba tylko zadzwonić restartLoader a następnie (ponownie) ustawić kursor z karty w onLoadFinished. Twój podgląd list zostanie ponownie załadowany zaktualizowanymi danymi.

Zarządzanie kursorem w swojej działalności lub fragmentu powinno odbywać się w sposób bardzo prosty i bezpośredni sposób:

  • W celu zainicjowania kursor:

    public void onCreate(Bundle savedInstanceState) { // or onStart 
    // ... 
    this.getLoaderManager().initLoader(MY_CURSOR_ID, null, this); 
    // ... 
    } 
    
    public Loader<Cursor> onCreateLoader(int id, Bundle args) { 
    // TODO: create a cursor loader that will load your cursor here 
    } 
    
    public void onLoadFinished(Loader<Cursor> arg0, final Cursor arg1) { 
    // TODO: set your cursor as the cursor of your adapter here; 
    } 
    
    public void onLoaderReset(Loader<Cursor> arg0) { 
    // TODO: set null as the cursor of your adapter and 'free' all cursor 
    // references; 
    } 
    
  • a potem, kiedy musisz przeładować swoje dane:

    this.getLoaderManager().restartLoader(MY_CURSOR_ID, null, this); 
    
+1

Zaimplementowałem interfejs na moim adapterze, aby powiadomić o liście, gdy element został usunięty, a następnie zgodnie z sugestią, ponownie uruchomię program ładujący. Teraz działa ;) – colletjb

1

połączeń cursor.requery(); notifyDataSetChanged(); .

Jeśli chcesz uzyskać rzeczywistą wydajność, użyj modelu AsyncTaskLoader.

+0

to przestarzałe! – Online98

+0

To nie działa! :( – Jorgesys

1

Wystarczy ponowić kwerendę w Cursor takiego:

public void onClick(DialogInterface dialog, int id) { 
    // User clicked OK button 
    DBAdapter dba = new DBAdapter(mActivity); 
    dba.open(); 
    dba.remove(_id); 
    Log.i("TAAG", "removed: "+_id); 
    dba.close();  
    cursor.requery(); 
    notifyDataSetChanged();         
} 

a następnie zadzwonić notifyDataSetChanged() powiedzieć Adapter że dane uległy zmianie, a to musi ponownie zbudować adapter.

To będzie intensywna operacja, jeśli żądanie trwa długo. Rozważ zrobienie tego w innym wątku.

+0

Testowałem, ale to nie zadziałało, ponadto cursor.requery() jest przestarzałe :( – colletjb

+0

Jeśli jest przestarzałe, możesz równie dobrze zażądać nowego kursora za pomocą 'AsyncTaskLoader' jak @Loxley wspomnianego w odpowiedź poniżej: – tolgap

1

Po usunięciu elementu w DB, zadzwoń notifyDataSetChanged na CommentCursorAdapter, udzielonego tej anonimowej klasy wewnętrznej używasz trzeba będzie final odniesienie do this ponieważ to w wewnątrz CursorAdapter. To powinno spowodować odświeżenie twojego ListView.

http://developer.android.com/reference/android/widget/BaseAdapter.html#notifyDataSetChanged()

+0

Próbowałem tego bez powodzenia: '(: builder.setPositiveButton (android.R.string.ok, new DialogInterface.OnClickListener() { \t \t \t \t \t public void onClick (okno DialogInterface, int id) { \t \t \t \t \t \t // użytkownik kliknął przycisk OK \t \t \t \t \t \t dbAdapter dba = new dbAdapter (mActivity); \t \t \t \t \t \t dba.open(); \t \t \t \t \t \t dba.remove (_id); \t \t \t \t \t \t Log.i ("TAAG", "removed:" + _id); \t \t \t \t \t \t dba.close(); \t \t \t \t \t \t \t \t \t \t \t \t \t \t cursor.requery(); \t \t \t \t \t \t mInstance.notifyDataSetChanged(); \t \t \t \t \t} \t \t \t \t}); – colletjb

Powiązane problemy