Android:ListView子项按钮引用及点击监听空指针问题排查
解决ListView子布局按钮设置OnClickListener时的空指针问题
嘿,这个问题我太熟了!你看到的Trying to define a onClick Listener on null item错误,本质是找控件的姿势不对——直接在Activity里用findViewById(R.id.mybutton)根本找不到这个按钮!
为什么会出错?
findViewById()的作用是在当前Activity绑定的布局(也就是activity_main.xml)里查找控件,但你的按钮是定义在ListView的item布局main_resource.xml里的,这个布局属于ListView的子视图,只有当ListView渲染出对应的item时,这些控件才会存在。Activity的布局里压根没有这个按钮,所以btn自然会返回null,调用setOnClickListener就会触发空指针错误。
正确的解决方法
要给ListView item里的按钮设置点击事件,得在ListView的适配器里处理,比如用BaseAdapter的话,在getView()方法中绑定控件并设置监听:
public class MyListAdapter extends BaseAdapter { private Context mContext; // 这里可以添加你的数据源,比如List<String> mData; // 构造方法,传入上下文和数据源 public MyListAdapter(Context context) { mContext = context; } @Override public int getCount() { // 返回数据源的长度,比如return mData.size(); return 0; } @Override public Object getItem(int position) { // 返回对应位置的数据,比如return mData.get(position); return null; } @Override public long getItemId(int position) { return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { ViewHolder holder; // 复用item视图,提升性能 if (convertView == null) { // 加载ListView的item布局main_resource.xml convertView = LayoutInflater.from(mContext).inflate(R.layout.main_resource, parent, false); holder = new ViewHolder(); // 从item布局里找到按钮 holder.myButton = convertView.findViewById(R.id.mybutton); convertView.setTag(holder); } else { holder = (ViewHolder) convertView.getTag(); } // 给按钮设置点击事件 holder.myButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 这里写你的点击逻辑,比如调用你的myFancyMethod myFancyMethod(v); // 如果需要用到当前item的位置或数据,可以用position参数 } }); return convertView; } // ViewHolder模式,避免重复findViewById static class ViewHolder { Button myButton; } // 你的自定义方法 private void myFancyMethod(View v) { // 逻辑代码 } }
额外提醒
如果你的按钮出现“点击没反应”的情况,可能是按钮抢占了ListView item的焦点,这时候可以在main_resource.xml的按钮标签里加上:
android:focusable="false" android:focusableInTouchMode="false"
这样就能确保按钮和ListView的item点击都能正常工作啦~
内容的提问来源于stack exchange,提问作者tester9
相关产品推荐
相关产品推荐

