当进行选择时,ListView 列表会反转
所以我的列表视图工作得很好,然后我决定添加一个上下文菜单。一旦我这样做,每当我正常单击列表视图中的某个项目时,整个列表都会在第一次单击时反转。后续单击不会对顺序产生任何影响,但当再次取消选择第一个项目时,列表将恢复正常。当我取出添加的上下文菜单逻辑时,列表视图问题并没有消失。
我已经附加了一个调试器,列表适配器中的元素永远不会重新排序,并且 ListView 本身永远不会使用 .setStackFromBottom()
设置为反向,
这是我注册的 onClick 侦听器,用于处理列表视图项:
public void onClick(View v) {
ViewHolder holder = (ViewHolder) v.getTag();
CheckBox b = holder.box;
Boolean check = b.isChecked();
b.setChecked(!check);
if (!check) {
mChecked.add(holder.fu);
if (mChecked.size() == 1) {
buttonLayout.setVisibility(View.VISIBLE);
}
} else {
mChecked.remove(holder.fu);
if (mChecked.size() == 0) {
buttonLayout.setVisibility(View.GONE);
}
}
}
viewholder 类仅保存对我在列表视图中用于优化的对象的引用。我无法弄清楚为什么这会导致我的列表在显示时反转,我尝试将侦听器移动到布局中的不同视图,我尝试重写侦听器,似乎没有任何效果!任何建议将不胜感激。
的代码
/** Class to provide a holder for ListViews. Used for optimization */
private class ViewHolder {
TextView date;
TextView gallons;
TextView cost;
TextView cpg;
TextView mpg;
CheckBox box;
FillUp fu;
}
编辑:这是视图持有者以及适配器
public class FillUpAdapter extends BaseAdapter {
ArrayList<FillUp> mElements;
ArrayList<FillUp> mChecked;
Context mContext;
public FillUpAdapter(Context c, ArrayList<FillUp> data) {
mContext = c;
mElements = data;
mChecked = new ArrayList<FillUp>();
}
public void clearChecked() {
mChecked.clear();
}
public ArrayList<FillUp> getChecked() {
return mChecked;
}
public boolean remove(FillUp f) {
mChecked.remove(f);
return mElements.remove(f);
}
@Override
public int getCount() {
return mElements.size();
}
@Override
public Object getItem(int arg0) {
return mElements.get(arg0);
}
@Override
public long getItemId(int arg0) {
return mElements.get(arg0).getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout layout;
ViewHolder holder;
if (convertView != null) {
layout = (LinearLayout) convertView;
holder = (ViewHolder) layout.getTag();
} else {
layout = (LinearLayout) LayoutInflater.from(mContext).inflate(
R.layout.fillup_list_item, parent, false);
holder = new ViewHolder();
holder.cost = (TextView) layout
.findViewById(R.id.fillUpListTotalValue);
holder.cpg = (TextView) layout
.findViewById(R.id.fillUpListCostPerGal);
holder.gallons = (TextView) layout
.findViewById(R.id.fillUpListGalValue);
holder.mpg = (TextView) layout
.findViewById(R.id.fillUpMPGText);
holder.date = (TextView) layout
.findViewById(R.id.fillUpListDate);
holder.box = (CheckBox) layout
.findViewById(R.id.fillUpListCheckBox);
holder.fu = (FillUp) getItem(position);
layout.setTag(holder);
}
holder.date.setText(holder.fu.getDate());
holder.gallons.setText(holder.fu.getGallonsText());
holder.cpg.setText(holder.fu.getCostText());
holder.cost.setText(holder.fu.getTotalText());
holder.mpg.setText(String.format("%03.1f MPG",holder.fu.getMPG()));
if (convertView != null) {
holder.box.setChecked(mChecked.contains(holder.fu));
}
layout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ViewHolder holder = (ViewHolder) v.getTag();
CheckBox b = holder.box;
Boolean check = b.isChecked();
b.setChecked(!check);
if (!check) {
mChecked.add(holder.fu);
if (mChecked.size() == 1) {
buttonLayout.setVisibility(View.VISIBLE);
}
} else {
mChecked.remove(holder.fu);
if (mChecked.size() == 0) {
buttonLayout.setVisibility(View.GONE);
}
}
}
});
return layout;
}
}
:更新:
好的,所以我将范围缩小到了 ButtonLayout 视图上的可见性变化,该视图是 Activity 布局底部、ListView 下方的线性按钮布局。每当我将该视图的可见性更改为 View.VISIBLE(在选中第一项时发生)时,列表的顺序就会相反。当视图的可见性设置为 View.GONE 时,顺序会恢复,
但我不知道是什么导致了:(
So I had my listview working perfectly then I decided to add a context menu. As soon as I did that whenever I normal clicked an item in my listview, the entire list gets inverted on the first click. Subsequent clicks do nothing to the order, but when the first item is de-selected again the list returns to normal. When I take out the context menu logic that I added, the list view problem does not go away.
I've attached a debugger and the elements in my list adapter are never reordered, and the ListView itself is never set to reverse with .setStackFromBottom()
Here is my onClick listener registered to handle the click events of the list view items:
public void onClick(View v) {
ViewHolder holder = (ViewHolder) v.getTag();
CheckBox b = holder.box;
Boolean check = b.isChecked();
b.setChecked(!check);
if (!check) {
mChecked.add(holder.fu);
if (mChecked.size() == 1) {
buttonLayout.setVisibility(View.VISIBLE);
}
} else {
mChecked.remove(holder.fu);
if (mChecked.size() == 0) {
buttonLayout.setVisibility(View.GONE);
}
}
}
The viewholder class just holds references to objects I use in the listview for optimizations. I cannot figure out why this is causing my list to invert when displayed, I've tried moving the listener to a different view in the layout, I've tried re-writing the listener, nothing seems to work! Any advice would be appreciated.
Edit: here is the code for the view holder
/** Class to provide a holder for ListViews. Used for optimization */
private class ViewHolder {
TextView date;
TextView gallons;
TextView cost;
TextView cpg;
TextView mpg;
CheckBox box;
FillUp fu;
}
as well as the adapter:
public class FillUpAdapter extends BaseAdapter {
ArrayList<FillUp> mElements;
ArrayList<FillUp> mChecked;
Context mContext;
public FillUpAdapter(Context c, ArrayList<FillUp> data) {
mContext = c;
mElements = data;
mChecked = new ArrayList<FillUp>();
}
public void clearChecked() {
mChecked.clear();
}
public ArrayList<FillUp> getChecked() {
return mChecked;
}
public boolean remove(FillUp f) {
mChecked.remove(f);
return mElements.remove(f);
}
@Override
public int getCount() {
return mElements.size();
}
@Override
public Object getItem(int arg0) {
return mElements.get(arg0);
}
@Override
public long getItemId(int arg0) {
return mElements.get(arg0).getId();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
LinearLayout layout;
ViewHolder holder;
if (convertView != null) {
layout = (LinearLayout) convertView;
holder = (ViewHolder) layout.getTag();
} else {
layout = (LinearLayout) LayoutInflater.from(mContext).inflate(
R.layout.fillup_list_item, parent, false);
holder = new ViewHolder();
holder.cost = (TextView) layout
.findViewById(R.id.fillUpListTotalValue);
holder.cpg = (TextView) layout
.findViewById(R.id.fillUpListCostPerGal);
holder.gallons = (TextView) layout
.findViewById(R.id.fillUpListGalValue);
holder.mpg = (TextView) layout
.findViewById(R.id.fillUpMPGText);
holder.date = (TextView) layout
.findViewById(R.id.fillUpListDate);
holder.box = (CheckBox) layout
.findViewById(R.id.fillUpListCheckBox);
holder.fu = (FillUp) getItem(position);
layout.setTag(holder);
}
holder.date.setText(holder.fu.getDate());
holder.gallons.setText(holder.fu.getGallonsText());
holder.cpg.setText(holder.fu.getCostText());
holder.cost.setText(holder.fu.getTotalText());
holder.mpg.setText(String.format("%03.1f MPG",holder.fu.getMPG()));
if (convertView != null) {
holder.box.setChecked(mChecked.contains(holder.fu));
}
layout.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
ViewHolder holder = (ViewHolder) v.getTag();
CheckBox b = holder.box;
Boolean check = b.isChecked();
b.setChecked(!check);
if (!check) {
mChecked.add(holder.fu);
if (mChecked.size() == 1) {
buttonLayout.setVisibility(View.VISIBLE);
}
} else {
mChecked.remove(holder.fu);
if (mChecked.size() == 0) {
buttonLayout.setVisibility(View.GONE);
}
}
}
});
return layout;
}
}
UPDATE:
Ok, so I've narrowed it down to the visibility change on the buttonLayout view, which is a linear layout of buttons on the bottom of the Activity's layout, underneath the ListView. Whenever I change that view's visibility to View.VISIBLE
(which happens when the first item is checked) the list's order is reversed. The order is restored when the view's visibility is set to View.GONE
I have no idea what would cause that though :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
进一步缩小范围后,我发现问题不是按钮栏可见性的变化,而是实际上
holder.fu
中FillUp
对象的传递我的ViewHolder
类。通过更改它以引用适配器的 getItem(position) 方法,一切似乎都顺利。这是一个相当奇怪的错误,因为适配器本身没有改变元素的顺序,但传递对对象的引用却让它非常不高兴。After narrowing the scope a bit more, I discovered the problem was not the changing of the visibility of my button bar, but actually the passing around of
FillUp
objects inholder.fu
of myViewHolder
class. By changing that to instead reference the adapter'sgetItem(position)
method, everything seemed to work out. Quite an odd bug, since the adapter itself was not having the order of the elements changed, but passing around a reference to the object made it very unhappy.如果您的列表视图背景颜色在您单击时发生变化,我认为这与您的主题有关。只需使用列表视图的缓存颜色参数即可,这里是一个示例:
If your listview background color changes when you click on it, I think it is about your theme. Just play with the cache color parameters of your listview, here is an example: