RecyclerView基本使用(二)-- 返回不同类型的View

本文介绍了如何在RecyclerView中展示不同类型的Item。通过创建多个XML布局文件和对应的数据源,结合不同的ViewHolder,实现在同一个RecyclerView中显示Image和TextView组成的复合视图。详细讲解了Adapter中的方法,包括判断View类型、实例化ViewHolder以及在onBindViewHolder中加载数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一篇博客RecyclerView的基本使用讲述了Recycler最基本的使用方法,这篇博客主要围绕如何在一个RecyclerView呈现不同的Item。

要实现在RecyclerView呈现复合Item,主要要在RecyclerView.adapter中的以下三个方法做处理:

  • getItemViewType()
  • onCreateViewHolder()
  • onBindViewHolder()

具体实现

首先,要呈现出不同Item,那么说明Item会有多个XML文件和对应的不同数据源。简便起见,假设我们的项目中有两种不同的Item,一种是单纯的Image,另外一种则是由多个TextView组成。

数据源定义如下:

private ArrayList<Object> getSampleArrayList() {
    ArrayList<Object> items = new ArrayList<>();
    items.add(new User("Dany Targaryen", "Valyria"));
    items.add(new User("Rob Stark", "Winterfell"));
    items.add("image");
    items.add(new User("Jon Snow", "Castle Black"));
    items.add("image");
    items.add(new User("Tyrion Lanister", "King's Landing"));
    return items;
}

可以看到,有User和单纯的String两种数据。这两种数据对应的布局文件也不同,那么必然导致需要使用不同的ViewHolder:
ViewHolder1.java

public class ViewHolder1 extends RecyclerView.ViewHolder {

    private TextView label1, label2;

    public ViewHolder1(View v) {
        super(v);
        label1 = (TextView) v.findViewById(R.id.text1);
        label2 = (TextView) v.findViewById(R.id.text2);
    }

    public TextView getLabel1() {
        return label1;
    }

    public void setLabel1(TextView label1) {
        this.label1 = label1;
    }

    public TextView getLabel2() {
        return label2;
    }

    public void setLabel2(TextView label2) {
        this.label2 = label2;
    }
}

然后是它的布局文件:

layout_viewholder1.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/llContainer"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:padding="5dp">

    <TextView
        android:id="@+id/text1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textStyle="bold"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:gravity="center_vertical"/>

    <TextView
        android:id="@+id/text2"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceListItemSmall"
        android:gravity="center_vertical" />

</LinearLayout>

ViewHolder2.java

public class ViewHolder2 extends RecyclerView.ViewHolder {

    private ImageView ivExample;

    public ViewHolder2(View v) {
        super(v);
        ivExample = (ImageView) v.findViewById(R.id.ivExample);
    }

    public ImageView getImageView() {
        return ivExample;
    }

    public void setImageView(ImageView ivExample) {
        this.ivExample = ivExample;
    }
}

layout_viewholder2.xml

<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ivExample"
    android:adjustViewBounds="true"
    android:scaleType="fitXY"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"/>

接下来是我们在例子中使用的图片资源:
这里写图片描述

创建ComplexRecyclerViewAdapter

public class ComplexRecyclerViewAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {

    // The items to display in your RecyclerView
    private List<Object> items;

    private final int USER = 0, IMAGE = 1;

    // Provide a suitable constructor (depends on the kind of dataset)
    public ComplexRecyclerViewAdapter(List<Object> items) {
        this.items = items;
    }

    // Return the size of your dataset (invoked by the layout manager)
    @Override
    public int getItemCount() {
        return this.items.size();
    }

    @Override
    public int getItemViewType(int position) {
         //More to come
    }

    @Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {
         //More to come
    }

    @Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
         //More to come
    }
}

这里给出了必须要覆盖的函数,并没有给出实现细节,下面一个一个讨论:
首先是getItemViewType,这里我们需要根据数据源的类型,判定Item的View类型:

@Override
public int getItemViewType(int position) {
    if (items.get(position) instanceof User) {
        return USER;
    } else if (items.get(position) instanceof String) {
        return IMAGE;
    }
        return -1;
}

接下来,我们需要根据getItemViewType获得的View类型来实例化所需的ViewHolder:

@Override
    public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup viewGroup, int viewType) {

        RecyclerView.ViewHolder viewHolder;
        LayoutInflater inflater = LayoutInflater.from(viewGroup.getContext());

        switch (viewType) {
            case USER:
                View v1 = inflater.inflate(R.layout.layout_viewholder1, viewGroup, false);
                viewHolder = new ViewHolder1(v1);
                break;
            case IMAGE:
                View v2 = inflater.inflate(R.layout.layout_viewholder2, viewGroup, false);
                viewHolder = new ViewHolder2(v2);
                break;
            default:
                View v = inflater.inflate(android.R.layout.simple_list_item_1, viewGroup, false);
                viewHolder = new RecyclerViewSimpleTextViewHolder(v);
                break;
        }
        return viewHolder;
    }

最后重写onBindViewHolder,将数据源中的内容呈现到ViewHolder的控件中去。这里需要根据viewHolder的不同来加载不同的数据。


@Override
    public void onBindViewHolder(RecyclerView.ViewHolder viewHolder, int position) {
        switch (viewHolder.getItemViewType()) {
            case USER:
                ViewHolder1 vh1 = (ViewHolder1) viewHolder;
                configureViewHolder1(vh1, position);
                break;
            case IMAGE:
                ViewHolder2 vh2 = (ViewHolder2) viewHolder;
                configureViewHolder2(vh2);
                break;
            default:
                RecyclerViewSimpleTextViewHolder vh = (RecyclerViewSimpleTextViewHolder) viewHolder;
                configureDefaultViewHolder(vh, position);
                break;
        }
    }
private void configureDefaultViewHolder(RecyclerViewSimpleTextViewHolder vh, int position) {
        vh.getLabel().setText((CharSequence) items.get(position));
    }

    private void configureViewHolder1(ViewHolder1 vh1, int position) {
        User user = (User) items.get(position);
        if (user != null) {
            vh1.getLabel1().setText("Name: " + user.name);
            vh1.getLabel2().setText("Hometown: " + user.hometown);
        }
    }

    private void configureViewHolder2(ViewHolder2 vh2) {
        vh2.getImageView().setImageResource(R.drawable.sample_golden_gate);
    }

到这里,就已经大功告成了,只需要在Activity或者Fragment中,对RecyclerView进行一些准备工作即可。

效果如下:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值