zoukankan      html  css  js  c++  java
  • Android中RecyclerView用法,一步一步教你如何使用RecyclerView以及带你走过编码中可能会出现的坑~

    首先,要明白RecyclerView是做什么的?其次是为什么要用RecyclerView?这里牵扯到RecyclerView和ListView的区别,这里不废话,大家自行百度即可!

    以下示例我用的Android API 29 ,启用了AndroidX。

    第一步,添加依赖

    创建一个新的工程,在app/build.gradle中的dependencies闭包添加以下内容:

    implementation 'com.android.support:appcompat-v7:29.0.0'

      注意这里的‘29.0.0’要和你的 compileSdkVersion 版本号一致。版本号是28,就改为28。

    别的不需要改,以下是此时的项目目录以及gradle文件内容

    第二步,创建RecyclerView布局

    在你的布局文件中添加RecyclerView,切记要为RecyclerView添加id。

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity">
    
        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rv_card"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    
    </RelativeLayout>

    第三步,为RecyclerView中的item创建一个统一的布局文件

    在layout下创建一个名为layout_rv_card的布局文件,文件名命名要和你的实际业务相匹配方便后期查找。

     在此布局文件中,可以添加任何你想展示的视图,在这里我们先创建两个TextView为大家展示:

    <?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="50dp"
        android:gravity="center"
        android:orientation="horizontal">
    
        <TextView
            android:id="@+id/tv_id"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center" />
    
        <TextView
            android:id="@+id/tv_state"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:gravity="center" />
    </LinearLayout>

      别忘了添加id。

    第四步,创建Adapter

      Adapter是连接后端数据和前端显示的适配器接口,是数据和UI(View)之间一个重要的纽带。

      如果之前没有接触过,先跟着做,做完之后就会理解了。

      我们在项目目录下新建一个Java类,取名为CardAdapter。

       然后在CardAdapter中我们创建一个内部类MyViewHolder继承RecyclerView.ViewHolder。

      为什么要创建内部类?

      答:就是为了方便而已,创建在外部也是可以,但是如果项目大了之后,类太多不好区分,而且基本上因为布局的不同ViewHolder也基本不同,不会复用,所以创建在内部即可。

      为什么要使用ViewHolder?

      答:ViewHolder的主要任务:容纳View视图。前边我们提到Adapter连接了后端数据和前端显示,viewHolder的作用就是提供前端的视图文件。

    接下来,我们在ViewHolder绑定视图文件,同在activity中类似,itemView顾名思义即列表中每一项的视图,每一项都要绑定。

    import android.view.View;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    
    /**
     * @Author: Messi Mei
     * @Date: 2020/8/24 13:46
     * @Email: 709909986@qq.com
     **/
    public class CardAdapter {
        
        class MyViewHolder extends RecyclerView.ViewHolder {
            private TextView tvId,tvState;
            public MyViewHolder(@NonNull View itemView) {
                super(itemView);
                tvId = itemView.findViewById(R.id.tv_id);
                tvState = itemView.findViewById(R.id.tv_state);
            }
        }
    }
    

    第五步,完成Adapter

    在我们创建的CardAdapter类继承我们创建的内部类MyViewHolder,并重写提供的三个方法:

    onCreateViewHolder(),onBindViewHolder(),getItemCount()
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    
    /**
     * @Author: Messi Mei
     * @Date: 2020/8/24 13:46
     * @Email: 709909986@qq.com
     **/
    public class CardAdapter extends RecyclerView.Adapter<CardAdapter.MyViewHolder> {
    
        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            return null;
        }
    
        @Override
        public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
    
        }
    
        @Override
        public int getItemCount() {
            return 0;
        }
    
        class MyViewHolder extends RecyclerView.ViewHolder {
            private TextView tvId,tvState;
            public MyViewHolder(@NonNull View itemView) {
                super(itemView);
                tvId = itemView.findViewById(R.id.tv_id);
                tvState = itemView.findViewById(R.id.tv_state);
            }
        }
    }

    5.1重写onCreateViewHolder方法,返回我们的内部类MyViewHolder ,此处为将我们的item布局文件和adapter绑定。

     @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            View view = inflater.inflate(R.layout.layout_rv_card,parent,false);
            return new MyViewHolder(view);
        }

    也可以写为

    @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_rv_card,parent,false);
            return new MyViewHolder(view);
        }

    一样的。

    5.2为每一项视图,添加数据。

    此处holder为你每一项的MyViewHolder对象,position 定位,可以理解为list下标。

    @Override
        public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
            holder.tvId.setText(position);
            holder.tvState.setText(position+position);
        }

    5.3返回列表大小

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

    第六步,创建数据接口

    创建一个List列表(当然也可以是JsonArray),以此为例,我们创一个Card实体类,为List添加该类泛型。

     6.1接下来在CardAdapter创建一个带该list的构造器

    List<Card> list;
    
        public CardAdapter(List<Card> list) {
            this.list = list;
        }

    6.2在getItemCount方法中返回该列表大小

      @Override
      public int getItemCount() {
        return list == null ? 0 : list.size();
      }

    6.3在onBindViewHolder方法中绑定真实数据

      @Override
      public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.tvId.setText(list.get(position).getId());
        holder.tvState.setText(list.get(position).getState());
      }

    以下为整体代码(文末有我在使用RecycleView中对Adapter的改进代码,如有需要可以参考):

    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    import java.util.List;
    
    /** @Author: Messi Mei @Date: 2020/8/24 13:46 @Email: 709909986@qq.com */
    public class CardAdapter extends RecyclerView.Adapter<CardAdapter.MyViewHolder> {
      private List<Card> list;
    
      public CardAdapter(List<Card> list) {
        this.list = list;
      }
    
      @NonNull
      @Override
      public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_rv_card, parent, false);
        return new MyViewHolder(view);
      }
    
      @Override
      public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
        holder.tvId.setText(list.get(position).getId());
        holder.tvState.setText(list.get(position).getState());
      }
    
      @Override
      public int getItemCount() {
        return list == null ? 0 : list.size();
      }
    
      static class MyViewHolder extends RecyclerView.ViewHolder {
        private TextView tvId, tvState;
    
        MyViewHolder(@NonNull View itemView) {
          super(itemView);
          tvId = itemView.findViewById(R.id.tv_id);
          tvState = itemView.findViewById(R.id.tv_state);
        }
      }
    }

    第七步,使用RecycleView

    在Activity中创建RecycleView对象并绑定视图,创建Adapter对象。

    在initData中初始化数据。

    package com.mz.myapplication;
    
    import android.os.Bundle;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
      private RecyclerView recyclerView;
      private CardAdapter cardAdapter;
      private List<Card> list;
    
      @Override
      protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initData();
        initView();
      }
    
      private void initData() {
          list = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            Card card = new Card();
            card.setId(i+1+"");
            if (i%2 == 1){
                card.setState("在线");
            }else{
                card.setState("离线");
            }
            list.add(card);
        }
      }
    
      private void initView() {
        recyclerView = findViewById(R.id.rv_card);
        cardAdapter = new CardAdapter(list);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setAdapter(cardAdapter);
      }
    }

    至此,运行即可。

    如果你想要更复杂的列表布局,在布局文件中加入相应的视图即可,修改完后记得在ViewHolder中加入、绑定相应的视图,在Adapter中的onBindViewHolder为其添加、绑定数据。

    而我更推荐以下这种方式,用set方法去设置Adapter中的数据,更加灵活。

    package com.mz.myapplication;
    
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    
    import androidx.annotation.NonNull;
    import androidx.recyclerview.widget.RecyclerView;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /** @Author: Messi Mei @Date: 2020/8/24 13:46 @Email: 709909986@qq.com */
    public class Card2Adapter extends RecyclerView.Adapter<Card2Adapter.MyViewHolder> {
      private List<Card> list = new ArrayList<>();
    
      public void setList(List<Card> list) {
        this.list = list;
      //一定要记得加,否则视图不会更新!!! notifyDataSetChanged(); } @NonNull @Override
    public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.layout_rv_card, parent, false); return new MyViewHolder(view); } @Override public void onBindViewHolder(@NonNull MyViewHolder holder, int position) { holder.tvId.setText(list.get(position).getId()); holder.tvState.setText(list.get(position).getState()); } @Override public int getItemCount() { return list == null ? 0 : list.size(); } static class MyViewHolder extends RecyclerView.ViewHolder { private TextView tvId, tvState; MyViewHolder(@NonNull View itemView) { super(itemView); tvId = itemView.findViewById(R.id.tv_id); tvState = itemView.findViewById(R.id.tv_state); } } }
    package com.mz.myapplication;
    
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.recyclerview.widget.LinearLayoutManager;
    import androidx.recyclerview.widget.RecyclerView;
    
    import android.os.Bundle;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Main2Activity extends AppCompatActivity {
        private RecyclerView recyclerView;
        private Card2Adapter card2Adapter;
        private List<Card> list;
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main2);
            initView();
            initData();
        }
        private void initData() {
            list = new ArrayList<>();
            for (int i = 0; i < 50; i++) {
                Card card = new Card();
                card.setId(i+1+"");
                if (i%2 == 1){
                    card.setState("在线");
                }else{
                    card.setState("离线");
                }
                list.add(card);
            }
            card2Adapter.setList(list);
        }
    
        private void initView() {
            recyclerView = findViewById(R.id.rv_card);
            card2Adapter = new Card2Adapter();
            recyclerView.setLayoutManager(new LinearLayoutManager(this));
            recyclerView.setAdapter(card2Adapter);
        }
    }

    这样你可以在任意位置修改列表中的数据。

  • 相关阅读:
    河北省科技创新年报统计系统分析
    《软件需求十步走》阅读笔记06
    《软件需求十步走》阅读笔记05
    《软件需求十步走》阅读笔记04
    河北科技创新平台年报统计
    《软件需求十步走》阅读笔记03
    《软件需求十步走》阅读笔记02
    《软件需求十步走》阅读笔记01
    案例分析
    2017秋季个人阅读计划
  • 原文地址:https://www.cnblogs.com/mzxiaoze/p/13554222.html
Copyright © 2011-2022 走看看