0

У меня есть ListActivity, который использует CursorAdapter, и я не могу его обновить. Вот некоторые из кода, я использую:Обновить ListView из ListActivity с помощью CursorAdapter

public class ContactDetailsActivity extends ListActivity 
{ 

    private ContactDetailsBroadcastReceiver mLvBroadcastReceiver; 
    private Contact contact; 


    @Override 
    protected void onCreate(Bundle savedInstanceState) 
    { 
     super.onCreate(savedInstanceState); 


     contact = (Contact)getIntent().getSerializableExtra(AwesomeApp.CONTACT_OBJECT); 

     if(contact == null) { 
      DataUtils.log("Starting ContactDetailsActivity with NULL contact."); 
      Toast.makeText(this, getString(R.string.no_contact_selected), Toast.LENGTH_SHORT).show(); 
      finish(); 
      return; 
     } 

     DataUtils.log("Starting ContactDetailsActivity with contact:" + contact.toString()); 
     setTitle(contact.getName()); 

     Cursor cursor = getContactDetailsCursor(); 
     startManagingCursor(cursor); 

     setListAdapter(new ContactDetailsCursorAdapter(this, cursor)); 

     ListView lv = getListView(); 
     lv.setBackgroundResource(R.color.white); 
     lv.setOnItemClickListener(new AdapterView.OnItemClickListener() 
     { 
      @Override 
      public void onItemClick(AdapterView<?> parent, View view, int position, long id) 
      { 
       Toast.makeText(ContactDetailsActivity.this, "touched", Toast.LENGTH_SHORT).show(); 
      } 
     }); 

     //Create broadcast receiver, to detect when a file upload has finished so we can update the pic status. 
     mLvBroadcastReceiver = new ContactDetailsBroadcastReceiver(); 
    } 

    private class ContactDetailsBroadcastReceiver extends BroadcastReceiver 
    { 
     @Override 
     public void onReceive(Context context, Intent intent) 
     { 
      DataUtils.log("In BroadcastReceiver - ContactDetails"); 
      refreshListView(); 
     } 
    } 

Мой адаптер в основном только расширяет CursorAdapter, в котором я преимущественную newView и bindView:

public class ContactDetailsCursorAdapter extends CursorAdapter 

У меня есть метод внутри ContactDetailsActivity называется refreshListView(), которую я называю в onResume(), и в onReceive() методе моего BroadcastReceiver

private void refreshListView() 
{ 
    DataUtils.log("In ContactDetailsActivity refreshListView"); 
    ((ContactDetailsCursorAdapter)getListAdapter()).notifyDataSetChanged(); 

    this.getListView().invalidate(); 

    this.getListView().invalidateViews(); 
} 

Это мой getContactDetailsCursor() метод:

private Cursor getContactDetailsCursor() 
{ 
    AwesomeDbAdapter dbAdapter = AwesomeApp.getDbAdapter(this); 
    Cursor c = dbAdapter.getRecentConversationsFromContact(contact.getId()); 
    DataUtils.log("New ContactDetails cursor has " + c.getCount() + " elements"); 
    return c; 
} 

Как вы можете видеть, я попытался notifyDataSetChanged(), invalidate(), invalidateViews() и ничто не кажется, чтобы обновить ListView.

У меня полно идей о том, как это можно обновить. Я вижу журналы, и метод вызывается как от onResume(), так и от методов onReceive() BroadcastReceiver.

Любые указатели оцениваются!

ответ

0

Возможно, вы забыли зарегистрировать ресивер: Регистрация приемника без регистрации не будет, зарегистрируйте этот приемник, как показано ниже.

Пример: В OnCreate:

ContactDetailsBroadcastReceiver receiver=new ContactDetailsBroadcastReceiver(); 
IntentFilter filter=new IntentFilter("android.net.wifi.STATE_CHANGE") 
registerReceiver(receiver, filter); 

В OnDestroy:

unregisterReceiver(receiver); 
+0

На самом деле это регистрируется, и я вижу сообщение журнала, когда 'OnReceive()' вызывается метод и 'refreshListView()' называется. Но список остался прежним. Этот код не был указан выше для ясности, но это упоминается. – Sandy

0

startManagingCursor (курсор);

Это осуждается способ работы с курсором, вы должны использовать Loaders, который может перезагрузить данные автоматически

+0

Да, я знаю об этом, но так оно и должно быть сделано. – Sandy

+0

В дополнение к этому мои данные используются только моим приложением и, согласно http://stackoverflow.com/questions/18326954/how-to-read-an-sqlite-db-in-android-with-a- cursorloader кажется, что Loaders больше подходят для данных ContentProvider и не столько для других данных, которые не предоставлены таким образом. – Sandy

+0

Погрузчики - это решение для асинхронного погрузки курсора из данных, например, с помощью SQL, независимо от того, используете ли вы ContentProvider или нет –

1

Это то, что, наконец, работал для меня. Как упоминал @ Кирилл Шальнов, startManagingCursor() устарел, но это то, что мне нужно использовать. Честно говоря, все это немного догадки, но, увы, все, что мне нужно.

@SuppressWarnings("deprecation") 
private void refreshListView() 
{ 
    DataUtils.log("In ContactDetailsActivity refreshListView"); 

    ContactDetailsCursorAdapter adapter = (ContactDetailsCursorAdapter)getListAdapter(); 

    Cursor oldCursor = null; 
    if(adapter != null) { 
     oldCursor = adapter.getCursor(); 
    } 
    Cursor newCursor = getContactDetailsCursor(); 

    if(oldCursor != null) { 
     stopManagingCursor(oldCursor); 
     oldCursor.close(); 
    } 
    startManagingCursor(newCursor); 

    adapter = null; 
    setListAdapter(new ContactDetailsCursorAdapter(this, newCursor)); 

    ListView listView = getListView(); 
    listView.setBackgroundResource(R.color.white); 
    listView.invalidate(); 
    listView.invalidateViews(); 
} 
Смежные вопросы