viewtype

Up until now we’ve displayed same type of Views within a RecyclerView. In this tutorial, we’ll implement heterogeneous layouts inside a RecyclerView.

到目前为止,我们已经在RecyclerView中显示了相同类型的View。 在本教程中,我们将在RecyclerView中实现异构布局。

回收站视图 (RecyclerView)

RecyclerView with heterogeneous layouts is commonly used in to display section headers and details(Both require different layouts, hence different view type). Also, it’s used in a Newsfeed Application(like Facebook, Instagram) that display essentially different views for different types. Example: text, image, gif, video etc. Each of these requires a different layout type inside the RecyclerView.

具有不同布局的RecyclerView通常用于显示节标题和详细信息(两者都需要不同的布局,因此需要不同的视图类型)。 此外,它还用于Newsfeed应用程序(例如Facebook,Instagram)中,该应用程序针对不同类型显示本质上不同的视图。 例如:文本,图像,gif,视频等。每一个在RecyclerView内都需要不同的布局类型。

It’s also used in a NavigationDrawer to separate the Header from the rest of the section.
Without wasting any time, let’s implement it in our application.

它在NavigationDrawer中也用于将Header与本节的其余部分分开。
不浪费时间,让我们在应用程序中实现它。

Android RecyclerView多个ViewType项目结构 (Android RecyclerView Multiple ViewType Project Structure)

We’ll be implementing three view types (text, image, audio) that are inflated by three different layouts. Each has its own implementation specified in the adapter class.

我们将实现三种视图类型(文本,图像,音频),这些视图类型将通过三种不同的布局进行放大。 每个适配器都有在适配器类中指定的自己的实现。

码 (Code)

Our activity_main.xml contains the CoordinatorLayout as the root and the RecyclerView acts as it’s child view.

我们的activity_main.xml包含CoordinatorLayout作为根,而RecyclerView充当其子视图。

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout xmlns:android="https://schemas.android.com/apk/res/android"xmlns:app="https://schemas.android.com/apk/res-auto"xmlns:tools="https://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:fitsSystemWindows="true"tools:context="com.journaldev.recyclerviewmultipleviewtype.MainActivity"><android.support.design.widget.AppBarLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"android:theme="@style/AppTheme.AppBarOverlay"><android.support.v7.widget.Toolbarandroid:id="@+id/toolbar"android:layout_width="match_parent"android:layout_height="?attr/actionBarSize"android:background="?attr/colorPrimary"app:popupTheme="@style/AppTheme.PopupOverlay" /></android.support.design.widget.AppBarLayout><android.support.v7.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"app:layout_behavior="@string/appbar_scrolling_view_behavior"android:layout_height="match_parent" /></android.support.design.widget.CoordinatorLayout>

Take note of the line app:layout_behavior="@string/appbar_scrolling_view_behavior" inside RecyclerView. Removing this would scroll the RecyclerView over the whole screen thereby overlapping it with the AppBarLayout.

注意app:layout_behavior="@string/appbar_scrolling_view_behavior"中的app:layout_behavior="@string/appbar_scrolling_view_behavior" 。 删除它会在整个屏幕上滚动RecyclerView,从而使其与AppBarLayout重叠。

The Model.java class that populates the data in the Adapter is given below

下面给出了在Adapter中填充数据的Model.java类

public class Model {public static final int TEXT_TYPE=0;public static final int IMAGE_TYPE=1;public static final int AUDIO_TYPE=2;public int type;public int data;public String text;public Model(int type, String text, int data){this.type=type;this.data=data;this.text=text;}
}

It consists of three data types.

它包含三种数据类型。

  1. The int type holds the view type constant.int type使视图类型保持不变。
  2. The String text contains the String that’ll be displayed in the TextView.String text包含将在TextView中显示的字符串。
  3. The int data variable is used to store the respective data that we’ll be populating. Ideally it’ll contain a drawable or raw type resource.int data变量用于存储我们将要填充的各个数据。 理想情况下,它将包含可绘制或原始类型的资源。

The MainActivity.java class is given below

MainActivity.java类如下所示

package com.journaldev.recyclerviewmultipleviewtype;import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import java.util.ArrayList;public class MainActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);setSupportActionBar(toolbar);ArrayList<Model> list= new ArrayList();list.add(new Model(Model.TEXT_TYPE,"Hello. This is the Text-only View Type. Nice to meet you",0));list.add(new Model(Model.IMAGE_TYPE,"Hi. I display a cool image too besides the omnipresent TextView.",R.drawable.wtc));list.add(new Model(Model.AUDIO_TYPE,"Hey. Pressing the FAB button will playback an audio file on loop.",R.raw.sound));list.add(new Model(Model.IMAGE_TYPE,"Hi again. Another cool image here. Which one is better?",R.drawable.snow));MultiViewTypeAdapter adapter = new MultiViewTypeAdapter(list,this);LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this, OrientationHelper.VERTICAL, false);RecyclerView mRecyclerView = (RecyclerView) findViewById(R.id.recyclerView);mRecyclerView.setLayoutManager(linearLayoutManager);mRecyclerView.setItemAnimator(new DefaultItemAnimator());mRecyclerView.setAdapter(adapter);}
}

The R.raw.sound is a sound.mp3 file that’ll be played in the Audio View Type. The Adapter class for the RecyclerView contains three major methods that need to be overridden.

R.raw.sound是一个sound.mp3文件,将在“音频视图类型”中播放。 RecyclerView的Adapter类包含三个需要重写的主要方法。

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

We’ll be using switch statements in the getItemViewType() method to return the respective viewType. This viewType variable is internal to the Adapter class. It’s used in the onCreateViewHolder() and onBindViewHolder to inflate and populate the mapped layouts.

我们将在getItemViewType()方法中使用switch语句返回各自的viewType 。 此viewType变量在Adapter类的内部。 在onCreateViewHolder()和onBindViewHolder中使用它来填充和填充映射的布局。

Before we jump into the implementation of the Adapter class, let’s look at the types of layouts that are defined for each view type.

在进入Adapter类的实现之前,让我们看一下为每种视图类型定义的布局类型。

text_type.xml

text_type.xml

<android.support.v7.widget.CardView xmlns:card_view="https://schemas.android.com/apk/res-auto"xmlns:android="https://schemas.android.com/apk/res/android"android:id="@+id/card_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_marginTop="@dimen/activity_horizontal_margin"card_view:cardElevation="10dp"><TextViewandroid:id="@+id/type"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"/></android.support.v7.widget.CardView>

image_type.xml

image_type.xml

<android.support.v7.widget.CardView xmlns:card_view="https://schemas.android.com/apk/res-auto"xmlns:android="https://schemas.android.com/apk/res/android"android:id="@+id/card_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="@dimen/activity_horizontal_margin"card_view:cardElevation="10dp"><LinearLayoutandroid:layout_width="match_parent"android:orientation="vertical"android:layout_height="wrap_content"><TextViewandroid:id="@+id/type"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"/><ImageViewandroid:id="@+id/background"android:layout_width="match_parent"android:layout_height="150dp"android:scaleType="centerCrop"android:src="@drawable/snow"/></LinearLayout></android.support.v7.widget.CardView>

audio_type.xml

audio_type.xml

<android.support.v7.widget.CardView xmlns:card_view="https://schemas.android.com/apk/res-auto"xmlns:android="https://schemas.android.com/apk/res/android"android:id="@+id/card_view"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_margin="@dimen/activity_horizontal_margin"card_view:cardElevation="10dp"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><TextViewandroid:id="@+id/type"android:layout_width="match_parent"android:layout_height="wrap_content"android:padding="10dp"/><android.support.design.widget.FloatingActionButtonandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerHorizontal="true"android:tint="#FFFFFF"android:id="@+id/fab"android:layout_below="@+id/type"android:layout_margin="@dimen/activity_horizontal_margin"android:src="@drawable/volume"/></RelativeLayout></android.support.v7.widget.CardView>

Note: Add the following dependency for CardView in the build.gradle file

注意:在build.gradle文件中为CardView添加以下依赖

compile 'com.android.support:cardview-v7:24.2.0'

Make sure that the version number of the appcompat dependency matches with the cardview one. (It’s 24.2.0 for me presently. Can be different for you.)

确保appcompat依赖项的版本号与cardview之一匹配。 (目前对我来说是24.2.0。可能与您有所不同。)

We’ll be creating three separate ViewHolder classes for each of the above layouts as shown in the MultiViewTypeAdapter.java class below.

我们将为上述每个布局创建三个单独的ViewHolder类,如下面的MultiViewTypeAdapter.java类所示。

package com.journaldev.recyclerviewmultipleviewtype;import android.content.Context;
import android.media.MediaPlayer;
import android.support.design.widget.FloatingActionButton;
import android.support.v7.widget.CardView;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;import java.util.ArrayList;/*** Created by anupamchugh on 09/02/16.*/
public class MultiViewTypeAdapter extends RecyclerView.Adapter {private ArrayList<Model>dataSet;Context mContext;int total_types;MediaPlayer mPlayer;private boolean fabStateVolume = false;public static class TextTypeViewHolder extends RecyclerView.ViewHolder {TextView txtType;CardView cardView;public TextTypeViewHolder(View itemView) {super(itemView);this.txtType = (TextView) itemView.findViewById(R.id.type);this.cardView = (CardView) itemView.findViewById(R.id.card_view);}}public static class ImageTypeViewHolder extends RecyclerView.ViewHolder {TextView txtType;ImageView image;public ImageTypeViewHolder(View itemView) {super(itemView);this.txtType = (TextView) itemView.findViewById(R.id.type);this.image = (ImageView) itemView.findViewById(R.id.background);}}public static class AudioTypeViewHolder extends RecyclerView.ViewHolder {TextView txtType;FloatingActionButton fab;public AudioTypeViewHolder(View itemView) {super(itemView);this.txtType = (TextView) itemView.findViewById(R.id.type);this.fab = (FloatingActionButton) itemView.findViewById(R.id.fab);}}public MultiViewTypeAdapter(ArrayList<Model>data, Context context) {this.dataSet = data;this.mContext = context;total_types = dataSet.size();}@Overridepublic RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {View view;switch (viewType) {case Model.TEXT_TYPE:view = LayoutInflater.from(parent.getContext()).inflate(R.layout.text_type, parent, false);return new TextTypeViewHolder(view);case Model.IMAGE_TYPE:view = LayoutInflater.from(parent.getContext()).inflate(R.layout.image_type, parent, false);return new ImageTypeViewHolder(view);case Model.AUDIO_TYPE:view = LayoutInflater.from(parent.getContext()).inflate(R.layout.audio_type, parent, false);return new AudioTypeViewHolder(view);}return null;}@Overridepublic int getItemViewType(int position) {switch (dataSet.get(position).type) {case 0:return Model.TEXT_TYPE;case 1:return Model.IMAGE_TYPE;case 2:return Model.AUDIO_TYPE;default:return -1;}}@Overridepublic void onBindViewHolder(final RecyclerView.ViewHolder holder, final int listPosition) {Model object = dataSet.get(listPosition);if (object != null) {switch (object.type) {case Model.TEXT_TYPE:((TextTypeViewHolder) holder).txtType.setText(object.text);break;case Model.IMAGE_TYPE:((ImageTypeViewHolder) holder).txtType.setText(object.text);((ImageTypeViewHolder) holder).image.setImageResource(object.data);break;case Model.AUDIO_TYPE:((AudioTypeViewHolder) holder).txtType.setText(object.text);((AudioTypeViewHolder) holder).fab.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (fabStateVolume) {if (mPlayer.isPlaying()) {mPlayer.stop();}((AudioTypeViewHolder) holder).fab.setImageResource(R.drawable.volume);fabStateVolume = false;} else {mPlayer = MediaPlayer.create(mContext, R.raw.sound);mPlayer.setLooping(true);mPlayer.start();((AudioTypeViewHolder) holder).fab.setImageResource(R.drawable.mute);fabStateVolume = true;}}});break;}}}@Overridepublic int getItemCount() {return dataSet.size();}
}

In the above code, we’re keeping a global boolean variable for storing the volume button state that’s toggled at each click(along with changing the image resource for the FloatingActionButton).

在上面的代码中,我们保留了一个全局布尔变量,用于存储每次单击时切换的音量按钮状态(以及更改FloatingActionButton的图像资源)。

The output of the above application is given below.

上面的应用程序的输出如下。

This brings an end to this tutorial. You can download the final Android RecyclerViewMultipleViewType Project from the below link.

本教程到此结束。 您可以从下面的链接下载最终的Android RecyclerViewMultipleViewType项目。

Download Android RecyclerView Multiple ViewType Project下载Android RecyclerView多个ViewType项目

翻译自: https://www.journaldev.com/12372/android-recyclerview-example

viewtype

viewtype_Android RecyclerView示例–多个ViewType相关推荐

  1. 【Interfacenavigation】用RecyclerView创建一个列表(4)

    原 如果您的应用程序需要基于大型数据集(或经常更改的数据)显示元素滚动列表,则应RecyclerView 按照本页所述使用. 提示:通过单击文件>新建>片段>片段(列表),从Andr ...

  2. Android零基础入门第64节:揭开RecyclerView庐山真面目

    大家还记得之前在第38期~第50期都在学习列表控件吗,其中用了8期讲ListView的使用,相信都已经掌握好了吧.那么本期一起来学习Android 5.X新增的一个列表组件,那就是RecyclerVi ...

  3. 一分钟RecyclerView转场动画实现(淡入/出、旋转、缩放等)

    前言: RecyclerView作为Android中最重要的一个系统组件,在用户界面展示时就势必要展示其最好的一面(美观.健壮.优化).本文将通过设置Animation来快速地达到设置各种炫酷的动画效 ...

  4. Android——RecyclerView——Recycler类全部源码翻译及注释

    总结一下:Recycler就是一个不折不扣的回收站,在里面针对ViewHolder进行一系列回收站应进行的操作. 下一个看adapter类或者rvpool类 // mAttachedScrap是你re ...

  5. RecyclerView二级列表

    最近正好有做到二级列表,就记载一下怎样使用RecyclerView做二级列表吧. 效果大概就是这个样子,可以凑合用,主要是弄清楚大概原理,这样就知道步骤.代码地址在最下面. 需要了解 我们知道,写一个 ...

  6. 一个适用于ListView/GridView/RecyclerView的通用适配器

    简化大量重复代码 支持多布局 自定义图片加载 常用数据操作 view复用 RecyclerView item 点击和长按事件 GitHub源码地址 简书地址 gradle依赖 dependencies ...

  7. AndroidX RecyclerView总结-Recycler

    文章目录 概述 源码探究 ViewHolder的存储 布局期间 mCachedViews RecycledViewPool mAttachedScrap.mChangedScrap 滚动期间 View ...

  8. RecyclerView详解

    RecyclerView 简称 RV, 是作为 ListView 和 GridView 的加强版出现的,目的是在有限的屏幕之上展示大量的内容,因此 RecyclerView 的复用机制的实现是它的一个 ...

  9. RecyclerView实现上拉加载功能

    最近在做需求的时候,需要实现列表的上拉加载功能.在这里进行记录分享. 其实上拉加载功能只需要为RecyclerView的Item布局添加一个FooterView,然后通过判断是否滑动到最后一条Item ...

最新文章

  1. SURF角点检测(python)
  2. wxWidgets:获取主机的IP地址
  3. CakePHP 2.10.17 发布,PHP 快速开发框架
  4. CodeForces - 225C. Barcode(DP)
  5. JavaScript高级之ECMASript 7、8 、9 、10 新特性
  6. JVM虚拟机-Class文件之方法表集合
  7. php用户名框架,ThinkPHP框架结合Ajax实现用户名校验功能示例
  8. 软件测试:我该坚持在一个人的岗位还是辞职?
  9. Jenkins指定maven打包命令
  10. laravel中when的使用
  11. 微信小程序——案例:收货信息表单
  12. 软考中级-嵌入式系统设计师
  13. 555定时器产生对称三角波电路
  14. 经验分享:半桥电路的工作原理及注意问题
  15. 其他算法-建立在流形上的降维UMAP
  16. 去除push完数组里面的逗号
  17. STM32循迹小车系列教程(三)—— 使用灰度传感器循迹
  18. 记一个cakephp调试问题
  19. VMware虚拟机安装macos Big Sur 11.2.2 (20D80)镜像CDR/ISO下载
  20. STM32 HAL 硬件I2C HTU21D

热门文章

  1. Obective-C之宏定义
  2. 懒惰是人类进步的动力,勤奋是实现偷懒的途径
  3. [转载] numpy用法(logical_and, nonzero,arange, reshape)
  4. [转载] Python3 日历(Calendar)模块介绍
  5. [转载] 抽象类中不能有static,final,private修饰的方法--姥姥家的程序员
  6. [译] 通过官网 Go 语言学习笔记 | How to Write Go Code
  7. 手把手教你写一个java的orm(二)
  8. angularJS前端分页插件
  9. .NET中的设计模式——一步步发现装饰模式
  10. 3D MRI brain tumor segmentation using autoencoder regularization