安卓 滚动控件RecyclerView androidx.widget.RecyclerView
知止自律打卡-微信小程序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
-
layout下
-
主文件
<?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
-
layout下
-
商品通用模板
<?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
- drawable目录下
<?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
- values目录下
<?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层
- ShopBean .java
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 适配器
- ShopAdapter.java
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 效果

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 点击效果

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