安卓开发之-------RecyclerView

目录

一、什么是RecyclerView?

二、RecyclerView的适配器

什么是ViewHolder?

三、RecyclerView的布局管理器

3.1 三大布局

3.2 横向、纵向划动

代码实例

1. 首先要用这个控件,你需要在gradle文件中添加包的引用

2. 创建一个主界面RecyclerViewActivity的布局文件recyclerview_main.xml

3. 主界面RecyclerViewActivity的逻辑代码

4. 把创建的主界面加入到androidmanifest.xml

5.定义一栏数据显示的数据类型

6. 定义一栏数据的布局

7. 编写RecyclerView控件的适配器


一、什么是RecyclerView?

RecyclerView不仅可以实现和ListView同样的效果,还有优化了ListView中的各种不足。其可以实现数据纵向滚动,也可以实现横向滚动(ListView做不到横向滚动)。

RecyclerView是谷歌V7包下新增的控件,用来替代ListView的使用,在RecyclerView中,标准化了ViewHolder,类似于ListView中convertView用来做视图缓存。先来说说RecyclerView的亮点就是,他可以通过设置LayoutManager来快速实现listview、gridview、瀑布流的效果,而且还可以设置横向和纵向显示,添加动画效果也非常简单(自带了ItemAnimation,可以设置加载和移除时的动画,方便做出各种动态浏览的效果),

 

二、RecyclerView的适配器

由于RecyclerView可以上下或者左右滚动数据的,因此每滚动一次,view里面所现实的数据都会不一样,因此就需要适配器来决定该现实什么数据。

而RecyclerView是自己有自己的适配器模版(是一个抽象类)的。因此当我们自定义RecyclerView的适配器时,需要把继承RecyclerView的适配器模版(RecyclerView.Adapter),并重写其三个方法抽象方法。

这三个方法分别是:

  1. onCreateViewHolder()用于创建ViewHolder实例,并把加载的布局传入到ViewHolder中,再把ViewHolder实例返回。
  2. onBindViewHolder()用于对子项的数据进行赋值,会在每个子项(Item,即某一栏数据)被滚动到屏幕内时执行。
  3. getItemCount()返回RecyclerView的子项数目(Item数目)。

即适配器每次其实都在配置一栏数据(一个Item)。

 

什么是ViewHolder?

ViewHolder类中各个成员都是一个个View。我们知道最终展示给用户看的界面看到的控件都是 一个个View,而在后台中,记录的一般都是数据,这些数据最终会在VIew中展示给用户。所以ViewHolder就相当于把数据转成纪录了数据的View的一个中间物体。ViewHolder都是通过VIew扽形式,记录着一栏数据(一个item),下面举个ViewHolder的例子:

 

三、RecyclerView的布局管理器

3.1 三大布局

在RecyclerView中提供了三种布局,第一是线性布局,第二是网格布局,第三是瀑布布局,而布局管理器LayoutManager则决定着到底选用哪一种布局。

如下图,作图是线性布局,跟LIstView一样,右图是列数为2的网格布局。

为了更好地展示网格布局和瀑布布局的区别,我把apple的字段复制了很多次,再运行,

如下图,左边是瀑布布局,右图是网格布局。可以看到瀑布布局上不会留白的。(两种的列数都为4)

 

3.2 横向、纵向划动

RecyclerView的滑动方向可以往左也可以往右,设置方式就在布局管理器中。

例如,在线性布局管理器LinearLayoutManager,在它的构造函数里,有RecycrView.VERTICAL 和 RecyclerView.HORIZONTAL ,分别表示这个布局是往纵向滑的和横向划的。

 

代码实例

1. 首先要用这个控件,你需要在gradle文件中添加包的引用

在app下的build.grade 下添加 RecycleView的 依赖:

implementation 'androidx.recyclerview:recyclerview:1.0.0'

2. 创建一个主界面RecyclerViewActivity的布局文件recyclerview_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/recycleview"/>
</LinearLayout>

可以看到此界面的布局只有一个recyclerview控件

3. 主界面RecyclerViewActivity的逻辑代码

创建RecyclerViewActivity.kt (kotlin的类)

此界面为app启动的第一个页面。

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import androidx.recyclerview.widget.*
import com.ugc.andorid.landing.adapter.MessageAdapter
import com.ugc.andorid.landing.view_class.MessagePic

class RecyclerViewActivity: AppCompatActivity() {
    var messageList = mutableListOf<MessagePic>()
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.recyclerview_main)
        //初始化要现实的数据
        initMessages()
        var recyclerView:RecyclerView = findViewById(R.id.recycleview)
        //初始化布局管理器
        var myLayoutManager:LinearLayoutManager = LinearLayoutManager(this) //线性布局
        //var myLayoutManager:GridLayoutManager = GridLayoutManager(this,4)  //网格 布局
        //var myLayoutManager:StaggeredGridLayoutManager = StaggeredGridLayoutManager(4,OrientationHelper.VERTICAL) //瀑布布局
        recyclerView.layoutManager = myLayoutManager
        //创建适配器
        var messageAdapter:MessageAdapter = MessageAdapter(this,messageList)
        recyclerView.adapter = messageAdapter
    }

    /*初始化数据*/
    fun initMessages(){
        for(i in 1..20){
            var apple:MessagePic = MessagePic("apple",R.drawable.apple_pic)
            messageList.add(apple)
            var banana:MessagePic = MessagePic("banana",R.drawable.banana_pic)
            messageList.add(banana)
        }
    }
}

上面的代码中,初始化数据时,注意,我们是提前放了苹果的照片apple_pic.jpeg 和 香蕉的照片banana_pic.jpeg 进目录res/drawable中的。

4. 把创建的主界面加入到androidmanifest.xml

对主界面的布局和逻辑编写完成后,把该界面(即Activity)加入到Androidmanifest.xml中,相当于在系统中声明此Activity

在androidmanifest.xml中声明RecyclerViewActivity这个Activity

5.定义一栏数据显示的数据类型

MessagePic.kt:

这个类共有name和imageId两个类型。分别表示数据的名字和数据的图片的id。后续imageId会转成对应的图片,所以一栏数据展示的内容其实分别是 name和图片。

class MessagePic(var name:String, var imageId:Int) {
}

6. 定义一栏数据的布局

recycler_item.xml:

此布局表示,图片和名字信息会纵向地排列,即第一列数据为图片,第二列数据为name信息

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/image"/>
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/message_name"
        android:layout_gravity="center_vertical"
        android:text="aaa"
        android:layout_marginLeft="10dp"/>
</LinearLayout>

 

7. 编写RecyclerView控件的适配器

MessageAdapter.kt:

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.ugc.andorid.landing.R
import com.ugc.andorid.landing.view_class.MessagePic

class MessageAdapter:RecyclerView.Adapter<MessageAdapter.MyViewHolder> {


    private var datas:List<MessagePic>?=null
    private var context:Context?=null

    constructor(context:Context,datas:List<MessagePic>){
        this.context = context
        this.datas = datas
    }
    //定义ViewHolder
    class MyViewHolder(itemView:View):RecyclerView.ViewHolder(itemView){
        var name:TextView = itemView.findViewById(R.id.message_name)
        var image:ImageView = itemView.findViewById(R.id.message_image)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        var view = LayoutInflater.from(context).inflate(R.layout.recycler_item,parent,false)
        return MyViewHolder(view)
    }

    override fun getItemCount(): Int {
        return datas!!.size
    }

    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        var dataItem:MessagePic = datas!!.get(position)
        holder.image.setImageResource(dataItem.imageId)
        holder.name.setText(dataItem.name)
    }
}

运行效果:(可以上下滑动)

 

 

 

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值