如何让复选框在我的列表视图中工作?
How can I get checkboxes working in my listview?
我一直在尝试按照 S.O 上的教程/post 学习如何让我的 checkbox
在我的 listview
中工作。我想用它做很多事情,但首先我想简单地检查项目的位置,但应用程序崩溃了,我收到 NullPointerException
错误。
错误是(这部分下面有更多内容):
java.lang.NullPointerException at com.example.chris.tutorialspoint.SelectPhoneContactAdapter.getView(SelectPhoneContactAdapter.java:104)
第 104 行是:
convertView.setTag(v);
但对我来说,我似乎一直在正确地遵循教程,但我不知道如何使这些 post 适应我的问题:Getting NullPointerException in custom ListView and Crash in ListView at AbsListView.obtainView for ListActivity。你能告诉我哪里出了问题吗?在我开始尝试使用这些复选框之前,一切都运行良好。
这是我的 customadapter
代码,SelectPhoneContactAdapter
:
public class SelectPhoneContactAdapter extends BaseAdapter {
//define a list made out of SelectPhoneContacts and call it theContactsList
public List<SelectPhoneContact> theContactsList;
//define an array list made out of SelectContacts and call it arraylist
private ArrayList<SelectPhoneContact> arraylist;
boolean itemChecked[];
Context _c;
//define a ViewHolder to hold our name and number info, instead of constantly querying
// findviewbyid. Makes the ListView run smoother
ViewHolder v;
public SelectPhoneContactAdapter(final List<SelectPhoneContact> selectPhoneContacts, Context context) {
theContactsList = selectPhoneContacts;
_c = context;
this.arraylist = new ArrayList<SelectPhoneContact>();
this.arraylist.addAll(theContactsList);
itemChecked = new boolean[theContactsList.size()];
}
@Override
public int getCount() {
System.out.println("the amount in arraylist :" + arraylist.size());
return arraylist.size();
}
@Override
public Object getItem(int i) {
return theContactsList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
static class ViewHolder {
// In each cell in the listview show the items you want to have
// Having a ViewHolder caches our ids, instead of having to call and load each one again and again
TextView title, phone;
CheckBox check;
}
@Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {
//we're naming our convertView as view
View view = convertView;
if (view == null) {
v = new ViewHolder();
System.out.println("getview position :" + i);
//if there is nothing there (if it's null) inflate the view with the layout
LayoutInflater li = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.phone_inflate_listview, null);
// So, for example, title is cast to the name id, in phone_inflate_listview,
// phone is cast to the id called no etc
v.title = (TextView) view.findViewById(R.id.name);
v.phone = (TextView) view.findViewById(R.id.no);
v.check = (CheckBox) view.findViewById(R.id.checkBoxContact);
convertView.setTag(v);
//or else use the view (what we can see in each row) that is already there
} else {
view = convertView;
}
// store the holder with the view
final SelectPhoneContact data = (SelectPhoneContact) theContactsList.get(i);
//in the listview for contacts, set the name
v.title.setText(data.getName());
//in the listview for contacts, set the number
v.phone.setText(data.getPhone());
v.check.setChecked(false);
v.check.setChecked(itemChecked[i]);
v.check
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
itemChecked[i] = isChecked;
}
});
// Return the completed view to render on screen
return view;
}
}
我的 getter 和 setter,SelectPhoneContact
:
public class SelectPhoneContact {
String phone;
public String getPhone() {return phone;}
public void setPhone(String phone) {
this.phone = phone;
}
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Boolean selected;
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected){
this.selected=selected;
}
}
如有必要,我可以 post 更多代码。
考虑这段代码:
@Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {
...
View view = convertView;
if (view == null) {
...
view = li.inflate(R.layout.phone_inflate_listview, null);
...
convertView.setTag(v);
}
...
}
首先,您将 convertView
的值分配给 view
变量。当它为 null 时,您分支到 if
语句,在这里您通过 li.inflate()
.
将新值分配给 view
但是,您稍后会在此 if
语句中引用 convertView
。尽管你在上面写了 view = convertView
,但此时 convertView
仍然是 null
。
有两种方法可以解决这个问题。第一个选项是简单地将 convertView.setTag(v)
更改为 view.setTag(v)
。另一种是删除这一行:
View view = convertView;
只需将您引用 view
的任何地方更改为使用 convertView
即可。无需引入新的 View view
变量;您可以直接使用 convertView
。
我一直在尝试按照 S.O 上的教程/post 学习如何让我的 checkbox
在我的 listview
中工作。我想用它做很多事情,但首先我想简单地检查项目的位置,但应用程序崩溃了,我收到 NullPointerException
错误。
错误是(这部分下面有更多内容):
java.lang.NullPointerException at com.example.chris.tutorialspoint.SelectPhoneContactAdapter.getView(SelectPhoneContactAdapter.java:104)
第 104 行是:
convertView.setTag(v);
但对我来说,我似乎一直在正确地遵循教程,但我不知道如何使这些 post 适应我的问题:Getting NullPointerException in custom ListView and Crash in ListView at AbsListView.obtainView for ListActivity。你能告诉我哪里出了问题吗?在我开始尝试使用这些复选框之前,一切都运行良好。
这是我的 customadapter
代码,SelectPhoneContactAdapter
:
public class SelectPhoneContactAdapter extends BaseAdapter {
//define a list made out of SelectPhoneContacts and call it theContactsList
public List<SelectPhoneContact> theContactsList;
//define an array list made out of SelectContacts and call it arraylist
private ArrayList<SelectPhoneContact> arraylist;
boolean itemChecked[];
Context _c;
//define a ViewHolder to hold our name and number info, instead of constantly querying
// findviewbyid. Makes the ListView run smoother
ViewHolder v;
public SelectPhoneContactAdapter(final List<SelectPhoneContact> selectPhoneContacts, Context context) {
theContactsList = selectPhoneContacts;
_c = context;
this.arraylist = new ArrayList<SelectPhoneContact>();
this.arraylist.addAll(theContactsList);
itemChecked = new boolean[theContactsList.size()];
}
@Override
public int getCount() {
System.out.println("the amount in arraylist :" + arraylist.size());
return arraylist.size();
}
@Override
public Object getItem(int i) {
return theContactsList.get(i);
}
@Override
public long getItemId(int i) {
return i;
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
static class ViewHolder {
// In each cell in the listview show the items you want to have
// Having a ViewHolder caches our ids, instead of having to call and load each one again and again
TextView title, phone;
CheckBox check;
}
@Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {
//we're naming our convertView as view
View view = convertView;
if (view == null) {
v = new ViewHolder();
System.out.println("getview position :" + i);
//if there is nothing there (if it's null) inflate the view with the layout
LayoutInflater li = (LayoutInflater) _c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = li.inflate(R.layout.phone_inflate_listview, null);
// So, for example, title is cast to the name id, in phone_inflate_listview,
// phone is cast to the id called no etc
v.title = (TextView) view.findViewById(R.id.name);
v.phone = (TextView) view.findViewById(R.id.no);
v.check = (CheckBox) view.findViewById(R.id.checkBoxContact);
convertView.setTag(v);
//or else use the view (what we can see in each row) that is already there
} else {
view = convertView;
}
// store the holder with the view
final SelectPhoneContact data = (SelectPhoneContact) theContactsList.get(i);
//in the listview for contacts, set the name
v.title.setText(data.getName());
//in the listview for contacts, set the number
v.phone.setText(data.getPhone());
v.check.setChecked(false);
v.check.setChecked(itemChecked[i]);
v.check
.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
itemChecked[i] = isChecked;
}
});
// Return the completed view to render on screen
return view;
}
}
我的 getter 和 setter,SelectPhoneContact
:
public class SelectPhoneContact {
String phone;
public String getPhone() {return phone;}
public void setPhone(String phone) {
this.phone = phone;
}
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
Boolean selected;
public boolean isSelected() {
return selected;
}
public void setSelected(boolean selected){
this.selected=selected;
}
}
如有必要,我可以 post 更多代码。
考虑这段代码:
@Override
public View getView(final int i, View convertView, ViewGroup viewGroup) {
...
View view = convertView;
if (view == null) {
...
view = li.inflate(R.layout.phone_inflate_listview, null);
...
convertView.setTag(v);
}
...
}
首先,您将 convertView
的值分配给 view
变量。当它为 null 时,您分支到 if
语句,在这里您通过 li.inflate()
.
view
但是,您稍后会在此 if
语句中引用 convertView
。尽管你在上面写了 view = convertView
,但此时 convertView
仍然是 null
。
有两种方法可以解决这个问题。第一个选项是简单地将 convertView.setTag(v)
更改为 view.setTag(v)
。另一种是删除这一行:
View view = convertView;
只需将您引用 view
的任何地方更改为使用 convertView
即可。无需引入新的 View view
变量;您可以直接使用 convertView
。