我有一个ListViews的自定义row_item,带有图像,一对TextView和一个复选框。 根据我的理解,因为checkBox是一个可聚焦的元素,它会从listView中窃取焦点,所以OnListItemClicked永远不会被触发,除非我将每个row_item设置为不可点击并阻止后代的可聚焦性。
然后,为了管理checkBoxes更改,我在我的适配器getView方法中为我的checkBox设置了一个“OnCheckedChangeListener”。
这是一个不好的方法吗? (因为每次调用getView时我都会创建新的监听器) 还有其他方法可以做同样的事吗?
我附上一些代码,以便更容易理解我的意思。
getView方法:(在arrayAdapter中)
@Override
public View getView(int position, View convertView, ViewGroup parent) {
/** recycling views */
View row = convertView;
PregoHolder holder = null;
if(row == null)
{
LayoutInflater inflater = ((Activity)context).getLayoutInflater();
row = inflater.inflate(layoutResourceId, parent, false);
holder = new PregoHolder();
holder.imgIcon = (ImageView)row.findViewById(R.id.thumbnail);
holder.txtTitle = (TextView)row.findViewById(R.id.txtTitle);
holder.txtNews = (TextView)row.findViewById(R.id.txtNews);
holder.chBox = (CheckBox) row.findViewById(R.id.checkBox);
row.setTag(holder);
}
else
{
holder = (PregoHolder)row.getTag();
}
Prego Prego = data[position];
holder.txtTitle.setText(Prego.title);
holder.imgIcon.setImageResource(Prego.icon);
holder.txtNews.setText(Prego.news);
holder.chBox.setChecked(Prego.checked);
/** wiring up Listeners...
* (works fine but we are creating new listener each time)
* (Done like this because of the custom list view focusable issue)
*/
holder.chBox.setOnCheckedChangeListener(new OnCheckedChangeListener(){
@Override
public void onCheckedChanged(CompoundButton arg0, boolean checked) {
/** Getting the view position in the ListView */
ListView parent = (ListView)(arg0.getParent()).getParent();
int pos = parent.getPositionForView(arg0);
if (checked){
checkedPregons[pos] = true;
pregonsChecked++;
}
else if (!checked){
checkedPregons[pos] = false;
pregonsChecked--;
}
Toast.makeText(context, pregonsChecked+" is/are checked", Toast.LENGTH_SHORT).show();
}
});
row.setOnClickListener(new OnClickListener(){
@Override
public void onClick(View v) {
//mMode = ((Activity)context).startActionMode(new PregonsActionModes());
ListView parent = (ListView)v.getParent();
int pos = parent.getPositionForView(v);
Toast.makeText(context, "getView should show prego "+pos,Toast.LENGTH_SHORT).show();
}
});
return row;
}
提前致谢。
答案 0 :(得分:3)
我想可能有更好的方法来解决这个问题,但这不是我失眠的原因。你的方法是由许多新旧开发人员疯狂实现的,这只是一种简单的自然方式。此外,请记住,ListView
一次只有你在屏幕上看到的行数(滚动时不断调用getView
),所以你说的是8 - 12在任何给定时间制造物体(显然完全猜测),所以你的瓶颈不会在这里。事实上,根据我需要修改的对象的位置,我甚至没有想到它。
但在OnCheckedChangeListener
中使用ListView
是我强烈反对的事情。就像我说的那样,每一行都会调用getView
,因为它正在滚动和制作。这个已检查的已更改的侦听器正在被激活时被触发,尽管绝对不能保证getView
每行只调用一次 ,实际上我保证不会这样做。因此,这些代码块可能会被唤醒wazoo,即使您可能只是在手动处理CheckBox
框勾选时才打算这样做。加上一个相对更密集的命令,如notifyDataSetChanged()
,你会看到你的ListView
锁定了这个现象。
解决方案是简单地使用复选框onClickListener
并检查内部的isChecked()
。