RecycleView设置顶部分割线(记录一个坑)

大家都知道,想给RecycleView设置分割线可以重写RecyclerView.ItemDecoration

项目过程中,遇到一个需求:RecycleView顶部有一条灰色的间隔,我想到了给RecycleView设置分割线的方法,当然只给第一个Item设置,而且在上方。

public class MyDividerItemDecoration extends RecyclerView.ItemDecoration {

    private Drawable mDivider;

    /**
     * Custom divider will be used
     */
    public MyDividerItemDecoration(Context context, int resId) {
        mDivider = ContextCompat.getDrawable(context, resId);
    }

    @Override
    public void getItemOffsets(Rect outRect, View view, RecyclerView parent,                                RecyclerView.State state) {
        super.getItemOffsets(outRect, view, parent, state);
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        //因为绘制了顶部分割线,因此需要将第一行的item下移相应的距离        //这里要注意,判断该RecycleView是什么布局,如果是竖直方向上的线性布局(水平方向上的这里没有考虑)        //,那么需要让第一个Item下移,移动的距离是分割线的高度,因为分割线会占据Item的空间        //如果是网格布局,那么需要把第一行的所有Item都下移相应的高度
        if (layoutManager instanceof LinearLayoutManager) {
            if (parent.getChildAdapterPosition(view) == 0) {
                outRect.set(0, mDivider.getIntrinsicHeight(), 0, 0);
            }
        }
        if (layoutManager instanceof GridLayoutManager) {
            if (parent.getChildAdapterPosition(view) >= 0 &&                 parent.getChildAdapterPosition(view) < getSpanCount(parent)) {
                outRect.set(0, mDivider.getIntrinsicHeight(), 0, 0);
            }
        }
    }

    @Override
    public void onDrawOver(Canvas c, RecyclerView parent, RecyclerView.State state) {

        //绘制分割线
        int left = 0;
        int right = parent.getWidth();
        View child = parent.getChildAt(0);

        RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) child.getLayoutParams();

        //不可以直接设置top = 0;因为这样的话分隔线就不会跟着移动,因为top = 0,是绝对位置,        //所以应该设置为子view的相对位置
        //这样才可以跟着滑动。        //child的顶部坐标,减去设置的margin_top的值,再减去child为了给分割线腾出空间所下滑的高度,        //这样分割线才会在顶部
        int top = child.getTop() - params.topMargin - mDivider.getIntrinsicHeight();
        int bottom;
        bottom = top + mDivider.getIntrinsicHeight();
        mDivider.setBounds(left, top, right, bottom);
        mDivider.draw(c);
    }

    private int getSpanCount(RecyclerView parent) {
        // 列数
        int spanCount = -1;
        RecyclerView.LayoutManager layoutManager = parent.getLayoutManager();
        if (layoutManager instanceof GridLayoutManager) {
            spanCount = ((GridLayoutManager) layoutManager).getSpanCount();
        } else if (layoutManager instanceof StaggeredGridLayoutManager) {
            spanCount = ((StaggeredGridLayoutManager) layoutManager)
                    .getSpanCount();
        } else if (layoutManager instanceof LinearLayoutManager) {
            spanCount = layoutManager.getItemCount();
        }
        return spanCount;
    }

在onDrawOver方法中可以绘制分割线。

这里有一个需要注意的坑,调试了很久,最终才发现,难受。

在onDrawOver里面,一开始我设置top = 0;因为绘制在顶部嘛。结果出现了一个现象,顶部分割线一直停留在顶部,不会跟着移动。最后改为int top = child.getTop() - params.topMargin - mDivider.getIntrinsicHeight();才成功了。为什么呢?

因为直接写top = 0;这是绝对位置了,要让分割线也跟着滑动,需要用的是相对位置,相对于item的位置,这样才能够跟着item滑动

调用

recyclerView.addItemDecoration(new MyDividerItemDecoration(this, R.drawable.item_decoration));

item_decoration代码如下:

<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <size android:height="10dp" />
    <solid android:color="@color/comic_gray_bg" />
</shape>

原文地址:https://www.cnblogs.com/tangZH/p/9489486.html

时间: 2024-10-25 08:00:01

RecycleView设置顶部分割线(记录一个坑)的相关文章

H5+ app 记录一个坑 希望有缘人可以解决这个问题

最新少主在开发一款公益的web APP  用的是h5 +  然后打包的 少主两部手机 拿来测试 发现有一部手机出了问题 应用没有缓存 一离开应用就注销了 之后才知道 原来是自己设置了一个东西 在开发者模式 应用 [不保留活动 ] 这个不要开~~~ 开了 应用就没有缓存了 然后再进入就重新开发了 然后假如有授权登陆的话 直接授权不了~~~ (OK 已经解决 部分手机设置了 不保留活动 在开发者选项 应用 用户离开后即撤销每个活动 这个不能开~~!!) 原文地址:https://www.cnblog

记录一个坑

在做spring security JWT登录验证的时候写了一个filter public class JwtAuthenticationTokenFilter extends BasicAuthenticationFilter { @Value("${token.header}") private String token_header; @Autowired private UserDetailsServiceImpl userDetailsService; @Autowired

记录我开发工作中遇到HTTP跨域和OPTION请求的一个坑

我通过这篇文章把今天工作中遇到的HTTP跨域和OPTION请求的一个坑记录下来. 场景是我需要在部署在域名a的Web应用里用JavaScript去消费一个部署在域名b的服务器上的服务.域名b上的服务也是我开发的,因此我将域名a加到了该服务的HTTP响应结构的头文件里,这样就允许了域名a上的JavaScript代码用AJAX访问域名b的服务. 域名b上的服务是一个Servlet,允许域名a跨域访问的代码就一行: protected void doGet(HttpServletRequest req

[JavaEE]记录一下反向代理下SSO不能正常使用的一个坑

嗯...真的是很久没更新了,感觉有点瓶颈了,学又学不下去,工作要用的东西又没有难度,跳槽又没经验没学历关键是还不会吹也是尴尬... 无意间翻到这个博客,又是好久不更新突然想到了还有这个东西,就发一个最近做的小工具好了 主要是在做的某系统,客户哪里不愿意提供多端口,但是要部署多个应用和单点登录,于是就理所当然的用上了反向代理,然后就被公司内部的sso客户端给坑了... SSO单点登陆一般思路应该是这样: 重定向到单点登录服务器 -> 服务器登陆成功跳回并带上身份标识 -> 项目二次前往单点登陆服

【Java记录】try-with-resources的一个坑

[Java记录]try-with-resources的一个坑 今天处理 AsynchronousFileChannel 时候的一个问题,代码如下: public static void main(String[] args) throws Exception { String filePath = "/home/xe/git/osc/JavaNote/Lang/data/Test.java"; ExecutorService executorService = Executors.ne

再次记录 Visual Studio 2015 CTP 5 的一个坑

升级到 VS2015 CTP 之后,今天要改项目中的一个东西,然后就不得不把 C# 6.0 改变的语法代码中改了下(之前没改,大约200多个),首先,比如下面示例代码: var fullName = "\{customer.FirstName} \{customer.LastName}"; 项目中有很多这样的类似代码,这些都得改掉,怎么办?手动改???算了,还是批量修改吧,但是怎么批量替换呢,难道直接把"\ {"替换成"{",但是"$&

Android中隐藏顶部状态栏的那些坑

Android中隐藏顶部状态栏的那些坑 先看看常规的隐藏状态栏的方法: 方法一: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); //去除title requestWindowFeature(Window.FEATURE_NO_TITLE); //去掉Activity上面的状态栏 getWindow().setFlags(WindowManager

记学习PHP掉进去的第一个坑

从前几天开始刚开是学习PHP,就经历了一个坑,让人确实挺郁闷的,主要是因为开发环境的问题. 直接切入正题. =================================================================================================== 实验环境:PHPStorm2016 + Xampp 在学习使用表单的post方法接受数据一节时,怎么也接受不到数据,不知道怎么回事.代码如下 <form name="form1"

MySQL JDBC的queryTimeout的一个坑

遇到一个MySQL JDBC的queryTimeout的坑,比较恶心,算是它的BUG,也可以不算,^_^,为啥这么说?看一下下面的解释: 现象: 用同一个Connection执行大批量SQL的时候,导致了OOM现象. 细节现象描述: 1.SQL是从某个存储设备上拿到的,不会直接占用大量的内存,每次只会取最多1千条数据过去,也会判定容量不超过多少M. 2.每一批SQL执行会单独创建Statement对象,执行一批SQL后,会将这个Statement关闭掉. 3.SQL语句中只有insert,没有其