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

一个很麻烦的问题,引用两个或者多个布局由于使用了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第一次不初始化,必须上下滚动后才可以加载数据,有解决的一定要贴给我哦!!三克油

要在Android ListView的一行中显示多个元素,可以使用自定义布局。以下是如何实现它的步骤: 1. 创建一个自定义布局文件,例如row_layout.xml。在此文件中,可以添加多个元素,例如ImageView、TextView等。 2. 在适配器中重写getView()方法。在此方法中,可以将自定义布局文件中的元素与数据绑定,并将其添加ListView的每一行中。 3. 在Activity中,将适配器绑定到ListView上。 以下是一个示例代码: row_layout.xml: ``` <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content"> <ImageView android:id="@+id/imageView" android:layout_width="50dp" android:layout_height="50dp" /> <TextView android:id="@+id/textView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="20sp" /> </LinearLayout> ``` CustomAdapter.java: ``` public class CustomAdapter extends ArrayAdapter<String> { public CustomAdapter(Context context, ArrayList<String> data) { super(context, 0, data); } @Override public View getView(int position, View convertView, ViewGroup parent) { View itemView = convertView; if (itemView == null) { LayoutInflater inflater = LayoutInflater.from(getContext()); itemView = inflater.inflate(R.layout.row_layout, parent, false); } ImageView imageView = itemView.findViewById(R.id.imageView); TextView textView = itemView.findViewById(R.id.textView); // 绑定数据 String item = getItem(position); imageView.setImageResource(R.drawable.icon); textView.setText(item); return itemView; } } ``` MainActivity.java: ``` public class MainActivity extends AppCompatActivity { private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); listView = findViewById(R.id.listView); ArrayList<String> data = new ArrayList<>(); data.add("Item 1"); data.add("Item 2"); data.add("Item 3"); CustomAdapter adapter = new CustomAdapter(this, data); listView.setAdapter(adapter); } } ``` 在此示例中,我们创建了一个自定义布局文件row_layout.xml,其中包含一个ImageView和一个TextView。然后,我们在CustomAdapter中重写了getView()方法,将数据绑定到自定义布局文件中的元素上,并将每个元素添加ListView的每一行中。最后,在MainActivity中,我们将适配器绑定到ListView上,以显示多个元素的每一行。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值