关于ListView数据显示错乱的解决方案

原创 2016年10月04日 15:57:22

我们在平常开发Android中经常用到listview, 然而, 这个空间如果不进行优化的写法, 是非常吃内存的. 但是google在2013年IO大会上提出的viewholder写法显然已经是现在的优化标准了, 然而这个优化带来的烦恼也挺多的.
首先使用viewholder优化其实就是复用的创建好的item, 然后如果我们在创建好的item上面现实图片或者是在条目上做一些操作显然BUG是挺多的, 比如:我们listview显示的item里面是从网络获取的图片, 那么我们用viewholder优化后, 滑动listview图片会错乱, 会闪烁; 再比如, 我们常见的点赞操作, 我点击某一个条目, 它会给该条目设置一个标识, 然后当我在滑动的时候, 你会发现很奇怪, 怎么下面的item也会有该标识.
这里写图片描述

所以我们为了让listview做到尽量节约内存, 我们还是使用这个优化方案, 反之, 他出现的bug也要解决掉.

如果是网络请求获取图片显示在listview上面, 我们可以设置标签, 也就是tag, 可以使用他的URL来做他的标签, 然后加一个 if, else判断, 假如我们要在item上面做一些操作,
比如加载的是本地的图片, 假设我现在点击listview的条目, 要在条目上显示一个图片 类似于空间微信点赞操作, 那么我们应该怎么做?
这里写图片描述

package com.himan.blogdemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {


    private ListView lv_test;
    private List<CheckBean> strList;
    private StrListAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        lv_test = (ListView) findViewById(R.id.lv_test);
        strList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            strList.add(new CheckBean(false, "item"+i));
        }
        adapter = new StrListAdapter();
        lv_test.setAdapter(adapter);
    }


    class StrListAdapter extends BaseAdapter {

        ViewHolder holder;

        @Override
        public int getCount() {
            return strList.size();
        }

        @Override
        public Object getItem(int position) {
            return strList.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(final int position, View convertView, ViewGroup parent) {
            if (convertView == null) {
                convertView = View.inflate(MainActivity.this, R.layout.list_item_layout, null);
                holder = new ViewHolder(convertView);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            final CheckBean bean = strList.get(position);
            if(bean.isClick()){
                holder.iv_check.setVisibility(View.VISIBLE);
            }else{
                holder.iv_check.setVisibility(View.GONE);
            }

            holder.tv_content.setText(strList.get(position).getStr());

            holder.rl_items.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    bean.setClick(!bean.isClick());
                    notifyDataSetChanged();
                }
            });

            return convertView;
        }
    }


    class ViewHolder {
        TextView tv_content;
        ImageView iv_check;
        RelativeLayout rl_items;

        public ViewHolder(View view) {
            tv_content = (TextView) view.findViewById(R.id.tv_content);
            iv_check = (ImageView) view.findViewById(R.id.iv_check);
            rl_items = (RelativeLayout) view.findViewById(R.id.rl_items);
        }
    }
}

这个是MainActivity代码, List的类型正是我创建的bean类的类型

package com.himan.blogdemo;

/**
 * Created by HIMan on 2016/10/4.
 */

public class CheckBean {

    private boolean isClick;
    private String str;

    public CheckBean(boolean isClick, String str) {
        this.isClick = isClick;
        this.str = str;
    }

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    public boolean isClick() {
        return isClick;
    }

    public void setClick(boolean click) {
        isClick = click;
    }
}

在convertView里面做判断的时候有if同时也要有else, 这样不会有bug也会更严谨一些, 另外如果加载网络图片的话使用第三方库好多都有带防止图片错乱机制, 如果没有的话, 我们直接可以setTag(), 然后在根据getTag()来判断刚才的tag值, 可以用URL作为tag, 用法上大同小异.

——-代码下载——–

版权声明:本文为博主原创文章,未经博主允许不得转载。

listview数据错乱、重复的原因分析与解决方案

目前我们使用listview展示数据时,adapter的getView方法通常使用convertView.setTag(viewHolder)的方式来避免出现卡顿的情况,这种方式能使convertVi...

关于ListView数据错乱的解决方案

前言  本篇博客要给大家分享的是在Android开发中遇到滑动数据错乱的问题如何解决,先描述一些为什么会出现数据错乱,熟悉ListView复用原因的朋友一定知道,我们在开发中为了优化数据显示,避免卡顿...

关于ListView数据错乱的解决方案

前言  本篇博客要给大家分享的是在Android开发中遇到滑动数据错乱的问题如何解决,先描述一些为什么会出现数据错乱,熟悉ListView复用原因的朋友一定知道,我们在开发中为了优化数据显示,避免卡...

listview中使用checkbox滑动或者加载更多数据错乱问题解决方案

解决思路很简单, 创建一个map集合来存放选定的状态 private HashMap isSelected = new HashMap 先进行事件监听再进行选定状态初始化(如果反过来,呵呵,错乱又...

关于一个ListView使用多个item布局在优化时出现显示错乱的解决方案

一个很麻烦的问题,引用两个或者多个布局由于使用了ViewHolder和contenView做优化,页面在复用时出现要显示的内容错乱,经过上网查询和查谷歌官方的源码终于解决了这个问题 首先看下谷歌源码...

关于ListView图片错乱解决方案

  • 2016年10月04日 15:55
  • 28.98MB
  • 下载

tableViewCell数据显示错乱的解决方案

UITableView继承自UIScrollview,是苹果为我们封装好的一个基于scroll的控件。上面主要是一个个的UITableViewCell,可以让UITableViewCell响应一些点击...

Android中ListView复用导致布局错乱的解决方案

首先来说一下具体的需求是什么样的: 需求如图所示,这里面有ABCD四个选项的题目,当点击A选项,如果A是正确的答案,则变成对勾的图案,如果是错误答案,则变成错误的图案, 这里当时在写的时候觉得很简...

ListView添加头部之后出现位置获取错乱的问题解决方案

/**  * Add a fixed view to appear at the top of the list. If addHeaderView is  * called more than ...

Android 竞拍类App节选功能点-高性能更新数据,错位图片闪烁,定时器错乱,定时器时间不同步解决方案

Android 错位图片闪烁,定时器错乱,定时器时间不同步解决方案
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于ListView数据显示错乱的解决方案
举报原因:
原因补充:

(最多只允许输入30个字)