2018-01-12GridView滑动数据紊乱

你一定遇到过滑动列表时item里面的控件错位,该出现的地方不出现,不该出现的地方反而蹦出来的情况。

总结起来就是如果GridView的宽度高度不确定,getView会多执行几次position=0来计算item的高度和宽度,得出每屏幕能够显示最大的item,

同时也给出了两个解决方案:

一是if else就能解决

问题的所在就是你的adapter里面,这里我们直接看一个最简单ListView 的Adapter,其他的GridView,RecyclerView原理也是一模一样,就不多赘述。

直接看adapter里面的getView方法:

@Override  

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

ViewHolder viewHolder =null;  

if (convertView == null) {  

convertView = inflater.inflate(R.layout.item_layout, parent,false);  

viewHolder =new ViewHolder();  

            viewHolder.title = (TextView) convertView.findViewById(R.id.title);  

            viewHolder.image = (ImageView) convertView.findViewById(R.id.image);  

            viewHolder.check = (CheckBox) convertView.findViewById(R.id.check);  

            viewHolder.button = (Button) convertView.findViewById(R.id.button);  

            convertView.setTag(viewHolder);  

}else {  

            viewHolder = (ViewHolder) convertView.getTag();  

        }  

        ListViewBean listViewBean = mList.get(position);  

        viewHolder.title.setText(listViewBean.getTitle());  

//绑定数据  


//重点!!!  


//滑动导致item里面的控件错位  


//第一种情况  

// 数据绑定之后滑动错位  

//很多情况我们会写如下代码  

//根据image的路径是否为空来给ImageView赋值  

//你可能认为逻辑没错,如果iamgePath有路径那么才给图片赋值  

//但是运行之后,全TM乱了  

if (!"".equals(listViewBean.getImagePath())) {  

            viewHolder.image.setImageURI(Uri.parse(listViewBean.getImagePath()));  

        }  


//解决方案:只需要再加上一个else就够了  

//为什么加上一个else就不会错位了?  

//我也懒得给你们讲缓存什么的(我也不会讲)  

//通俗易懂的来说:  

// 当进入listViewBean.getImagePath()有路径的时候,  

// 程序进了if里面,里面明确规定了我要把路径赋值给imageView,程序就照着我规定的做  

// 但是,如果listViewBean.getImagePath()是空的时候,程序不会进入if,  

// 不仅没进if,而且你也没在任何地方给他规定路径是空的时候他应该做什么  

// 那他就只能胡乱给你填数据咯  

if (!"".equals(listViewBean.getImagePath())) {  

            viewHolder.image.setImageURI(Uri.parse(listViewBean.getImagePath()));  

}else {  

//所以当路径为空时,也必须规定该控件应该怎么做  

            viewHolder.image.setImageResource(R.mipmap.ic_launcher);  

        }  


// 第二种情况:  

//设置某一控件显示或者隐藏  


//下面的代码,我定义了一个boolean类型的属性,用来判断我的checkBox是否显示  

//单当你运行之后就会发现,checkBox错位了  

if (listViewBean.isDisPlayCheck()) {  

            viewHolder.check.setVisibility(View.VISIBLE);  

        }  


//解决方案:同样也只需要加上一个else  

//代码修改如下,button也同样  

if (listViewBean.isDisPlayCheck()) {  

            viewHolder.check.setVisibility(View.VISIBLE);  

}else {  

            viewHolder.check.setVisibility(View.GONE);  

        }  

if (listViewBean.isDisPlayButton()) {  

            viewHolder.button.setVisibility(View.VISIBLE);  

}else {  

            viewHolder.button.setVisibility(View.GONE);  

        }  

return convertView;  

    }  


总结:只要是在ViewHolder里面声明了的控件,要么不赋值,要么在所有分支都赋值,有if,就一定要有else,要让控件无论进入哪一个分支都明白自己应该做什么事


第二种方法是:使用list集合

由于滑动,view的复用,会丢失之前item选中的状态,但是,item上显示的数据为什么没有错乱呢?这是因为数据集合没有错乱。那么我们能不能把item上需要保存的状态,也与数据集合一同保存呢?这样是不是就不会错乱。当然可以,这样更容易理解。

//自定义适配器

class PictureAdapterextends BaseAdapter {

private LayoutInflaterinflater;

private Listpictures;

public PictureAdapter(int[] titles,int[] icon,String[] username, Context context) {

super();

pictures =new ArrayList();

inflater = LayoutInflater.from(context);

Picture picture =null;

for (int i =1; i <31; i++)

{

picture =new Picture(i+"", icon[0],null);

if (titles.length>0&&icon!=null&&username!=null)

{

for (int j=0;j

{

if (i==titles[j]){

mSelectedDelete.add(String.valueOf(i));

picture=new Picture(i+"", icon[1],username[j]);

}

}

}

pictures.add(picture);

}

}

@Override

    public int getCount()

{

if (null !=pictures)

{

return pictures.size();

}else

        {

return 0;

}

}

@Override

    public Object getItem(int position)

{

return pictures.get(position);

}

@Override

    public long getItemId(int position)

{

return position;

}

@Override

    public View getView(int position, View convertView, ViewGroup parent)

{

ViewHolder viewHolder;

if (convertView ==null)

{

convertView =inflater.inflate(R.layout.item,null);

viewHolder =new ViewHolder();

viewHolder.title = (TextView) convertView.findViewById(R.id.text);

viewHolder.button=convertView.findViewById(R.id.seat);

viewHolder.image = (ImageView) convertView.findViewById(R.id.image);

convertView.setTag(viewHolder);

}else

        {

viewHolder = (ViewHolder) convertView.getTag();

}

viewHolder.title.setText(pictures.get(position).getTitle());

viewHolder.button.setText(pictures.get(position).getUsername());

if (mSelectedDelete.contains(String.valueOf(position+1))){//

convertView.setClickable(false);

convertView.setFocusable(false);

convertView.setEnabled(false);

System.out.println(pictures.get(position).getUsername()+"===="+pictures.get(position));

viewHolder.button.setVisibility(convertView.VISIBLE);

}else {

viewHolder.button.setVisibility(convertView.INVISIBLE);

}

viewHolder.image.setImageResource(pictures.get(position).getImageId());

return convertView;

}

}

class ViewHolder

{

public Buttonbutton;

public TextViewtitle;

public ImageViewimage;

}

搞定:效果图


你可能感兴趣的:(2018-01-12GridView滑动数据紊乱)