自定義 ListView 包含 ImageView、TextView 和 CheckBox,需檢測 CheckBox 選中狀態變化。直接使用 OnItemClickListener 無法響應 CheckBox 點擊,因 CheckBox 搶奪焦點。
在 Adapter 的 getView() 方法中為 CheckBox 設置 OnCheckedChangeListener,並通過 Tag 關聯數據對象:
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View customView = inflater.inflate(R.layout.listrow, parent, false);
CheckBox cb = customView.findViewById(R.id.checkBox1);
final PInfo pinfo = installedApps.get(position);
cb.setTag(pinfo); // 關聯數據對象
cb.setOnCheckedChangeListener((buttonView, isChecked) -> {
PInfo info = (PInfo) buttonView.getTag();
if (isChecked) {
// 執行選中邏輯,如添加到選中集合
} else {
// 執行取消選中邏輯
}
});
// 設置其他視圖數據...
return customView;
}
getView 重新綁定監聽器,防止位置錯亂boolean isChecked 字段並在 getView 中根據該字段設置 cb.setChecked()android:focusable="false" 和 android:focusableInTouchMode="false",確保 Item 點擊事件正常觸發static class ViewHolder {
ImageView icon;
TextView name;
CheckBox checkBox;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null) {
convertView = inflater.inflate(R.layout.listrow, parent, false);
holder = new ViewHolder();
holder.icon = convertView.findViewById(R.id.imageView1);
holder.name = convertView.findViewById(R.id.textView2);
holder.checkBox = convertView.findViewById(R.id.checkBox1);
convertView.setTag(holder);
} else {
holder = (ViewHolder) convertView.getTag();
}
PInfo pinfo = installedApps.get(position);
holder.name.setText(pinfo.appname);
holder.icon.setImageDrawable(pinfo.icon);
holder.checkBox.setTag(pinfo);
holder.checkBox.setChecked(pinfo.isChecked); // 同步狀態
holder.checkBox.setOnCheckedChangeListener((btn, checked) -> {
pinfo.isChecked = checked;
// 更新選中集合等業務邏輯
});
return convertView;
}
在 getView 中為 CheckBox 設置獨立監聽器,結合 Tag 傳遞數據對象,是處理 ListView 中複雜交互控件的標準做法。