Как обновить список рассылки Android? - PullRequest
415 голосов
/ 12 февраля 2010

Как обновить Android ListView после добавления / удаления динамических данных?

Ответы [ 25 ]

1 голос
/ 01 августа 2014

Если вы хотите сохранить свою позицию прокрутки при обновлении, и вы можете сделать это:

if (mEventListView.getAdapter() == null) {
    EventLogAdapter eventLogAdapter = new EventLogAdapter(mContext, events);
    mEventListView.setAdapter(eventLogAdapter);
} else {
    ((EventLogAdapter)mEventListView.getAdapter()).refill(events);
}

public void refill(List<EventLog> events) {
    mEvents.clear();
    mEvents.addAll(events);
    notifyDataSetChanged();
}

Подробную информацию см. В Android ListView: сохранение позиции прокрутки при обновлении .

0 голосов
/ 21 июля 2018

для другой опции - это метод onWindowFocusChanged, но он чувствителен и нуждается в некотором дополнительном кодировании, для которого он заинтересован

 override fun onWindowFocusChanged(hasFocus: Boolean) {
        super.onWindowFocusChanged(hasFocus)

       // some controls needed
        programList = usersDBHelper.readProgram(model.title!!)
        notesAdapter = DailyAdapter(this, programList)
        notesAdapter.notifyDataSetChanged()
        listview_act_daily.adapter = notesAdapter
    }
0 голосов
/ 28 ноября 2017

Проще всего сделать новый Adaper и уронить старый:

myListView.setAdapter(new MyListAdapter(...));
0 голосов
/ 12 марта 2016

Мне удалось получить notifyDataSetChanged, только получив новые данные адаптера, затем сбросив адаптер для представления списка, а затем сделав вызов, например, так:

    expandableAdapter = baseFragmentParent.setupEXLVAdapter();
    baseFragmentParent.setAdapter(expandableAdapter);
    expandableAdapter.notifyDataSetChanged(); 
0 голосов
/ 31 октября 2015

Если вы идете по направляющим линиям Android и используете ContentProviders для получения данных от Database и отображаете их в ListView с помощью CursorLoader и CursorAdapters, то вы все измените связанные данные будут автоматически отражены в ListView.

Твоего getContext().getContentResolver().notifyChange(uri, null); на курсоре в ContentProvider будет достаточно, чтобы отразить изменения. Нет необходимости в дополнительной обработке.

Но если вы не используете их все, вам нужно сообщить адаптеру, когда изменяется набор данных. Также вам нужно повторно заполнить / перезагрузить ваш набор данных (скажем, список), а затем вам нужно вызвать notifyDataSetChanged() на адаптере.

notifyDataSetChanged() не будет работать, если в наборе данных нет изменений. Вот комментарий над методом в docs-

/**
 * Notifies the attached observers that the underlying data has been changed
 * and any View reflecting the data set should refresh itself.
 */
0 голосов
/ 22 августа 2013

Мне не удалось заставить notifyDataSetChanged () работать над обновлением моего SimpleAdapter, поэтому вместо этого я попытался сначала удалить все представления, которые были присоединены к родительскому макету, с помощью removeAllViews (), затем добавить ListView, и это сработало, что позволило мне обновить пользовательский интерфейс:

LinearLayout results = (LinearLayout)findViewById(R.id.results);
ListView lv = new ListView(this);
ArrayList<HashMap<String,String>> list = new ArrayList<HashMap<String,String>>();
SimpleAdapter adapter = new SimpleAdapter( this, list, R.layout.directory_row, 
                new String[] { "name", "dept" }, new int[] { R.id.name, R.id.dept } );

for (...) { 
    HashMap<String, String> map = new HashMap<String, String>();
    map.put("name", name);
    map.put("dept", dept);
    list.add(map);
}

lv.setAdapter(adapter);
results.removeAllViews();     
results.addView(lv);
0 голосов
/ 19 января 2015

Я думаю, это зависит от того, что вы подразумеваете под обновлением. Вы имеете в виду, что дисплей GUI должен быть обновлен, или вы имеете в виду, что дочерние представления должны обновляться так, чтобы вы могли программно вызывать getChildAt (int) и получать представление, соответствующее тому, что находится в адаптере.

Если вы хотите обновить отображение GUI, вызовите notifyDataSetChanged () на адаптере. Графический интерфейс будет обновлен при следующей перерисовке.

Если вы хотите иметь возможность вызывать getChildAt (int) и получать представление, которое отражает то, что находится в адаптере, то вызовите layoutChildren (). Это приведет к восстановлению дочернего представления по данным адаптера.

0 голосов
/ 16 сентября 2014

Я был таким же, когда во фрагменте я хотел заполнить ListView (в одном TextView) с MAC-адресом устройств BLE, сканированных в течение некоторого времени.

Что я сделал, это было:

public class Fragment01 extends android.support.v4.app.Fragment implements ...
{
    private ListView                listView;
    private ArrayAdapter<String>    arrayAdapter_string;

...

@Override
public void onActivityCreated(Bundle savedInstanceState)
{
    ...
    this.listView= (ListView) super.getActivity().findViewById(R.id.fragment01_listView);
    ...
    this.arrayAdapter_string= new ArrayAdapter<String>(super.getActivity(), R.layout.dispositivo_ble_item, R.id.fragment01_item_textView_titulo);
    this.listView.setAdapter(this.arrayAdapter_string);
}


@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord)
{
    ...
    super.getActivity().runOnUiThread(new RefreshListView(device));
}


private class RefreshListView implements Runnable
{
    private BluetoothDevice bluetoothDevice;

    public RefreshListView(BluetoothDevice bluetoothDevice)
    {
        this.bluetoothDevice= bluetoothDevice;
    }

    @Override
    public void run()
    {
        Fragment01.this.arrayAdapter_string.add(new String(bluetoothDevice.toString()));
        Fragment01.this.arrayAdapter_string.notifyDataSetChanged();
    }
}

Затем ListView начал динамически заполняться MAC-адресами найденных устройств.

0 голосов
/ 22 марта 2012

После удаления данных из списка, вы должны позвонить refreshDrawableState(). Вот пример:

final DatabaseHelper db = new DatabaseHelper (ActivityName.this);

db.open();

db.deleteContact(arg3);

mListView.refreshDrawableState();

db.close();
Методы

и deleteContact в классе DatabaseHelper будут выглядеть примерно как

public boolean deleteContact(long rowId) {

   return db.delete(TABLE_NAME, BaseColumns._ID + "=" + rowId, null) > 0;

}
0 голосов
/ 21 июня 2013

Если вы хотите обновить представление списка пользовательского интерфейса из службы, сделайте адаптер статичным в вашем основном действии и сделайте это:

@Override
public void onDestroy() {
    if (MainActivity.isInFront == true) {
        if (MainActivity.adapter != null) {
            MainActivity.adapter.notifyDataSetChanged();
        }

        MainActivity.listView.setAdapter(MainActivity.adapter);
    }
}    
...