上一篇文章中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的布局
}
});
}
以上,请指正。