ListView adapter 显示错乱

ListView adapter 显示错乱

在使用ListView时候,一般都会使用复用的adapter去优化。但是有的时候会出现listView显示错乱的情况。下面先看下我之前的错误代码。

附上我的item布局文件,增加理解:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll_lsfw_detail_list_"
    android:layout_width="fill_parent"
    android:layout_height="60dp"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/lowyer_detail_list_top"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:gravity="center_vertical"
        android:textColor="#3c78d8"
        android:textSize="15sp"
        android:visibility="gone" />

    <LinearLayout
        android:id="@+id/ll_detail_item_"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:orientation="horizontal" >

        <TextView
            android:id="@+id/lowyer_detail_list_down_left"
            android:layout_width="100dp"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:layout_marginRight="10dp"
            android:gravity="right|center_vertical"
            android:textSize="15sp"
            android:textColor="#434343"
             />

        <TextView
            android:id="@+id/lowyer_detail_list_down_right"
            android:layout_width="wrap_content"
            android:layout_height="40dp"
            android:layout_gravity="center"
            android:layout_marginLeft="10dp"
            android:gravity="left|center_vertical"
            android:textSize="15sp" 
            android:textColor="#434343"
           />
    </LinearLayout>

</LinearLayout>
package adapter;

import java.util.List;

import Bean.LowyerDetail;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.guyue.sfj_app.R;

public class LowyerDetailAdapter extends BaseAdapter {

    private List<LowyerDetail> infos;
    private int LayoutId;
    private LayoutInflater inflater;
    private Context context;

    public LowyerDetailAdapter(Context context, int LayoutId,
            List<LowyerDetail> infos) {
        this.context = context;
        this.LayoutId = LayoutId;
        this.infos = infos;
        inflater = LayoutInflater.from(context);

    }

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

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

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

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if(convertView == null){
            holder = new ViewHolder();
            convertView = inflater.inflate(LayoutId, null);
            holder.txt_top = (TextView) convertView.findViewById(R.id.lowyer_detail_list_top);
            holder.txt_down_left = (TextView) convertView.findViewById(R.id.lowyer_detail_list_down_left);
            holder.txt_down_right = (TextView) convertView.findViewById(R.id.lowyer_detail_list_down_right);
            holder.ll = (LinearLayout) convertView.findViewById(R.id.ll_detail_item_);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }

        LowyerDetail info = infos.get(position);
        if(!(info.getTitle().equals(""))){
            holder.txt_top.setVisibility(View.VISIBLE);
            holder.txt_top.setText(info.getTitle());
            holder.ll.setVisibility(View.GONE);

        }

        holder.txt_down_left.setText(info.getType());
        holder.txt_down_right.setText(info.getData());



        return convertView;
    }

    class ViewHolder{
        private TextView txt_top;
        private TextView txt_down_left;
        private TextView txt_down_right;
        private LinearLayout ll; 
    }
}

粗略一看没有什么问题,但是注意了我有一个判断if(!(info.getTitle().equals(“”)),当这个条件满足的时候就显示holder.txt_top.setVisibility(View.VISIBLE);。这个时候我没有对另外的一种情况进行设置,所以出现错乱了。
下面来讲一下原理:

在网上找的资料了解到,源码中AbListView中获取getView()和滑动操作是异步进行的,其中滑动操作在一个FlingRunnable的支线程中运行,所以这就导致了在ListView在滑动时可能已经滑动到了第十行,但可能第二行的数据这时就被直接使用了,这就是导致数据加载错乱的根本原因。

listview的缓存优化机制,滚出屏幕的视图会被缓存下来并被复用。我们以为只要设置info.getTitle()不为空显示holder.txt_top,其他情况就是就不显示,却忽略了,除了info.getTitle()不为空之外的某些行会去复用已显示的holder.txt_top视图,因此也就会出现显示错乱。

总结一句话就是要加上else的判断(附上正的部分代码):

public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder holder = null;
        if(convertView == null){
            holder = new ViewHolder();
            convertView = inflater.inflate(LayoutId, null);
            holder.txt_top = (TextView) convertView.findViewById(R.id.lowyer_detail_list_top);
            holder.txt_down_left = (TextView) convertView.findViewById(R.id.lowyer_detail_list_down_left);
            holder.txt_down_right = (TextView) convertView.findViewById(R.id.lowyer_detail_list_down_right);
            holder.ll = (LinearLayout) convertView.findViewById(R.id.ll_detail_item_);
            convertView.setTag(holder);
        }else{
            holder = (ViewHolder) convertView.getTag();
        }

        LowyerDetail info = infos.get(position);
        if(!(info.getTitle().equals(""))){
            holder.txt_top.setVisibility(View.VISIBLE);
            holder.txt_top.setText(info.getTitle());
            holder.ll.setVisibility(View.GONE);

        }else{
            holder.txt_top.setVisibility(View.GONE);
            holder.ll.setVisibility(View.VISIBLE);
        }
        holder.txt_down_left.setText(info.getType());
        holder.txt_down_right.setText(info.getData());



        return convertView;
    }

猜你喜欢

转载自blog.csdn.net/qq_29917267/article/details/52087044