【问题标题】:ListView list is reversed when selection made进行选择时,ListView 列表反转
【发布时间】:2011-07-17 18:34:57
【问题描述】:

所以我的列表视图工作得很好,然后我决定添加一个上下文菜单。只要我这样做,每当我正常单击列表视图中的一个项目时,整个列表都会在第一次单击时反转。随后的单击对订单没有任何影响,但是当再次取消选择第一项时,列表恢复正常。当我取出我添加的上下文菜单逻辑时,列表视图问题并没有消失。

我附加了一个调试器,我的列表适配器中的元素永远不会重新排序,并且 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 时,顺序恢复

我不知道是什么原因造成的 :(

【问题讨论】:

  • 可能在您的适配器中,检查该代码
  • 是的,出现此类症状的问题几乎总是表明存在适配器错误。
  • 向我们展示适配器的代码

标签: java android listview reverse


【解决方案1】:

进一步缩小范围后,我发现问题不在于我的按钮栏可见性的变化,而实际上是在我的holder.fu 类的holder.fu 中传递FillUp 对象。通过将其更改为引用适配器的 getItem(position) 方法,一切似乎都解决了。相当奇怪的错误,因为适配器本身并没有改变元素的顺序,但是传递对对象的引用使它非常不愉快。

【讨论】:

    【解决方案2】:

    如果您单击时列表视图的背景颜色发生变化,我认为这与您的主题有关。只需使用列表视图的缓存颜色参数即可,这是一个示例:

    <ListView
                android:layout_width="fill_parent"
                android:id="@android:id/list"
                android:scrollingCache="true"
                android:persistentDrawingCache="all"
                android:cacheColorHint="#0000"
                android:layout_height="wrap_content"
                android:fastScrollEnabled="true"
                android:stackFromBottom="true"
                android:smoothScrollbar="true"
                android:paddingTop="115dip">
    </ListView>
    

    【讨论】:

    • 颜色没有变化,只是列表排序的顺序。
    猜你喜欢
    • 2015-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-23
    • 2011-04-08
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    相关资源
    最近更新 更多