ListView展示两种布局

关于在ListView中显示两种布局时,某次曾经出现过ViewHolder的类转换异常。解决方法是在convertView不为null时,进行holder与type的判断,如果不匹配,则将convertView设置为null。

if ((convertView != null && convertView.getTag() instanceof ViewHolder1 && type == TYPE_2)
||(convertView != null && convertView.getTag() instanceof ViewHolder2 && type == TYPE_1)) {
            convertView = null;
}

可是这次写新的demo并没有出现这种情况。相关实现方法如下。

首先需要重写getViewTypeCount与getItemViewType这两个方法,type的值必须从0开始。

    private static final int TYPE_1 = 0;
    private static final int TYPE_2 = 1;

    @Override
    public int getViewTypeCount() {
        return 2;
    }

    @Override
    public int getItemViewType(int position) {
        if (position % 5 < 2) {
            return TYPE_1;
        } else {
            return TYPE_2;
        }
    }

然后就在getView中进行当前位置的判断确定是哪种类型并进行相应的加载。并提供两个ViewHolder进行不同布局的视图控制。当convertView为null时判断一次,convertView与holder绑定时判断一次,以及convertView不为null被复用时判断一次。
getView的相关代码如下:

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        ViewHolder1 holder1 = null;
        ViewHolder2 holder2 = null;
        int type = getItemViewType(position);
        if (convertView == null) {
            switch (type) {
                case TYPE_1:
                    convertView = LayoutInflater.from(context).inflate(R.layout.list_item1,null);
                    holder1 = new ViewHolder1();
                    holder1.tvName = (TextView) convertView.findViewById(R.id.tv_name);
                    holder1.tvHabit = (TextView) convertView.findViewById(R.id.tv_habit);
                    holder1.tvAge = (TextView) convertView.findViewById(R.id.tv_age);
                    convertView.setTag(holder1);
                    break;
                case TYPE_2:
                    convertView = LayoutInflater.from(context).inflate(R.layout.list_item2,null);
                    holder2 = new ViewHolder2();
                    holder2.tvName = (TextView) convertView.findViewById(R.id.tv_name);
                    holder2.tvAge = (TextView) convertView.findViewById(R.id.tv_age);
                    convertView.setTag(holder2);
                    break;
            }
        }else{
            switch (type){
                case TYPE_1:
                    holder1 = (ViewHolder1) convertView.getTag();
                    break;
                case TYPE_2:
                    holder2 = (ViewHolder2) convertView.getTag();
                    break;
            }
        }
        People p = list.get(position);
        switch (type){
            case TYPE_1:
                holder1.tvName.setText(p.name);
                holder1.tvAge.setText(p.age+"");
                holder1.tvHabit.setText(p.habit);
                break;
            case TYPE_2:
                holder2.tvName.setText(p.name);
                holder2.tvAge.setText(p.age+"");
                break;
        }
        return convertView;
    }

供加载的两种布局:


<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:padding="@dimen/activity_horizontal_margin">

    <TextView
        android:id="@+id/tv_name"
        android:text="name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_habit"
        android:text="habit"
        android:layout_below="@+id/tv_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_age"
        android:layout_below="@id/tv_habit"
        android:text="0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ImageView
        android:layout_alignParentRight="true"
        android:layout_alignBaseline="@id/tv_name"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:src="@mipmap/ic_launcher"/>

RelativeLayout>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ccc"
    android:padding="@dimen/activity_horizontal_margin">

    <TextView
        android:id="@+id/tv_name"
        android:text="name"
        android:layout_alignParentRight="true"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/tv_age"
        android:layout_below="@id/tv_name"
        android:layout_alignParentRight="true"
        android:text="0"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <ImageView
        android:layout_alignBaseline="@id/tv_name"
        android:layout_width="30dp"
        android:layout_height="30dp"
        android:src="@mipmap/ic_launcher"/>

RelativeLayout>

最后实现的结果:
ListView展示两种布局_第1张图片

当时出现异常的情况是:当拖动速度较快时会发生,如果慢慢的拖动则不会出现这种异常,如今不能重现这种情况了。不知道是不是当时进行网络请求的原因。希望有人能够告知一下。

你可能感兴趣的:(android开发)