欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

《第一行代码》阅读笔记(十)——RecyclerView

程序员文章站 2022-03-29 17:53:46
按照书上的说法就是RecycleView更强大!而且目前来看ListView基本上已经淘汰了,所以让我们来看看RecycleView吧。导包因为版本更新,书上的已经过时了,所以我百度了一下,发现了这个两个版本。v7:implementation ‘com.android.support:recyclerview-v7:28.0.0’x:implementation ‘androidx.recyclerview:recyclerview:1.1.0’参考文章:Android Studio新版本导入R...

按照书上的说法就是RecycleView更强大!而且目前来看ListView基本上已经淘汰了,所以让我们来看看RecycleView吧。

导包

因为版本更新,书上的已经过时了,所以我百度了一下,发现了这个两个版本。

v7:implementation ‘com.android.support:recyclerview-v7:28.0.0’
x:implementation ‘androidx.recyclerview:recyclerview:1.1.0’

参考文章:Android Studio新版本导入Recyclerview库的依赖
总是听到有人说AndroidX,到底什么是AndroidX?

简单来说就是Androidx比较新,v7比较老,同时两个包不能同时使用,会在某些地方出现冲突。一般现在都用x了

案例

第一步:修改activity_ main.xml

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

其实就是把之前的ListView改成RecyclerView,但是RecyclerView需要全类名

第二步:给RecyclerView新建一个适配器
先把ListView项目的Fruit类和fruit_item布局复制过来,可以去上一个章节寻找相关资料。

package com.firstcode.customuicontrols;

import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;

import java.util.List;

import androidx.recyclerview.widget.RecyclerView;

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

    private List<Fruit> mFruitList;

    static class ViewHolder extends RecyclerView.ViewHolder {
        ImageView fruitImage;
        TextView fruitName;

        public ViewHolder(View view) {
            super(view);
            fruitImage = (ImageView) view.findViewById(R.id.image_view);
            fruitName = (TextView) view.findViewById(R.id.text_view);
        }
    }


    public FruitRecyclerViewAdapter(List<Fruit> fruitList) {
        mFruitList = fruitList;
    }

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

    @Override
    public void onBindViewHolder( ViewHolder holder, int position) {
        Fruit fruit = mFruitList.get(position);
        holder.fruitImage.setImageResource(fruit.getImageId());
        holder.fruitName.setText(fruit.getName());
    }

    @Override
    public int getItemCount() {
        return mFruitList.size();
    }
}

因为避免和上一个案例重复,我自己修改了类名,其他的都是一样的。

这里说一下笔者的理解,首先就是使用了一个内部类,实现了RecyclerView每个子项的初始化。这个用法理解起来还是比较复杂的,笔者个人的理解就是内部类的形式实例化一个View,然后可以对其进行很多的操作。

第二部分就是整个适配器的构造函数,可以看出RecyclerView的适配器只需要传入一个数组即可。因为它把子项控件的初始化和布局的加载通过其他函数内置了,就是内部类和onCreateViewHolder。

onCreateViewHolder就是初始化,加载布局的。同样是使用LayoutInflater方法,但是我发现只要在Activity中,环境变量才能使用Activity或者this,而在其他的类中大多数使用View的方法getContext。这也间接的说明View和Activity就是环境。

onBindViewHolder通过书上的介绍就是在每个子项展示的时候调用,就是很简单的通过位置设置值。

最后一个函数就是返回数组长度。

但是笔者这里发现inflate的参数和之前自定义控件时候使用的不同。搜索了一下,发现其有四个构造函数。

《第一行代码》阅读笔记(十)——RecyclerView

这里有个新的概念就是ViewGroup,其实简单的来说就是像LinearLayout 之类的布局就是ViewGroup,而那些控件像Button就是一种View,View是ViewGroup的父类。到这里我就明白inflate的含义了。

《第一行代码》阅读笔记(十)——RecyclerView

先说为什么之前使用的inflate是两个参数的,它使用的是图中第一个构造函数,int类型的是布局id,而ViewGroup就是父布局,当时传入的是当前的Activity,其实Activity也是一个View。
而Adapter为啥要传入三个参数,因为Adapter是为list服务的,list自己有一个总体的布局,而他的子项也是一个布局,需要加载其中。所以使用图中第三个构造函数,最后的布尔型参数取消新建布局,把子布局放到list的子项里面。

参考资料
基础篇——View和ViewGroup的区别
Android LayoutInflate深度解析
Android View原理浅析——View的工作原理
Android View详解

第三步:修改MainActivity

RecyclerView recyclerView = (RecyclerView) findViewById(R.id.list_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        FruitRecyclerViewAdapter adapter = new FruitRecyclerViewAdapter(fruitList);
        recyclerView.setAdapter(adapter);

横向滑动

第一步 修改布局

其实就是把原来的横向布局改为竖向,文字和图片调整大小

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

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center_horizontal"/>

    <TextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:gravity="center_vertical"
        android:layout_gravity="center_horizontal"
        android:layout_marginTop="10dp"/>


</LinearLayout>

第二步:加载布局
只有一个操作,在之前加载布局前设置横向设置

        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);

瀑布布局

第一步还是修改布局

<?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:layout_margin="5dp"
    android:orientation="vertical">

    <ImageView
        android:id="@+id/image_view"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_gravity="center_horizontal" />

    <TextView
        android:id="@+id/text_view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="left"
        android:layout_marginTop="10dp" />


</LinearLayout>

第二步是也是一样的加载布局,同样的只需要一行代码就行了。

StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(3,StaggeredGridLayoutManager.VERTICAL);
        recyclerView.setLayoutManager(staggeredGridLayoutManager);

《第一行代码》阅读笔记(十)——RecyclerView

网格布局

到这里我已经感受到了RecycleView的强大之处,在于可以在List之上添加布局,虽然有些地方还是不明白。书中并没有网格布局的代码,也是留了个作业,所以我们就在这做一下,练练手。

在网上查阅了资料发现GridLayoutManager有两个参数,第一个就是上下文,第二个就是列数。
所以修改代码如下

GridLayoutManager gridLayoutManager = new GridLayoutManager(this, 2);
        recyclerView.setLayoutManager(gridLayoutManager);

《第一行代码》阅读笔记(十)——RecyclerView

点击事件

第一步:修改适配器代码

具体代码修改不多,和之前的按钮的点击事件相似。大家看看书本上的讲解应该就能明白。

规范

  1. 在实际开发中一般不使用构造函数来赋值,会写一个setData()方法来传入数据。这样可以保证实例化和赋值分开,减少错误。
  2. 点击事情写在ViewHolder里面,在onBindView方法中调用,这样结构更加清晰。

本文地址:https://blog.csdn.net/SafeVidulInfo/article/details/107525737