有勇气的牛排博客

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

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

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

安卓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


留言

专栏
文章
加入群聊