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;
}