有勇气的牛排博客
☰

安卓 滚动控件RecyclerView androidx.widget.RecyclerView

有勇气的牛排 1891 安卓 2021-10-19 00:24:49

知止自律打卡-微信小程序APP
一款微信自律打卡小程序,支持自定义打卡项目、习惯记录、项目日记、专注计时与数据统计。自律打卡、学习打卡、读书打卡、健身打卡、运动打卡、减肥打卡、戒色打卡、养生打卡、戒烟、戒酒、戒熬夜等多种场景。万能打卡模板自由创建。可自定义每日打卡目标,记录习惯连续天数,可视化追踪成长进度。
了解产品详情 →
微信搜索「知止自律打卡」
知止自律打卡微信小程序

1 介绍

滚动控件RecyclerView可以说是增强版的ListView。 其不仅可以轻松实现和ListView同样的效果,还优化了ListView中存在的各种不足。

2 导包

// 注入框架
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:design:28.0.0'

3 布局文件

3.1 activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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/recycler_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"></androidx.recyclerview.widget.RecyclerView>

</androidx.constraintlayout.widget.ConstraintLayout>

3.2 shop_item.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_gravity="center"
    android:layout_margin="5dp"
    android:background="@drawable/selector_list_item"
    android:gravity="center"
    app:cardBackgroundColor="#fff"
    app:cardCornerRadius="4dp"
    app:contentPadding="5dp">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="120dp"
        android:orientation="horizontal"
        android:padding="5dp">

        <ImageView
            android:id="@+id/shop_image"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginRight="5dp"
            android:layout_weight="2"
            android:scaleType="fitXY" />

        <LinearLayout
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="3"
            android:orientation="vertical">

            <TextView
                android:id="@+id/shop_name"
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="2"
                android:maxLines="2"
                android:text="6666666666666666666666666666666666666"
                android:textColor="@color/base_color"
                android:textSize="14sp" />

            <RelativeLayout
                android:layout_width="match_parent"
                android:layout_height="0dp"
                android:layout_weight="1">

                <TextView
                    android:id="@+id/text_price"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:text="价格"
                    android:textColor="@color/firebrick"
                    android:textSize="16sp" />

                <TextView
                    android:id="@+id/text_stock"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentBottom="true"
                    android:layout_toRightOf="@+id/text_price"
                    android:layout_marginLeft="30dp"
                    android:text=""
                    android:textSize="13sp" />

                <TextView
                    android:id="@+id/text_num"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:layout_alignParentRight="true"
                    android:layout_alignParentBottom="true"
                    android:text="数量" />
            </RelativeLayout>
        </LinearLayout>
    </LinearLayout>
</LinearLayout>

3.3 selector_list_item.xml

<?xml version="1.0" encoding="utf-8"?>

<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item  android:state_focused="true" android:drawable="@color/gainsboro" />
    <item  android:state_pressed="true" android:drawable="@color/gainsboro" />
    <item android:drawable="@color/white"/>
</selector>

3.4 colors.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="purple_200">#FFBB86FC</color>
    <color name="purple_500">#FF6200EE</color>
    <color name="purple_700">#FF3700B3</color>
    <color name="teal_200">#FF03DAC5</color>
    <color name="teal_700">#FF018786</color>
    <color name="black">#FF000000</color>
    <color name="white">#FFFFFFFF</color>

    <!--userInfo font  主字体 颜色 -->
    <color name="base_color">#505050</color>
    <!-- 暗金黄色 -->
    <color name="firebrick">#b22222</color>
    <!-- 洋李色 -->
    <color name="gainsboro">#dcdcdc</color>
</resources>

4 bean层

package com.example.study.bean;

public class ShopBean {
    private String name;
    private int imageID;

    public ShopBean(String name, int imageID) {
        this.name = name;
        this.imageID = imageID;
    }

    public String getName() {
        return name;
    }

    public int getImageID() {
        return imageID;
    }
}

5 适配器

package com.example.study.adapter;

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

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.study.R;
import com.example.study.bean.ShopBean;

import java.util.List;

public class ShopAdapter extends RecyclerView.Adapter<ShopAdapter.ViewHolder> {
    private List<ShopBean> mShopList;


    /**
     * onCreateViewHolder用于创建ViewHolder实例的,我们在这个方法中将shop_item布局加载进来,
     * 然后创建一个ViewHolder实例,并把加载进来的方法的布局传入到构造函数中,最后将ViewHolder的实例返回
     * */
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.shop_item, null);
        ViewHolder holder = new ViewHolder(view);
        return holder;
    }


    public ShopAdapter(List<ShopBean> shopList){
        mShopList=shopList;
    }
    /**
     * onBindViewHolder()方法是用于对RecyclerView子项的数据进行复制的,会在每个子项滚动到屏幕内的时候执行,
     * 这里我们通过position参数得到当前的Shop实例,然后再讲数据设置到ViewHolder的ImageView和TextView当中即可。
     * */
    @Override
    public void onBindViewHolder(@NonNull ShopAdapter.ViewHolder holder, int position) {
        ShopBean shop = mShopList.get(position);
        holder.shopImage.setImageResource(shop.getImageID());
        holder.shopName.setText(shop.getName());
    }

    /**
     * getItemCount()方法就很简单了,它用于告诉ReccylerView有多少子项,直接返回数据源的长度
     * */
    @Override
    public int getItemCount() {
        return mShopList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        ImageView shopImage;
        TextView shopName;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            shopImage = itemView.findViewById(R.id.shop_image);
            shopName = itemView.findViewById(R.id.shop_name);
        }
    }
}

6 MainActivity.java

package com.example.study;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.example.study.adapter.ShopAdapter;
import com.example.study.bean.ShopBean;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {

    private List<ShopBean> shopList = new ArrayList<>();

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initShops();
        RecyclerView recyclerView = findViewById(R.id.recycler_view);
        LinearLayoutManager layoutManager = new LinearLayoutManager(this);
        // 设置方向
//        layoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
        recyclerView.setLayoutManager(layoutManager);
        ShopAdapter adapter = new ShopAdapter(shopList);
        recyclerView.setAdapter(adapter);
    }

    private void initShops() {
        for (int i = 0; i < 6; i++) {
            ShopBean demo1 = new ShopBean("demo1", R.drawable.logo);
            ShopBean demo2 = new ShopBean("demo2", R.drawable.ic_launcher);
            ShopBean demo3 = new ShopBean("demo3", R.drawable.logo);
            ShopBean demo4 = new ShopBean("demo4", R.drawable.ic_launcher);
            ShopBean demo5 = new ShopBean("demo5", R.drawable.logo);
            ShopBean demo6 = new ShopBean("demo6", R.drawable.ic_launcher);
            shopList.add(demo1);
            shopList.add(demo2);
            shopList.add(demo3);
            shopList.add(demo4);
            shopList.add(demo5);
            shopList.add(demo6);
        }
    }
}

7 效果

安卓RecyclerView效果

8 监听器 修改 ShopAdapter.java

不同于ListView的是,RecyclerView并没有提供类似于setOnItemClickListener()这样的注册监听器的方法,而我们自己给子项具体的view去注册点击事件,相比于ListView来说,实现起来要复杂些。为什么说EecyclerView在各方面的设计都要优于ListView。
RecyclerView干脆直接摒弃了子项点击事件监听器,所有的点击事件,都由具体的View去注册。

package com.example.study.adapter;

import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;

import com.example.study.R;
import com.example.study.bean.ShopBean;

import java.util.List;

public class ShopAdapter extends RecyclerView.Adapter<ShopAdapter.ViewHolder> {
    private List<ShopBean> mShopList;


    /**
     * onCreateViewHolder用于创建ViewHolder实例的,我们在这个方法中将shop_item布局加载进来,
     * 然后创建一个ViewHolder实例,并把加载进来的方法的布局传入到构造函数中,最后将ViewHolder的实例返回
     */
    @NonNull
    @Override
    public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.shop_item, null);
        ViewHolder holder = new ViewHolder(view);

        // item的监视器
        holder.shopView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition(); // 获取点击的位置
                ShopBean shop = mShopList.get(position);    // 获取shop 商品
                Toast.makeText(view.getContext(), "你点击了" + shop.getName(), Toast.LENGTH_SHORT).show();
            }
        });

        //imageView的监听器
        holder.shopImage.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                int position = holder.getAdapterPosition(); // 获取点击位置
                ShopBean shop = mShopList.get(position);    // 获取shop
                Toast.makeText(view.getContext(), "你点击了" + shop.getName() + "的图片", Toast.LENGTH_SHORT).show();
            }
        });

        return holder;
    }


    public ShopAdapter(List<ShopBean> shopList) {
        mShopList = shopList;
    }

    /**
     * onBindViewHolder()方法是用于对RecyclerView子项的数据进行复制的,会在每个子项滚动到屏幕内的时候执行,
     * 这里我们通过position参数得到当前的Shop实例,然后再讲数据设置到ViewHolder的ImageView和TextView当中即可。
     */
    @Override
    public void onBindViewHolder(@NonNull ShopAdapter.ViewHolder holder, int position) {
        ShopBean shop = mShopList.get(position);
        holder.shopImage.setImageResource(shop.getImageID());
        holder.shopName.setText(shop.getName());
    }

    /**
     * getItemCount()方法就很简单了,它用于告诉ReccylerView有多少子项,直接返回数据源的长度
     */
    @Override
    public int getItemCount() {
        return mShopList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        View shopView;          // 监听相关:用来保存RecyclerView的子项最外层的实例
        ImageView shopImage;
        TextView shopName;

        public ViewHolder(@NonNull View itemView) {
            super(itemView);
            shopView = itemView;  // 监听相关:赋值
            shopImage = itemView.findViewById(R.id.shop_image);
            shopName = itemView.findViewById(R.id.shop_name);
        }
    }

}

9 点击效果

RecyclerView效果 点击效果

参考:
https://blog.csdn.net/qq_39326574/article/details/98098520

×
×