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

Why do I not need to use Adapter.notifyDataSetChanged()?

在执行readContacts()方法之前,contactsList是空的,也就是说,执行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 无法刷新?

该方法在 Android 框架内部调用。您不必明确调用它。

来源:https://www.udacity.com/course/developing-android-apps--ud853

除了莉莉的回答,如果你自己写适配器,你必须明确地调用它。

重点是您在订单中输入数据,即当您将列表中的一个项目推入它一直向下时,您没有在任何随机索引的第 4、5 个输入它,所以您不必须调用 notifyDataSetChanged(),因为它的定义本身就是这样说的:某些数据已被更改,或者任何反映数据集的视图都应该自行刷新以使新数据在列表中可见,因为在这种情况下,数据超出了可见列表的范围,即列表中显示的子项数量,因此它(ListView)总是调用 next 在 listView 中特定最后显示的索引值(项目)之后的视图。!

希望我让你明白一点...!

+++++++++++++++++++++++++++++++++++++++++++++ ++++++++++++++++++++++++++++ 在你编辑问题后回答,搜索并在这方面有自己的想法和理解后回答:

在第一种情况下,VIEW不需要进行任何更改。对吧? 如果这一点你很清楚,那就来第二个。首先,您从数据库中获取数据,然后在列表中添加一个项目,然后在设置适配器后填充它。!!直到整个方法执行并完成列表后才设置适配器。好的

但是在第二种情况中,您正在更改视图(几乎所有内容都是 android 中的视图),因此您通过在已经填充了视图(它已经有一个 set-ted 适配器),所以这次你需要告诉视图嘿,我已经在你里面添加了一个项目现在刷新你自己然后更新列表(即显示)。