我创建了一个包含自定义行的ListView,并且在每个自定义行中,我希望特定的TextView可以单击。在我的自定义适配器的getView方法中,我已经将onClickListener设置为我的TextView并根据需要实现onClick(View v)。这就是出现问题的地方。
在onClick(View v)中,我需要单击与适配器数据相关的TextView行的位置(与getView()的position参数不同)。在阅读堆栈溢出特别是这个article之后,获取所单击的TextView行的位置所需的魔术代码是:
final int position = listView.getPositionForView(v);
此代码非常有效,每次单击特定行的TextView时,都会返回正确的位置。但是,当我旋转手机以更改配置然后单击TextView的任何时,返回的位置始终为-1。将手机旋转回原始配置也会在按下任何TextView时保持返回-1的行为。
查看getPositionForView的文档,如果视图“与列表项不对应(或者当前不可见),则返回-1(INVALID_POSITION)”。为什么会这样?显然,对于我甚至可以单击TextView,视图必须在屏幕上可见。
如果重要,我使用convertView和ViewHolder模式来优化ListView。
我错过了什么?
更新: 为了更好地实现可视化,这是我的getView大致看起来像
getView(int position, View convertView, ViewGroup parent) {
final CustomViewHolder holder;
View = rowView;
if (convertView == null) {
rowView = inflater.inflate(R.layout.listitem, parent, false);
holder = new CustomViewHolder(rowView);
holder.textview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final int position = listView.getPositionForView(v);
//position is always -1 after configuration change
Log.d(TAG, "Like button pushed at position: " + position);
}
});
rowView.setTag(postHolder);
} else {
rowView = convertView;
postHolder = (PostListUserPostHolder) convertView.getTag();
}
//fill list item with data
}
return rowView;
}
更新#2 我似乎已经找到了解决方案。我没有将片段中的ListView引用传递给适配器,而是将对片段本身的引用传递给适配器。然后我在片段中提供了一个getter方法来获取ListView,然后使用了行:
final int position = fragment.getListView().getPositionForView(v);
我会认为这与我正在做的基本相同,但似乎并非如此。如果有人能够对可能发生的事情有所了解,那将是值得赞赏的。否则,我很高兴代码现在按预期工作!
答案 0 :(得分:0)
getView(int position, View convertView, ViewGroup parent) {
final CustomViewHolder holder;
if (convertView == null) {
rowView = inflater.inflate(R.layout.listitem, parent, false);
holder = new CustomViewHolder();
convertView .setTag(holder );
}
else {
holder= (CustomViewHolder ) convertView.getTag();
}
holder.textview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final int position = listView.getPositionForView(v);
//position is always -1 after configuration change
Log.d(TAG, "Like button pushed at position: " + position);
}
});
}
//fill list item with data
}
return convertView;
}
答案 1 :(得分:0)
你的getView()有点奇怪。您的持有人的字段textview
从未初始化?
持有人的用处是限制方法findViewById
的使用。
以下是我将使用的骨架:
static class ViewHolder {
public TextView textview;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View rowView = convertView;
// reuse views
if (rowView == null) {
LayoutInflater inflater = context.getLayoutInflater();
rowView = inflater.inflate(R.layout.listitem, null);
// configure view holder
ViewHolder viewHolder = new ViewHolder();
viewHolder.textview= (TextView) rowView.findViewById(R.id.textview);
rowView.setTag(viewHolder);
}
else {
ViewHolder holder = (ViewHolder) rowView.getTag();
}
// fill data
holder.textview.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
final int position = listView.getPositionForView(v);
//position is always -1 after configuration change
Log.d(TAG, "Like button pushed at position: " + position);
}
});
return rowView;
}
}
希望它能解决你的问题!
度过愉快的一天!