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


    按照书上的说法就是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的参数和之前自定义控件时候使用的不同。搜索了一下,发现其有四个构造函数。

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

    先说为什么之前使用的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);
    

    网格布局

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

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

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

    点击事件

    第一步:修改适配器代码

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

    规范

    1. 在实际开发中一般不使用构造函数来赋值,会写一个setData()方法来传入数据。这样可以保证实例化和赋值分开,减少错误。
    2. 点击事情写在ViewHolder里面,在onBindView方法中调用,这样结构更加清晰。
  • 相关阅读:
    JS之RegExp对象(一)
    八大排序算法总结
    mysql创建数据库指定编码格式
    Java学习笔记_22_Set接口的实现类
    HDU--杭电--3415--Max Sum of Max-K-sub-sequence--暴力或单调队列
    第六届蓝桥杯JavaB组省赛真题
    第六届蓝桥杯JavaA组省赛真题
    第六届蓝桥杯JavaA组省赛真题
    第六届蓝桥杯JavaA组省赛真题
    第六届蓝桥杯JavaA组省赛真题
  • 原文地址:https://www.cnblogs.com/zllk/p/13363729.html
Copyright © 2020-2023  润新知