当前,我正在Android中制作一个待办事项列表应用程序,它具有编辑文本,按钮和列表视图,单击按钮将文本添加到列表视图时,一切正常,但是当我向其中添加太多项目时列表视图并尝试选择一个列表项,我的应用程序停止运行,并且出现错误提示
java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.view.View.findViewById(int)' on a null object reference
有人知道解决方法吗?
这是我的视图数据方法,它在listview中显示项目
public void viewdata(String tablename)
{
db = new mydbhandler(this);
lvitemslist = findViewById(R.id.lvitemlist);
ArrayList mylist = new ArrayList();
Cursor c = db.getdata(tablename);
while(c.moveToNext())
{
mylist.add(c.getString(1));
}
ListAdapter mylistadapter = new ArrayAdapter(this,R.layout.custom_item_row,R.id.ctv,mylist);
lvitemslist.setAdapter(mylistadapter);
}
这是onitemclicklistener
lvitemslist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
View v = lvitemslist.getChildAt(i);
CheckedTextView ctv = v.findViewById(R.id.ctv);
ctv.setCheckMarkDrawable(android.R.drawable.checkbox_on_background);
db.deletedata(tablename,ctv.getText()。toString());
viewdata(tablename);
答案 0 :(得分:0)
在您的OnItemClickListener
中查看以下行:
View v = lvitemslist.getChildAt(i);
我猜您想将被单击的ListView
行分配给变量 v 。但是ViewGroup
方法getChildAt(int)
(ListView
是ViewGroup
的一种)会给您
位于指定位置的视图;如果该位置在组中不存在,则为null
(引用自ViewGroup documentation)
就像您说的那样,这适用于前几个项目,但对于较高的位置,应用程序崩溃了。这是因为ListView
拥有固定数量的子View
:同时与子屏幕上的子屏幕数量一样多,另外还有一些子元素可以平滑滚动。对于超出该固定数字的每一行,lvitemslist.getChildAt(i)
将返回null
。
您该怎么做才能修改代码?
幸运的是,您无需做很多工作来获得被点击的View
,它作为onItemClick()
的参数之一交给您:第二个参数是被点击的ListView
行。
所以你只需要写
lvitemslist.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long rowId) {
CheckedTextView ctv = view.findViewById(R.id.ctv);
ctv.setCheckMarkDrawable(android.R.drawable.checkbox_on_background);
db.deletedata(tablename,ctv.getText().toString());
viewdata(tablename);
}
}
这将帮助您避免使用NullPointerException
。
另一件事:通过调用从适配器外部更改ListView
行的外观
ctv.setCheckMarkDrawable(android.R.drawable.checkbox_on_background);
这很危险(此网站上有很多问题,导致人们在滚动时会有奇怪的行为)。对于您来说,这可能不是问题,因为您很快便刷新了整个ListView
。但是通常应该向适配器提供所有必要的数据,以决定每一行的外观。然后可以更改数据列表,然后当然可以在适配器上调用notifyDatasetChanged()
。