四、完整代码示例
RecyclerView.ItemDecoration 代码示例 :
package kim.hsl.recyclerview; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Rect; import android.view.View; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; public class ItemDecoration extends RecyclerView.ItemDecoration { @Override public void onDraw(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { // 1. 获取当前的组件个数 int itemCount = parent.getChildCount(); // 2. 遍历当前的所有组件 for (int i = 0; i < itemCount; i++) { // 3. 获取组件 View 对象 View view = parent.getChildAt(i); // 4. 获取 item 组件相对于父容器的坐标 int left = view.getLeft(); int top = view.getTop(); int right = view.getRight(); int bottom = view.getBottom(); // 5. 根据上述坐标进行绘图 if (i % 4 == 0){ // 给每一行的第一个元素绘制红色矩形背景, 向外延展 5 像素 Paint paint = new Paint(); paint.setColor(Color.RED); c.drawRect(left - 5, top - 5, right + 5, bottom + 5, paint); } } } @Override public void onDrawOver(@NonNull Canvas c, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { // 1. 获取当前的组件个数 int itemCount = parent.getChildCount(); // 2. 遍历当前的所有组件 for (int i = 0; i < itemCount; i++) { // 3. 获取组件 View 对象 View view = parent.getChildAt(i); // 4. 获取 item 组件相对于父容器的坐标 int left = view.getLeft(); int top = view.getTop(); int right = view.getRight(); int bottom = view.getBottom(); // 5. 根据上述坐标进行绘图 if (i % 2 == 0){ // 偶数序号的元素绘制蓝色圆形遮罩 Paint paint = new Paint(); paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5F); c.drawCircle((left + right) / 2F, (top + bottom) / 2F, (right - left) / 4F, paint); }else{ // 奇数序号的元素绘制红色矩形遮罩 Paint paint = new Paint(); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(5F); c.drawRect(left + 20, top + 20, right - 20, bottom - 20, paint); } } } @Override public void getItemOffsets(@NonNull Rect outRect, @NonNull View view, @NonNull RecyclerView parent, @NonNull RecyclerView.State state) { // 1. 获取当前设置边距的位置 int currentPosition = parent.getChildAdapterPosition(view); // 2. 针对不同的位置设置不同的边距 // 每排最左侧和最右侧的左右边距设置成 20 像素, 其余 4 个边距一律设置成 5 if (currentPosition % 4 == 0){ // 每排最左侧的边距 outRect.left = 40; outRect.top = 20; outRect.right = 20; outRect.bottom = 20; }else if (currentPosition %4 == 3){ // 每排最右侧的边距 outRect.left = 20; outRect.top = 20; outRect.right = 40; outRect.bottom = 20; }else{ // 普通元素的边距都是 5 outRect.left = 20; outRect.top = 20; outRect.right = 20; outRect.bottom = 20; } } }
主界面代码示例 :
package kim.hsl.recyclerview; import android.graphics.Color; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; import androidx.recyclerview.widget.StaggeredGridLayoutManager; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); //1 . 从布局中获取 RecyclerView RecyclerView recycler_view = findViewById(R.id.recycler_view); //2 . 创建并设置布局管理器 //创建布局管理器 StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager( 4, RecyclerView.VERTICAL); //设置布局管理器 recycler_view.setLayoutManager(layoutManager); // 设置边距 recycler_view.addItemDecoration(new ItemDecoration()); //3 . 创建并设置列表适配器 Adapter adapter = new Adapter(); recycler_view.setAdapter(adapter); } /** * RecyclerView 适配器 */ public class Adapter extends RecyclerView.Adapter<Adapter.ViewHolder> { @Override public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { View root_view = LayoutInflater.from(MainActivity.this) .inflate(R.layout.item_recyclerview, parent, false); return new ViewHolder(root_view); } @Override public void onBindViewHolder(@NonNull ViewHolder holder, int position) { holder.text.setText("" + position); } @Override public int getItemCount() { return 100; } public class ViewHolder extends RecyclerView.ViewHolder { TextView text; public ViewHolder(@NonNull View itemView) { super(itemView); text = itemView.findViewById(R.id.text); } } } }
运行效果 :
① 边距 : 正常的 item 边距设置都是 20 像素 , 每行最左侧距离左边 40 像素 , 每行最右侧边距距离右侧 40 像素 ;
① item 底部背景 : 使用 onDraw 方法绘制 , 给每行的第一个元素绘制一个底部背景 , 该背景会被 item 组件覆盖 ;
③ item 上层遮罩 : 使用 onDrawOver 方法绘制 , 给偶数序号的 item 元素绘制蓝色圆形遮罩 , 给奇数序号的 item 元素绘制红色矩形遮罩 ;
五、RecyclerView 相关资料
官方文档 :
使用 RecyclerView 创建动态列表 : https://developer.android.google.cn/guide/topics/ui/layout/recyclerview
高级 RecyclerView 自定义 : https://developer.android.google.cn/guide/topics/ui/layout/recyclerview-custom
代码示例 :
GitHub 源码地址 : https://github.com/han1202012/001_RecyclerView
博客源码快照 : https://download.csdn.net/download/han1202012/14951850
( 使用 Android Studio 打开 )