当选择做出的ListView列表逆转 [英] ListView list is reversed when selection made

查看:127
本文介绍了当选择做出的ListView列表逆转的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我有我的列表视图完美的工作然后,我决定增加一个上下文菜单。只要我做了,每当我在正常的列表视图我点击一个项目,整个列表大干快上的第一个点击反转。随后点击无可奈何的顺序,但是当第一个项目被再次取消选择列表中恢复正常。当我拿出我添加的上下文菜单的逻辑,列表视图问题不会消失。

我已经附加一个调试器,并在我的名单适配器的元素是永远不会重新排序,并ListView控件本身永远不会设定 .setStackFromBottom()

下面是我的onClick监听器注册来处理列表视图项的点击事件:

 公共无效的onClick(视图v){
    ViewHolder支架=(ViewHolder)v.getTag();
    复选框B = holder.box;
    布尔检查= b.isChecked();
    b.setChecked(检查!);
    如果(!查询){
       mChecked.add(holder.fu);
       如果(mChecked.size()== 1){
         buttonLayout.setVisibility(View.VISIBLE);
       }
    }其他{
       mChecked.remove(holder.fu);
       如果(mChecked.size()== 0){
         buttonLayout.setVisibility(View.GONE);
       }
   }
}

该viewholder类只是保存了我在ListView的优化使用对象的引用。我想不通这是为什么造成我的名单反转显示时,我已经试过听者移动到不同的视图中的布局,我试图重写听众,似乎没有任何工作!任何意见将是AP preciated。

编辑:这里是code的观点持有者

  / **类提供列表视图的持有者。用于优化* /
私有类ViewHolder {
    TextView的日期;
    TextView中加仑;
    TextView的费用;
    TextView的CPG;
    TextView的MPG;
    复选框箱;
    FillUp福;
}

以及适配器

 公共类FillUpAdapter延伸BaseAdapter {        ArrayList的< FillUp> mElements;
        ArrayList的< FillUp> mChecked;
        上下文mContext;        公共FillUpAdapter(上下文C,ArrayList的< FillUp>数据){
            mContext = C;
            mElements =数据;
            mChecked =新的ArrayList< FillUp>();
        }        公共无效clearChecked(){
            mChecked.clear();
        }        公众的ArrayList< FillUp> getChecked(){
            返回mChecked;
        }        公共布尔删除(FillUp F){
            mChecked.remove(F);
            返回mElements.remove(F);
        }        @覆盖
        公众诠释的getCount(){
            返回mElements.size();
        }        @覆盖
        公共对象的getItem(INT为arg0){
            返回mElements.get(为arg0);
        }        @覆盖
        众长getItemId(INT为arg0){            返回mElements.get(arg0中).getId();
        }        @覆盖
        公共查看getView(INT位置,查看convertView,父母的ViewGroup){
            的LinearLayout布局;
            ViewHolder持有人;
            如果(convertView!= NULL){
                布局=(的LinearLayout)convertView;
                支架=(ViewHolder)layout.getTag();
            }其他{
                布局=(的LinearLayout)LayoutInflater.from(mContext).inflate(
                        R.layout.fillup_list_item,父母,假);
                持有人=新ViewHolder();
                holder.cost =(TextView的)布局
                        .findViewById(R.id.fillUpListTotalValue);
                holder.cpg =(TextView的)布局
                        .findViewById(R.id.fillUpListCostPerGal);
                holder.gallons =(TextView的)布局
                        .findViewById(R.id.fillUpListGalValue);
                holder.mpg =(TextView的)布局
                        .findViewById(R.id.fillUpMPGText);
                holder.date =(TextView的)布局
                        .findViewById(R.id.fillUpListDate);
                holder.box =(复选框)布局
                        .findViewById(R.id.fillUpListCheckBox);
                holder.fu =(FillUp)的getItem(位置);
                layout.setTag(保持器);            }            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()));
            如果(convertView!= NULL){
                holder.box.setChecked(mChecked.contains(holder.fu));
            }            layout.setOnClickListener(新OnClickListener(){                @覆盖
                公共无效的onClick(视图v){
                    ViewHolder支架=(ViewHolder)v.getTag();
                    复选框B = holder.box;
                    布尔检查= b.isChecked();
                    b.setChecked(检查!);
                    如果(!查询){
                        mChecked.add(holder.fu);
                        如果(mChecked.size()== 1){
                            buttonLayout.setVisibility(View.VISIBLE);
                        }
                    }其他{
                        mChecked.remove(holder.fu);
                        如果(mChecked.size()== 0){
                            buttonLayout.setVisibility(View.GONE);
                        }
                    }
                }
            });
            返回布局;
        }
}

更新:结果
好了,我已经收窄到上buttonLayout认为,这是按钮上的活动的布局底部的线性布局,在ListView下面的可见性变化。每当我改变看法的能见度 View.VISIBLE 列表的顺序颠倒(当第一项签恰好)。当视图的可见性设置为 View.GONE

的顺序恢复

我不知道什么原因,虽然:(


解决方案

缩小范围,多一点之后,我发现这个问题是不是我的按钮栏的可见性的变化,但实际上各地的传球 FillUp 我的 ViewHolder 类的<​​code> holder.fu 。通过改变,而不是引用适配器的的getItem(位置)方法,一切似乎都工作了。相当奇怪的错误,因为适配器本身是没有改变的元素的顺序,而是通过周围对象的引用使得它很不高兴的。

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 :(

解决方案

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 in holder.fu of my ViewHolder class. By changing that to instead reference the adapter's getItem(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.

这篇关于当选择做出的ListView列表逆转的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆