首页 > 其他分享 >RecyclerView添加分割线

RecyclerView添加分割线

时间:2023-02-22 10:38:36浏览次数:26  
标签:parent int 分割线 添加 import android RecyclerView


RecyclerView 并没有 divider 属性,但是我们可以通过 RecyclerView 的 addItemDecoration() 来添加分割线,该方法参数为 RecyclerView.ItemDecoration。

介绍

当 RecyclerView 添加 ItemDecoration 后,RecyclerView 在绘制每个 item 的时候,会去绘制 decorator,也就是会调用 ItemDecoration 的 onDraw() 和 onDrawOver() 方法。

RecyclerView.ItemDecoration 是抽象类,主要提供三个方法:

  • onDraw(Canvas c, RecyclerView parent, State state): 在绘制item(drawChild) 前调用
  • onDrawOver(Canvas c, RecyclerView parent, State state): 在绘制item(drawChild) 后调用
  • getItemOffsets(Rect outRect, View view, RecyclerView parent, State state):outRect设置 item 的偏移量,用于绘制 decorator(也就是divider)

关于 getItemOffsets 函数:
RecyclerView 添加分割线,实际上就是 RecyclerView 的 item 之间添加了用作分割线的View,自然而然后续的 item 就会有偏移量,所以用 getItemOffsets 中的 outRect 来保存 item 的偏移量,从而便于绘制 decorator。

实现

实际上在当前版本的 ​​RecyclerView (25.3.1)​​​ 中已经有 ​​ItemDecoration​​​ 关于分割线的默认实现类 ​​DividerItemDecoration​

package android.support.v7.widget;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.NonNull;
import android.support.v4.view.ViewCompat;
import android.view.View;
import android.widget.LinearLayout;

public class DividerItemDecoration extends RecyclerView.ItemDecoration {
public static final int HORIZONTAL = LinearLayout.HORIZONTAL;
public static final int VERTICAL = LinearLayout.VERTICAL;

// 如果不设置,则默认的分割线为 android.R.attr.listDivider 指定的 drawable
private static final int[] ATTRS = new int[]{ android.R.attr.listDivider };

private Drawable mDivider;

/**
* Current orientation. Either {@link #HORIZONTAL} or {@link #VERTICAL}.
*/
private int mOrientation;

private final Rect mBounds = new Rect();

/**
* Creates a divider {@link RecyclerView.ItemDecoration} that can be used with a
* {@link LinearLayoutManager}.
*
* @param context Current context, it will be used to access resources.
* @param orientation Divider orientation. Should be {@link #HORIZONTAL} or {@link #VERTICAL}.
*/
public DividerItemDecoration(Context context, int orientation) {
final TypedArray a = context.obtainStyledAttributes(ATTRS);
mDivider = a.getDrawable(0);
a.recycle();
setOrientation(orientation);
}

/**
* Sets the orientation for this divider. This should be called if
* {@link RecyclerView.LayoutManager} changes orientation.
*
* @param orientation {@link #HORIZONTAL} or {@link #VERTICAL}
*/
public void setOrientation(int orientation) {
if (orientation != HORIZONTAL && orientation != VERTICAL) {
throw new IllegalArgumentException(
"Invalid orientation. It should be either HORIZONTAL or VERTICAL");
}
mOrientation = orientation;
}

/**
* Sets the {@link Drawable} for this divider.
*
* @param drawable Drawable that should be used as a divider.
*/
public void setDrawable(@NonNull Drawable drawable) {
if (drawable == null) {
throw new IllegalArgumentException("Drawable cannot be null.");
}
mDivider = drawable;
}

@Override
public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
if (parent.getLayoutManager() == null) {
return;
}
if (mOrientation == VERTICAL) {
drawVertical(c, parent);
} else {
drawHorizontal(c, parent);
}
}

// 绘制 RecyclerView 为垂直布局时的分割线,此时分割线为水平分割线
@SuppressLint("NewApi")
private void drawVertical(Canvas canvas, RecyclerView parent) {
canvas.save();
final int left;
final int right;
// 需要考虑clipToPadding的boolean值
if (parent.getClipToPadding()) {
left = parent.getPaddingLeft();
right = parent.getWidth() - parent.getPaddingRight();
canvas.clipRect(left, parent.getPaddingTop(), right,
parent.getHeight() - parent.getPaddingBottom());
} else {
left = 0;
right = parent.getWidth();
}

final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
parent.getDecoratedBoundsWithMargins(child, mBounds);
final int bottom = mBounds.bottom + Math.round(ViewCompat.getTranslationY(child));
final int top = bottom - mDivider.getIntrinsicHeight();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
canvas.restore();
}

// 绘制 RecyclerView 为水平布局时的分割线,此时分割线为垂直分割线
@SuppressLint("NewApi")
private void drawHorizontal(Canvas canvas, RecyclerView parent) {
canvas.save();
final int top;
final int bottom;
// 需要考虑clipToPadding的boolean值
if (parent.getClipToPadding()) {
top = parent.getPaddingTop();
bottom = parent.getHeight() - parent.getPaddingBottom();
canvas.clipRect(parent.getPaddingLeft(), top,
parent.getWidth() - parent.getPaddingRight(), bottom);
} else {
top = 0;
bottom = parent.getHeight();
}

final int childCount = parent.getChildCount();
for (int i = 0; i < childCount; i++) {
final View child = parent.getChildAt(i);
parent.getLayoutManager().getDecoratedBoundsWithMargins(child, mBounds);
final int right = mBounds.right + Math.round(ViewCompat.getTranslationX(child));
final int left = right - mDivider.getIntrinsicWidth();
mDivider.setBounds(left, top, right, bottom);
mDivider.draw(canvas);
}
canvas.restore();
}

@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
RecyclerView.State state) {
if (mOrientation == VERTICAL) { // 垂直方向的RecyclerView, item 的 bottom 偏移量 = 分割线高度
outRect.set(0, 0, 0, mDivider.getIntrinsicHeight());
} else { // 水平方向的RecyclerView, item 的 right 偏移量 = 分割线宽度
outRect.set(0, 0, mDivider.getIntrinsicWidth(), 0);
}
}
}

在代码中添加:

recyclerView.addItemDecoration(new DividerItemDecoration(recyclerView.getContext(), mLayoutManager.getOrientation()));

 就有了分割线。 默认的分割线效果是系统自带的 ​​listDivider​​​ 的效果,我们也可以在主题配置文件中自定义全局的分割线,或者调用 ​​setDivider​​​ 为每个 ​​RecyclerView​​ 设置单独的分割线。

小结

总的来说,目前添加分割线只需要使用 ​​recyclerview-v7​​​ 包下的 ​​DividerItemDecoration​​​ 类即可,分割线可以通过 setDivider 来个性化指定,也可以通过配置主题中的 ​​android:listDivider​​ 来全局指定。

例如:

RecyclerView mRecyclerView;
mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));

 

RecyclerView添加分割线_java

 这个能满足一般需求,但是如果我想使用自定义的分割线呢,看以下代码

DividerItemDecoration divider = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
divider.setDrawable(ContextCompat.getDrawable(this, R.drawable.divider));
mRecyclerView.addItemDecoration(divider);

RecyclerView添加分割线_android_02



 

package com.example.administrator.myapplication;

import android.content.ContextWrapper;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.DividerItemDecoration;
import android.support.v7.widget.RecyclerView;


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

public class BodyActivity extends AppCompatActivity {
RecyclerView mRecyclerView;

@Override
protected void onCreate(Bundle saveInstanceState) {
super.onCreate(saveInstanceState);
setContentView(R.layout.activity_body);
//1.获取控件
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);

//设置布局方式
mRecyclerView.setLayoutManager(new LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false));//线性布局
// mRecyclerView.setLayoutManager(new GridLayoutManager(this,2));//网格布局
mRecyclerView.setHasFixedSize(true); //是否重新计算大小

//3.准备数据
List<News> newsList = new ArrayList<>();
News news;
for (int i = 1; i <= 20; i++) {
news = new News();
news.setNewsTitle("java是世界上最好的语言" + i);
news.setNewsSource("新华网" + i);
news.setPublishTime("2018-8-6");
newsList.add(news);
}


//添加Android自带的分割线
// mRecyclerView.addItemDecoration(new DividerItemDecoration(this, DividerItemDecoration.VERTICAL));


//添加自定义的分割线
DividerItemDecoration divider = new DividerItemDecoration(this, DividerItemDecoration.VERTICAL);
divider.setDrawable(ContextCompat.getDrawable(this, R.drawable.divider));
mRecyclerView.addItemDecoration(divider);

//4.准备适配器
NewsAdapter newsAdapter = new NewsAdapter(newsList);
mRecyclerView.setAdapter(newsAdapter);


}
}

 

 

标签:parent,int,分割线,添加,import,android,RecyclerView
From: https://blog.51cto.com/u_4387387/6078238

相关文章

  • TC胖客户端添加扩展
    缘由:我刚开始是在找这个窗口的类,这样就可以扩展该窗口。  第一次:我通过NewDatasetsforMultipleFiles找到该窗口的扩展。尝试:我尝试用一个类来集成MultipleFiles......
  • rtk 快速实践 创建一个Post part2 文章列表和添加新文章
    这一节大概能对应文档的数据流结构项目启动大家好,经过rtk快速上手和前个视频的开发环境搭建,下面我们开始真正动手实践吖。从文档的探索初始项目开始,但是稍微有区别,以......
  • macOS永久添加环境变量
    1vim~/.bash_profile修改文件,假如要添加的环境变量为/usr/local/pgsql/bin,则在末尾添加一行:1exportPATH=/usr/local/pgsql/bin:$PATH依次按下esc、:、w、q四个......
  • centos添加磁盘挂载
     不使用逻辑卷格式化磁盘(一路回车)fdisk/dev/vdb格式化文件格式mkfs.xfs/dev/vdb1创建挂载目录mkdir/data/加入自启动echo"/dev/vdb1/data/......
  • scrollView 嵌套 recyclerview 时 BaseQuickAdapter 九宫格图片拖拽到底部删除
    九宫格图片布局,长按直接拖拽图片,长按时显示底部删除布局,拖拽到删除布局处松手可删除布局,最后添加按钮不可拖拽,基于BaseQuickAdapter基础上实现BaseQuickAdapter确实很......
  • 给UITableViewCell添加UITextField
     UITextField*textField=[[UITextFieldalloc]initWithFrame:CGRectMake(90,12,200,25)];textField.clearsOnBeginEditing=NO;//鼠标点上时,不清空......
  • 测试平台系列(3) 给Hello World添加日志
    给HelloWorld添加日志回顾通过上篇内容,我们已经使用Flask完成了我们的第一个接口。我们可以看到,使用Flask来编写接口是十分简单的。那么接下来,我们丰富一下上面的例子......
  • ubuntu22.04添加开机脚本和关机脚本
    一、在目录/etc/init.d/目录下新建自己的脚本sudovi/etc/init.d/myscript1#!/bin/bash2###BEGININITINFO3#Provides:myscript4#Requ......
  • matplotlib 添加网格、绘制两条线、添加图例
    添加网格#显示网格#linestyle网格线#透明度plt.grid(True,linestyle="--",alpha=0.5)添加描述信息#添加描述信息plt.xlabel("时间")plt.ylabel("温度")plt......
  • 在Qt4中添加QSerialPort模块
    在Qt5及以上的版本中提供了QSerialPort串口模块,如果想在Qt4版本中使用该模块,可以自行安装,但仅限于5.5以下的QSerialPort版本。下面就以qtserialport-opensource-src-5.4.2......