为什么我不需要使用Adapter.notifyDataSetChanged()?

9

contactsList 在执行 readContacts() 方法之前是空的,换句话说,在执行 contactsView.setAdapter(adapter) 时,contactsList 是空的。那么为什么这段代码仍然能正确显示联系人信息呢?

public class MainActivity extends AppCompatActivity {

ListView contactsView;
ArrayAdapter<String> adapter;
List<String> contactsList = new ArrayList<String>();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    contactsView = (ListView) findViewById(R.id.contacts_list);
    adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contactsList);
    contactsView.setAdapter(adapter);
    readContacts();
}

private void readContacts() {
    Cursor cursor = null;
    try {
        cursor = getContentResolver().query(
                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
                null, null, null, null);
        while (cursor.moveToNext()) {
            String displayName = cursor.getString(cursor.getColumnIndex(
                    ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME
            ));
            String number = cursor.getString(cursor.getColumnIndex(
                    ContactsContract.CommonDataKinds.Phone.NUMBER
            ));
            contactsList.add(displayName + "\n" + number);
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if (cursor != null) {
            cursor.close();
        }
    }
    }
}

但如果我添加了这样的内容,就必须调用notifyDataSetChanged()

    add.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            contactsList.add("blabla");
            adapter.notifyDataSetChanged();
        }
    });

add是一个按钮。 现在Android会自动调用该方法,那么为什么当移除 adapter.notifyDataSetChanged(); 后UI不能刷新呢?

3个回答

1

我的意思是当我设置适配器时,列表为空。然后在使用readcontacts之后,列表变得不为空,但我没有使用notifydatachanged()来刷新它。那么为什么ListView仍然可以显示信息呢? - Yriuns
@HungryMilk 当列表内容发生改变时,Android框架会自动调用notifyDataChanged()方法。因此,您不必自己调用它。 - Lilylakshi
谢谢!但我有一个新问题,请在上方刷新 :) - Yriuns

0
除了Lily的回答之外,如果你编写自己的适配器,你必须显式地调用它。

0
问题在于您正在输入订单数据,即当您将项目推入列表时,它会一直下移,您没有在第4个、第5个或任意随机索引处输入它,因此您不必调用notifyDataSetChanged(),因为其定义本身就是:某些数据已更改或任何反映数据集的视图都应刷新自身,以使新数据在列表上可见。在这种情况下,数据超出了可见列表的范围,即在列表中显示的子项数,因此(ListView)始终在特定最后显示的索引值(项目)之后调用下一个视图。希望我已经让您有所了解...!
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 在编辑问题并搜索后,我自己也有了一些想法和理解:
首先,对于VIEW,不需要进行任何更改。对吧?
如果您明白了这一点,请看第二个问题。首先,您从数据库中获取数据,然后将项目添加到列表中,然后设置适配器后填充它。在整个方法执行并完成列表之前,适配器都没有被设置。好的。
但在第二种情况下,您正在更改视图(在Android中几乎所有都是视图),因此您通过在已填充的视图上添加另一个项目来操作视图(该视图已经设置了适配器),因此这次您需要告诉视图,嘿,我已经在你里面添加了一个项目,请刷新自己,然后更新列表(即显示)。

谢谢!但我有一个新问题,请在上面刷新 :) - Yriuns
@HungryMilk 你好,请查看更新的说明,如果有帮助请接受它作为答案 :) - mfaisalhyder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接