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

时间:2020-12-12 15:51:59

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

这个是Adapter.class文件中的一段代码
/**
     * Get the type of View that will be created by {@link #getView} for the specified item.
     * 
     * @param position The position of the item within the adapter's data set whose view type we
     *        want.
     * @return An integer representing the type of View. Two views should share the same type if one
     *         can be converted to the other in {@link #getView}. Note: Integers must be in the
     *         range 0 to {@link #getViewTypeCount} - 1. {@link #IGNORE_ITEM_VIEW_TYPE} can
     *         also be returned.
     * @see #IGNORE_ITEM_VIEW_TYPE
     */
    int getItemViewType(int position);

这个方法主要告诉我们自己可以设置传入item的类型并将类型指定到getView方法中。但是我这里面说道了getViewTypeCount这个

这个说的是我们可以设置返回将创建的视图类型的数量。
 /**
     * <p>
     * Returns the number of types of Views that will be created by
     * {@link #getView}. Each type represents a set of views that can be
     * converted in {@link #getView}. If the adapter always returns the same
     * type of View for all items, this method should return 1.
     * </p>
     * <p>
     * This method will only be called when when the adapter is set on the
     * the {@link AdapterView}.
     * </p>
     * 
     * @return The number of types of Views that will be created by this adapter
     */
    int getViewTypeCount();

下面看下我写的Adapter

public class AnswerAdapter extends BaseAdapter {
    private Context context;
    private List<Answer> list;
     private static final int TYPE_LEFT = 1;  
     private static final int TYPE_RIGHT = 2;  
    public AnswerAdapter(Context context, List<Answer> list, int photo_id) {
        this.context = context;
        this.list = list;
    }

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

    @Override
    public Answer getItem(int position) {
        return list.get(position);
    }

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

      //默认值是1 
     @Override  
     public int getViewTypeCount() {  
         return 3;  
     }  

     //这里设置type类型
     @Override  
     public int getItemViewType(int position) {  
         return list.get(position).getType();
     }  
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        final RightViewHolder rightviewHolder;
        final LeftViewHolder leftviewHolder;
        Answer answer = getItem(position);
        if (convertView == null) {
            switch (answer.getType()) {
            case TYPE_LEFT:
                convertView = View.inflate(context, R.layout.answer_left_item,null);
                leftviewHolder = new LeftViewHolder();
                leftviewHolder.lefttv = (TextView) convertView
                        .findViewById(R.id.answer_tv);
                convertView.setTag(leftviewHolder);
                break;
            case TYPE_RIGHT:
                convertView = View.inflate(context, R.layout.answer_right_item,
                        null);
                rightviewHolder = new RightViewHolder();


                rightviewHolder.righttv = (TextView) convertView
                        .findViewById(R.id.answer_tv);
                convertView.setTag(rightviewHolder);
                break;
            }
        } else {
            switch (answer.getType()) {
            case TYPE_LEFT:
                leftviewHolder = (LeftViewHolder) convertView.getTag();
                leftviewHolder.lefttv.setText(answer.getBody());


                break;

            case TYPE_RIGHT:
rightviewHolder=(RightViewHolder)convertView.getTag();  

rightviewHolder.righttv.setText(answer.getBody());  
                break;
            }
        }

        return convertView;

    }

    class RightViewHolder {
        TextView righttv;
        TextView timetv;
        ImageView rightimg;
    }

    class LeftViewHolder {
        TextView lefttv;
        TextView timetv;
        ImageView leftimg;
    }


}

这样就解决了复用错乱的问题。但是还有一个问题,为什么我的listView第一次不初始化,必须上下滚动后才可以加载数据,有解决的一定要贴给我哦!!三克油