你一定遇到过滑动列表时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;
}
搞定:效果图