Adapter中除选中项外控制LinearLayout可见性时遇空引用异常求助
解决Adapter中切换LinearLayout可见性时的空引用问题
嘿,我看你这段代码在尝试实现“仅显示选中项的LinearLayout,隐藏其他项”时遇到了NullReferenceException,这主要是因为对布局层级的操作逻辑理解错了,我来帮你拆解问题并给出正确的实现方式:
问题出在哪?
你的代码里有两个核心错误:
- 操作对象完全不对:你用
mylinearlayout.GetChildAt(i)去访问子元素,但mylinearlayout是当前行的布局,它的子元素数量和parent.ChildCount(父容器的子项总数)根本不匹配。举个例子,如果父容器有5个列表项,但当前行的LinearLayout只有2个子元素,当i=2时,GetChildAt(i)就会返回null,你再去访问它的Visibility属性,自然就触发空引用异常了。 - 逻辑偏离目标:你想要的是切换不同列表行的LinearLayout可见性(选中行显示,其他行隐藏),但当前代码却在操作同一行内的子元素,完全没打到点子上。
正确的实现思路
在Adapter里做这种“仅展开选中项”的需求,正确的姿势是:
- 在Adapter类里维护一个变量,记录当前选中的位置;
- 点击按钮时更新这个选中位置,然后刷新Adapter;
- 在绑定列表项的方法里(RecyclerView的
OnBindViewHolder/ListView的GetView),根据当前项的位置和选中位置,设置对应LinearLayout的可见性。
示例代码(RecyclerView Adapter版)
首先给Adapter加个成员变量记录选中位置:
// 默认没有选中项,设为-1 private int _selectedPosition = -1;
然后处理按钮的点击事件:
btn.Click += delegate { // 更新选中位置为当前项的position _selectedPosition = position; // 刷新列表,让所有项重新绑定,更新可见性 NotifyDataSetChanged(); };
最后在OnBindViewHolder里设置可见性:
public override void OnBindViewHolder(ViewHolder holder, int position) { // 获取当前行的LinearLayout LinearLayout myLinearLayout = holder.ItemView.FindViewById<LinearLayout>(Resource.Id.test); // 根据是否是选中项来设置可见性 if (position == _selectedPosition) { myLinearLayout.Visibility = ViewStates.Visible; } else { myLinearLayout.Visibility = ViewStates.Gone; } // 其他的列表项绑定逻辑... }
如果是ListView的BaseAdapter
逻辑是一样的,在GetView方法里处理:
private int _selectedPosition = -1; public override View GetView(int position, View convertView, ViewGroup parent) { // 先完成convertView的初始化、复用逻辑... LinearLayout myLinearLayout = convertView.FindViewById<LinearLayout>(Resource.Id.test); Button btn = convertView.FindViewById<Button>(Resource.Id.your_button_id); btn.Click += delegate { _selectedPosition = position; NotifyDataSetChanged(); }; // 设置可见性 myLinearLayout.Visibility = position == _selectedPosition ? ViewStates.Visible : ViewStates.Gone; return convertView; }
这样修改后,不仅能解决空引用的问题,还能准确实现你想要的“仅显示选中项的LinearLayout”的效果。
内容的提问来源于stack exchange,提问作者Dhn
相关产品推荐
相关产品推荐

