Android Studio ListView内Switch点击无法切换至开启状态
问题根因
Switch点击后无法切换状态和位置参数无关,是代码逻辑错误导致的:
- 点击事件里无意义调用
listView.setAdapter(add)重置适配器,会强制触发所有列表项重绘,Switch刚触发的状态翻转直接被重绘操作覆盖,根本无法保留。 - 没有在数据源中存储Switch的选中状态,ListView本身存在View复用机制,重绘、滑动时控件会回到布局默认的未选中状态,就算去掉重置适配器的代码,后续滑动列表时开关状态也会错位混乱。
- 额外冗余问题:SimpleAdapter绑定的字段数组中写了
"Button"字段,但数据库查询组装数据时从未存入该字段,属于无效绑定;代码里定义的ArrayList<Integer> pos、final int[] popo = {0}全程未被使用,属于无效变量。
修复步骤
不需要依赖位置参数做特殊处理,按以下逻辑修改即可:
- 首先给列表数据源增加开关状态字段,组装数据库数据时初始化默认状态
修改getinspectionlist()方法内的结果集循环逻辑,增加状态存储:
while (rs.next()) { Map<String, String> dtname = new HashMap<String, String>(); dtname.put("Inspection_Name", rs.getString(3)); dtname.put("Inspection_Id", rs.getString(2)); // 新增:默认开关为关闭状态,用0表示关,1表示开 dtname.put("Switch_Status", "0"); data.add(dtname); }
- 重写getView内的状态赋值和点击逻辑,删除无效的重置适配器代码
把原来getView中Switch相关的代码替换为以下内容:
@Override public View getView(int position, View convertView, ViewGroup parent) { View v = super.getView(position, convertView, parent); // 不要用全局的nok_1变量,直接声明局部变量避免复用错位 Switch nok_1 = v.findViewById(R.id.nok_1); // 每次加载Item时先从数据源读取对应位置的开关状态,给Switch赋值,解决重绘/滑动状态丢失问题 String savedStatus = MyDataList.get(position).get("Switch_Status"); nok_1.setChecked("1".equals(savedStatus)); nok_1.setOnClickListener(view -> { // 先翻转Switch的选中状态 boolean newCheckStatus = !nok_1.isChecked(); nok_1.setChecked(newCheckStatus); // 将新状态同步存入对应位置的数据源,保证后续重绘能读取到正确状态 MyDataList.get(position).put("Switch_Status", newCheckStatus ? "1" : "0"); // 保留原有跳转逻辑,删除原本无意义的getAdapter、setAdapter代码 String d = MyDataList.get(position).get("Inspection_Name"); String vinno = vin.getText().toString().trim(); String inspname = d.trim(); Bundle bundle = new Bundle(); bundle.putString("vinno", vinno); bundle.putString("inspname", inspname); Intent intent = new Intent(Inspection.this, NOK_inspection.class); intent.putExtras(bundle); startActivity(intent); }); return v; }
- 清理冗余代码
- 删除点击事件中原本的这两行无效代码,就是它直接导致Switch状态被重绘冲掉:
ListAdapter add = listView.getAdapter(); listView.setAdapter(add);- 删除从未使用的
ArrayList<Integer> pos、final int[] popo = {0}变量,减少无意义的内存占用。 - 列表项布局中用于存
Inspection_Id的TextView宽高都设为0dp,如果不需要在界面显示该字段,直接给它加android:visibility="gone"属性即可,不需要占位。
补充说明:如果需要从目标页返回当前列表页时开关仍保持选中状态,跳转时不要调用
finish()销毁当前Activity即可,数据源里存储的状态不会丢失,返回时列表会自动显示正确的开关状态。
内容的提问来源于stack exchange,提问作者Syed Atif
相关产品推荐
相关产品推荐

