解决ViewHolder/convertView复用问题//ListView/GridView的onItemClick点击事件(改变控件背景颜色)优化

上一篇文章中GridView/ListView点击事件并改变控件的背景颜色
没有考虑到viewHolder的复用问题,在滚动刷新listView时会发现新进入视图的那一个view会复用了刚退出视图的那个view的设置。具体见ViewHolder的复用机制原理

在listView滚动时,为了节省耗时等原因,它会直接调用getView中ViewHolder(缓冲区)里面的Adapter布局,当item被滑出屏幕时,它的布局就会被放进缓冲区,下一个新进入屏幕的newItem会直接使用缓冲区里面的布局。为了避免新进入视图的newItem复用了被点击并已改变背景颜色的item的布局,需要在自定义适配器中做一些处理:(效果图)

1.首先在适配器类里面自定义一个记录被点击的item地址的方法:

 int mCurrentPosition;
 public void setSelectPosition(int position){
        this.mCurrentPosition=position; 
    }

2.在getView里面做一下区分地址的处理:

  @Override
    public View getView(int position, View convertView, ViewGroup parent) {

        View view;
        ViewHolder viewHolder;
  //这里打了一个Log,便于理解:getView中的position是指刚进入屏幕的那个item的地址
        Log.d("GridView------","position----"+position);
        
        if (convertView==null){
            view= LayoutInflater.from(context).inflate(R.layout.item_gridview_adapter,null);
            viewHolder=new ViewHolder();
            viewHolder.textView=view.findViewById(R.id.tv_name);
            viewHolder.imageView=view.findViewById(R.id.image_view);

            view.setTag(viewHolder);

        }else {
            view=convertView;
            viewHolder= (ViewHolder) view.getTag();
        }
        //如果被点击的item和刚进入屏幕的item是同一个,就设置背景
        if (mCurrentPosition==position){
            view.findViewById(R.id.layout_gv).setBackgroundColor(Color.parseColor("#3F51B5"));
        }else {
            view.findViewById(R.id.layout_gv).setBackgroundColor(Color.parseColor("#D1EEEE"));
        }

        viewHolder.textView.setText(list.get(position).getName());
        viewHolder.imageView.setImageResource(list.get(position).getResourceId());

        return view;


    }

    class ViewHolder{
        TextView textView;
        ImageView imageView;
    }

    public void setSelectPosition(int position){

        this.mCurrentPosition=position;

    }

}

3.然后在MainActivity的gridView.setOnItemClickListener中调用setSelectPosition()方法,记录一下被点击的item地址。

  girdView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

                //改变当前点击item的背景颜色
                int firstVisiblePosition=parent.getFirstVisiblePosition();//获取当前GridView在屏幕中可见的第一个item
                int lastVisiblePosition=parent.getLastVisiblePosition();//获取当前GridView在屏幕中可见的最后一个item
                int maxVisiblePosition=lastVisiblePosition-firstVisiblePosition;

                Log.d("onSelectScan----","firstPosition--"+firstVisiblePosition);
                Log.d("onSelectScan----","lastPosition--"+lastVisiblePosition);

                for (int i=firstVisiblePosition;i<lastVisiblePosition+1;i++){
                    int item=i-firstVisiblePosition;
                    if (item<0||item>parent.getChildCount()){
                        Log.d("MainActivity------","SelectionItem---Error");
                    }else {
                        View v = parent.getChildAt(item);//如果当前的子类不在视图列表内,parent.getChildAt()就会报空指针的错误,所以item要处理一下
                        if (i == position) {
                            if (item == 0) {
                            //使用setSelection,将指定的view放置在屏幕的顶部
                                girdView.setSelection(firstVisiblePosition);
                            } else if (item == maxVisiblePosition) {
                                girdView.setSelection(lastVisiblePosition - 5);//这个5是根据我的屏幕大小设置的,我的屏幕最多放6个view
                            }
                            view.findViewById(R.id.layout_gv).setBackgroundColor(Color.parseColor("#3F51B5"));
                            Log.d("setColor-----","colorssssss");
                        } else {
                            v.findViewById(R.id.layout_gv).setBackgroundColor(Color.parseColor("#D1EEEE"));
                            Log.d("setColor-----","color");
                        }
                    }
                }
                adapter1.setSelectPosition(position);//记录被点击的item地址
                setRightView(position);//刷新右边View的布局
            }
        });

    }

以上,请指正。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小辣椒_Carly

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值