Оновлення подання списку при зміні даних адаптера


104

Коли дані, пов’язані з адаптером масиву, змінені, недійсне перегляд списку достатньо для відображення оновлених значень? Наступний фрагмент коду не працює, я щось тут неправильно зрозумів.

public class ZeroItemListActivity extends Activity {
    private ArrayList<String> listItems=new ArrayList<String>();
    private ListView mMyListView;
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mMyListView=(ListView) findViewById(R.id.MyListView);
        mMyListView.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,listItems));
    }
    public void addItem(View v){
        listItems.add("list Item");
        mMyListView.invalidate();
    }
}

Використано макет:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="fill_parent"
    android:layout_height="fill_parent">
    <TextView android:layout_width="fill_parent"
        android:layout_height="wrap_content" android:text="@string/hello" />
    <ListView android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:id="@+id/MyListView"></ListView>
    <Button android:layout_width="wrap_content"
        android:layout_height="wrap_content" android:id="@+id/AddItemsButton"
        android:text="Add Items" android:onClick="addItem"></Button>
</LinearLayout>

Відповіді:


172

замінник:

mMyListView.invalidate();

для:

((BaseAdapter) mMyListView.getAdapter()).notifyDataSetChanged(); 

Якщо це не працює, зверніться до цієї теми: Оновлення перегляду списку Android


@blindstuff, якщо мені потрібно оновити окремий елемент listview, то що мені робити
Developer

Якщо BaseAdapter не існує, notifyDataSetChanged () не з’явиться, тож вам потрібно змінитись BaseAdapterнаYourCustomAdapter
Junior Mayhé

12

Змініть цей рядок:

mMyListView.setAdapter(new ArrayAdapter<String>(this, 
                           android.R.layout.simple_list_item_1, 
                           listItems));

до:

ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                                   android.R.layout.simple_list_item_1, 
                                   listItems)
mMyListView.setAdapter(adapter);

а після оновлення значення елемента списку зателефонуйте:

adapter.notifyDataSetChanged();

3

invalidate();викликає подання списку, щоб визнати недійсним (тобто колір фону)
invalidateViews();викликає недійсність усіх його дітей. що дозволяє оновлювати уявлення дітей

Я припускаю, що це певний тип ефективності, що заважає всім предметам постійно переробляти, якщо не потрібно.


2

Я знайшов рішення, яке є більш ефективним, ніж прийнята зараз відповідь, тому що поточна відповідь змушує оновити всі елементи списку. Моє рішення оновить лише один елемент (який торкнувся), викликаючи адаптери getView та переробляючи поточний вигляд, що додає ще більшої ефективності.

mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      // Edit object data that is represented in Viewat at list's "position"
      view = mAdapter.getView(position, view, parent);
    }
});
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.