Android——RecyclerView简单实现及Viewbinding优化

 本文是博主对Adapter(适配器)的一些理解,为了加深对Adapter的理解以及记录自己的阶段学习而写,同时也适合初学者阅读,参考本条博客的逻辑进行学习。

首先需要的代码如下:

目录

(1)XML主代码

(2)XML布局文件

(3)Java内容类Message

(4)Java主代码

(5)Java适配器recy_Adapter类

 (6)效果图


(1)XML主代码

首先布置主界面的布局,就一个recyclerview即可

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

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

(2)XML布局文件

接下来设置recyclerview中每个item的布局

<?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"
    android:background="#FFFFFF"
    android:paddingTop="10dp"
    android:paddingBottom="10dp"
    android:paddingRight="20dp"
    android:paddingLeft="20dp">


    <ImageView
        android:id="@+id/imagess"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_marginRight="10dp"
        android:src="@android:mipmap/sym_def_app_icon" />


    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="1"
        android:orientation="vertical">

        <TextView
            android:id="@+id/name"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:textColor="@color/black"
            android:textSize="16sp" />

        <TextView
            android:id="@+id/news"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="14sp"
            android:textColor="#666666" />

    </LinearLayout>

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="end"
        android:textColor="#999999"
        android:textSize="14sp"
        android:text="2021年4月24日\n19:02:50"/>

</LinearLayout>

(3)Java内容类Message

接着就是设置每个item的内容是什么类型的,把所有内容聚集成一个对象,方便后续从对象中获取需要的内容

package com.example.recyclerview;

public class Message {
    private int imageId;
    private String name;
    private String subText;
    private String time;

    public int getImageId() {
        return imageId;
    }

    public String getName() {
        return name;
    }

    public String getTime() {
        return time;
    }

    public String getSubText() {
        return subText;
    }

    public Message(int imageId, String name, String subText,String time) {
        this.imageId = imageId;
        this.name = name;
        this.subText = subText;
        this.time=time;
    }
}

(4)Java主代码

接下来初始化控件,初始化数据,给控件设置布局,最后绑定适配器。

public class MainActivity extends AppCompatActivity{
    RecyclerView recyclerView;
    List<Message> list = new ArrayList<Message>();
    LinearLayoutManager linearLayoutManager;
    recy_Adapter recy_adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initview();
        initdata();
        settinglayout();
        binddata();
    }

    //给recycler设置一个布局
    private void settinglayout() {
        linearLayoutManager = new LinearLayoutManager
                (this, RecyclerView.VERTICAL, false);
    }

    //为控件绑定适配器
    private void binddata() {
        recy_adapter = new recy_Adapter(this, list);
        recyclerView.setAdapter(recy_adapter);
        recyclerView.setLayoutManager(linearLayoutManager);
    }

    //初始化List的数据
    private void initdata() {
        Message message1 = new Message(R.drawable.like, "喜欢"
                , "想要去北极玩", "2021年4月24日"+"\n"+"19:06:50");
        list.add(message1);

        Message message2 = new Message(R.drawable.local, "定位"
                , "想要去北极", "2021年4月24日"+"\n"+"19:06:50");
        list.add(message2);

        Message message3 = new Message(R.drawable.report, "举报"
                , "想要去北", "2021年4月24日"+"\n"+"19:06:50");
        list.add(message3);

        Message message4 = new Message(R.drawable.share, "分享"
                , "想要去", "2021年4月24日"+"\n"+"19:06:50");
        list.add(message4);
    }

    //找控件
    private void initview() {
        recyclerView = findViewById(R.id.recycler);
    }

(5)Java适配器recy_Adapter类

最后是自定义适配器一开始实现接口会爆红,把接口实现了就正常,就是以下这个图。

public class recy_Adapter extends RecyclerView.Adapter<recy_Adapter.MyAdapter> {

    @NonNull
    @Override
    public MyAdapter onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return null;
    }

    @Override
    public void onBindViewHolder(@NonNull MyAdapter holder, int position) {

    }

    @Override
    public int getItemCount() {
        return 0;
    }

    public class MyAdapter extends RecyclerView.ViewHolder{

        public MyAdapter(@NonNull View itemView) {
            super(itemView);
        }
    }
}

然后写入传统方法,已注释

    /*
    ① 创建一个继承RecyclerView.Adapter<VH>的Adapter类
    ② 创建一个继承RecyclerView.ViewHolder的静态内部类
    ③ 在Adapter中实现3个方法:
       onCreateViewHolder()
       onBindViewHolder()
       getItemCount()
    */
public class recy_Adapter extends RecyclerView.Adapter<recy_Adapter.MyAdapter>{
    Context context;
    List<Message> list=new ArrayList<Message>();

    //构造方法
    public recy_Adapter(Context context, List<Message> list) {
        this.context = context;
        this.list = list;
    }

     @Override
    //返回Item总条数
    public int getItemCount() {
        return list == null ? 0 : list.size();
    }

    @NonNull
    @Override
    //创建ViewHolder,返回每一项的布局
    public MyAdapter onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //用LayoutInflater类的方法创建一个layoutinflater对象
        LayoutInflater layoutInflater = (LayoutInflater) context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        //调用inflater方法实例化recy_list的xml文件,并返回View对象还赋予一个parent父布局
        View view = layoutInflater.inflate(R.layout.recy_list, parent, false);
        //把布局中的控件利用自己创建的类给绑定起来,此时myAdapter就有了某个item里面的所有控件
        MyAdapter myAdapter = new MyAdapter(view);
        //返回对象
        return myAdapter;
    }

    @Override
    //将数据和控件绑定,获取List中对应的数据然后set到控件中(简单来说就是设置item中的控件信息)
    //第一个参数是onCreateViewHolder回调中的返回值,等于你那项item和里面的控件都获取了
    //第二个参数是每个item在List数据中的位置,从0开始数
    public void onBindViewHolder(@NonNull MyAdapter holder, int position) {
        //获取List列表中对应位置的Message的对象
        Message message = list.get(position);
        //从对象中取出对应的字段数据
        holder.image.setImageResource(message.getImageId());
        holder.name.setText(message.getName());
        holder.subtext.setText(message.getSubText());
        holder.time.setText(message.getTime());
    }

    //内部类,绑定控件
    public class MyAdapter extends RecyclerView.ViewHolder{
        //布局有什么控件就写定义什么
        TextView name,subtext,time;
        ImageView image;

        //找item里的控件
        public MyAdapter(@NonNull View itemView) {
            super(itemView);
            image = itemView.findViewById(R.id.imagess);
            name = itemView.findViewById(R.id.name);
            subtext = itemView.findViewById(R.id.news);
            time = itemView.findViewById(R.id.time);
        }
}

用ViewBinding优化后的Adapter

public class recy_Adapter extends RecyclerView.Adapter<recy_Adapter .MyAdapter> {
    private final Context context;
    private final List<Message> list;
    public recy_Adapter (Context context, List<Message> list) {
        this.context= context;
        this.list= list;
    }
    @Override
    public int getItemCount() {
        return  list == null ? 0 : list.size();
    }
    @NonNull
    @Override
    public MyAdapter onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        ItemListBinding it=ItemListBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false))
        return new MyAdapter(it);
    }
    @Override
    public void onBindViewHolder(@NonNull MyAdapter holder, int position) {
        Message message = list.get(position);
        holder.mView.image.setImageResource(message .getImageId());
        holder.mView.name.setText(message .getName());
        holder.mView.subtext.setText(message .getSubText());
        holder.mView.time.setText(message .getTime());
    }
    static class MyAdapter extends RecyclerView.ViewHolder {
        ItemListBinding mView;
        public MyAdapter (ItemListBinding itemView) {
            super(itemView.getRoot());
            this.mView = itemView;
        }
    }
}

通俗的说,inflate就相当于将一个xml中定义的布局找出来。

因为在一个Activity里如果直接用findViewById()的话,找的是setConentView()的那个layout布局里的组件。

因此如果你的Activity里如果用到别的layout,比如对话框上的layout布局,你还要设置对话框上的layout布局里的组件像ImageView,TextView上的内容,你就必须用inflate()先将对话框上的layout布局找出来,然后再用这个layout布局对象去找到它上面的组件,如:

从一个Context中,获得一个布局填充器,这样你就可以使用这个填充器来把xml布局文件转为View对象了。

//加载整个应用的布局管理器
LayoutInflater layoutInflater= LayoutInflater.from(context);
//利用布局管理器,将xml布局转换为view对象
convertView = layoutInflater.inflate(R.layout.item_myseallist,parent, false);
//利用view对象,找到xml布局中的组件
convertView.findViewById(R.id.delete);

(6)效果图

上面已经注释的挺简单了,后面我觉得不好再修改,下面就是写完后的效果,但是还没有设置点击事件,后面我写完的时候再更新一下博客。

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

七qi_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值