前言

系列文章

这篇文章是这个系列的第六篇文章了,下面是前五篇文章:

1、玩安卓从 0 到 1 之总体概览

2、玩安卓从 0 到 1 之项目首页

3、玩安卓从 0 到 1 之首页框架搭建。

4、玩安卓从 0 到 1 之架构思考

5、玩安卓从 0 到 1 之适配器思考

按照惯例,放一下 Github 地址和 apk 下载地址吧!

apk 下载地址:www.pgyer.com/llj2

Github地址:github.com/zhujiang521…

前因后果

RecyclerView 大家平时都会使用,在本项目中 RecyclerView 使用方法基本都是下面这种:

基本都是文章的列表,包括有下拉刷新和上拉加载,下拉刷新和上拉加载用的是下面这个库:

SmartRefreshLayout

下面是这个库的依赖:

api  'com.scwang.smart:refresh-layout-kernel:2.0.1'      //核心必须依赖
api  'com.scwang.smart:refresh-header-classics:2.0.1'    //经典刷新头
api  'com.scwang.smart:refresh-footer-classics:2.0.1'    //经典加载

这个库的使用方法在下面会有提及,不过更建议去官方 Github 上看文档。

说到这里,终于要进入正题了!今天到底要实现一个什么功能呢?

故事发生在上周末,我无聊在刷着自己写的玩安卓,在看最新的一些文章,刷了好久,看了很多条目,突然想回到顶部,就只能一直往下滑了,想了下这也太不人性化了吧!好多软件都有一键置顶的功能,也是很方便的,说干就干,那就来给玩安卓也添加一个一键置顶的功能吧!

先来看看最终的实现效果吧!

开始实现

实现

其实核心实现非常简单,只需要下面的一行代码:

mToTopRecycleView.smoothScrollToPosition(0)

这个大家都会,我就不多解释了。

我展示一键置顶按钮的时机是只有在上滑的时候才会展示,平时不展示,下滑的时候也不展示,,当上滑到顶部的时候也不展示。为什么这样设置呢?因为我个人认为只有用户向上滑了才证明用户又可能想回到顶部。

那么下面就来看下怎样设置展示时机吧!

mToTopRecycleView.addOnScrollListener(object : RecyclerView.OnScrollListener() {override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {if (!recyclerView.canScrollVertically(-1)) {// 上滑到顶部} else if (dy < 0) {// 上滑} else if (dy > 0) {// 下滑}}
})

其实到这里基本已经实现功能了,只需要在布局中添加一个按钮,然后给按钮添加下点击事件就行了。但是。。。。。。

凡事就怕但是,如果只是这一个页面需要一键置顶的话那就简单了,在这个页面布局中加一个按钮就好,但是文章列表有很多个页面啊,不止一个!而且都有下拉刷新和上拉加载的功能,本着程序员的懒劲,还是少写点吧,抽一个控件出来吧,别的地方如果需要使用的话直接用这个控件就行!那么就开始吧!

先来想一下这个控件的父类该是谁,肯定是一个 ViewGroup,其实布局并不难,那就使用 FrameLayout 吧!

class ToTopRecyclerView @JvmOverloads constructor(private val mContext: Context,attrs: AttributeSet? = null,defStyleAttr: Int = 0
) : FrameLayout(mContext, attrs, defStyleAttr)

定义好类就完成了一大半了,为啥呢?万事开头难嘛!头都开了,还怕啥!

接下来在 init 方法中将写好的布局加载进来:

init{View.inflate(mContext, R.layout.layout_to_top, this)
}

来看下布局文件吧:

<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><com.scwang.smart.refresh.layout.SmartRefreshLayoutandroid:id="@+id/toTopSmartRefreshLayout"android:layout_width="match_parent"android:layout_height="match_parent"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/toTopRecycleView"android:layout_width="match_parent"android:layout_height="match_parent" /></com.scwang.smart.refresh.layout.SmartRefreshLayout><ImageViewandroid:id="@+id/toTopIvClick"android:layout_width="@dimen/dp_40"android:layout_height="@dimen/dp_40"android:layout_gravity="right|bottom"android:layout_margin="@dimen/dp_20"android:background="@drawable/to_top_bg"android:padding="@dimen/dp_8"android:src="@drawable/ic_baseline_vertical_align_top_24"android:visibility="gone" /></merge>

为啥最外面是 merge 就不说了,这要是不会赶快再去看看基础吧。

下面就是 findViewById 了,这个太简单就不贴代码了,浪费时间。

接下来需要想一下咱们想让这个控件完成什么功能,思来想去一共有以下几个功能:

  • 设置 RecyclerView 的 adapter
  • 设置上拉加载和下拉刷新的事件
  • 设置 RecyclerView 的 LayoutManager

可能有人会说,一键置顶不需要吗?如果需要的话那咱们写这个控件的意义何在啊!

下面就根据上面的列表顺序来一个一个写吧!

首先是设置 RecyclerView 的 adapter:

fun setAdapter(adapter: RecyclerView.Adapter<BaseListAdapter.ViewHolder>) {mToTopRecycleView.adapter = adapter
}

代码很简单,只是提供给外部一个设置 adapter 的入口。

然后是设置上拉加载和下拉刷新的事件:

fun onRefreshListener(onRefreshListener: () -> Unit, onLoadMoreListener: () -> Unit) {mToTopSmartRefreshLayout.apply {setOnRefreshListener { reLayout ->reLayout.finishRefresh(measureTimeMillis {onRefreshListener.invoke()}.toInt())}setOnLoadMoreListener { reLayout ->val time = measureTimeMillis {onLoadMoreListener.invoke()}.toInt()reLayout.finishLoadMore(if (time > mLoadTime) time else mLoadTime)}}
}

这个方法有必要说下了,这就是文章开头所说那个库的使用方法。

这块使用了一个高阶函数,方法参数是两个函数,通过名称就可以知道第一个是刷新的函数,第二个是加载更多的函数。

最后是设置 RecyclerView 的 LayoutManager,为了省事我决定将这个函数写的方便一些,别的地方调用的时候只需要传入布尔值或者 int ,然后通过判断设置不同的 LayoutManager。

思来想去,本项目中的 RecyclerView 只用到了两种 LayoutManager,分别是 LinearLayoutManager(竖屏) 和 StaggeredGridLayoutManager(横屏),那么就用布尔值作为参数来判断使用哪种 LayoutManager 吧,下面是方法的代码:

fun setRecyclerViewLayoutManager(isLinearLayout: Boolean) {if (isLinearLayout) {mToTopRecycleView.layoutManager = LinearLayoutManager(context)} else {val spanCount = 2val layoutManager =StaggeredGridLayoutManager(spanCount, StaggeredGridLayoutManager.VERTICAL)mToTopRecycleView.layoutManager = layoutManagerlayoutManager.gapStrategy = StaggeredGridLayoutManager.GAP_HANDLING_NONE}
}

OK,这就差不多了。

使用

实现完成了就该使用了,实践是检验真理的唯一标准!

先给首页尝试下,添加到布局中:

<com.zj.core.view.custom.ToTopRecyclerViewandroid:id="@+id/homeToTopRecyclerView"android:layout_width="match_parent"android:layout_height="match_parent"/>

注意!上面写的下面就要进行调用了!

homeToTopRecyclerView.setAdapter(articleAdapter)
homeToTopRecyclerView.onRefreshListener({page = 1getArticleList(true)
}, {page++getArticleList(true)
})
homeToTopRecyclerView.setRecyclerViewLayoutManager(true)

还是那句话,如果只是一个地方调用,怎么写都是对的,但如果很多地方调用的话抽出来就很有必要了!

大家可以下载项目看下历史提交,省了很多代码。

本篇 View 的代码

精致的结尾

到这里本篇文章就要和大家说再见了,这篇文章虽然实现的功能很简单,但也能提升一些用户体验!欢迎大家下载体验。

能力一般、水平有限,对大家有帮助的话别忘了三连,有 Github 账号的帮忙点个 Star ,感激不尽!

就这样,下回再见!!!

玩安卓从 0 到 1 之列表一键置顶相关推荐

  1. 玩安卓从 0 到 1 之项目总结

    玩安卓从 0 到 1 之项目总结 前言 这篇文章是这个系列的第七篇文章了,也是我准备写的这个系列的最后一篇文章.下面是前六篇文章: 1.玩安卓从 0 到 1 之总体概览 2.玩安卓从 0 到 1 之项 ...

  2. 玩安卓从 0 到 1 之总体概览

    玩安卓从 0 到 1 之总体概览 前言 其实写MVVM?瞎搞一波?和MVVM?继续搞一波这两篇文章的时候没觉得水,但是后来自己看了一遍,感觉除了截了几张图之外并没说什么关于技术的东西,这就很扯淡了,技 ...

  3. 玩安卓从 0 到 1 之架构思考

    前言 这篇文章是这个系列的第四篇文章了,下面是前三篇文章: 1.玩安卓从 0 到 1 之总体概览 2.玩安卓从 0 到 1 之项目首页 3.玩安卓从 0 到 1 之首页框架搭建. 按照惯例,放一下 G ...

  4. 玩安卓从 0 到 1 之首页框架搭建

    前言 这篇文章是这个系列的第三篇文章了,前两篇文章分别是玩安卓从 0 到 1 之总体概览和玩安卓从 0 到 1 之项目首页. 一开始想的是一篇文章搞定,从项目的搭建到完成把所有的知识点写一遍,努力不做 ...

  5. autojs模仿qq消息列表侧拉置顶删除菜单

    牙叔教程 简单易懂 效果展示 思路 使用安卓qq可知, 消息列表每次只能有一个侧拉菜单被打开 autojs版本 9.0.4 你将学到以下知识点 RecyclerView的基本使用 拦截rv的触摸事件 ...

  6. android列表实现置顶,Android利用RecyclerView实现全选、置顶和拖拽功能示例

    Android利用RecyclerView实现全选.置顶和拖拽功能示例 发布时间:2020-08-23 16:26:42 来源:脚本之家 阅读:159 作者:爱开发 前言 今天给大家分享是如何在Rec ...

  7. android环信删除会话列表,关于会话列表的置顶聊天

    最近搞完了置顶聊天,来写篇文章分享下经验. 其实刚刚开始 ,我自己在想,我是不是要去做出类似于QQ那种的滑动,然后显示置顶和删除. 图1 我就开始写,写完了之后然后去置顶,取消置顶,其实是有用的,但是 ...

  8. mix2线刷开发板救砖_小米Mix 2(安卓8.0)一键救砖教程,轻松刷回官方系统

    小米Mix 2(安卓8.0)手机变砖了怎么办?对于经常刷机的安卓玩家来说,碰到刷机失败导致小米Mix 2(安卓8.0)手机无法启动甚至无法进入recovery都是在所难免的事,这个时候我们就需要用到奇 ...

  9. android版本怎么升级到7,安卓7.0更新

    [CNMO新闻]近日,微信再次迎来更新,不出意外的话,这将会是年前的最后一次更新.本次更新版本为7.0.3,用户可以在微信端进行更是体验,主要是修复了一些已知的bug,并且小程序有了全新的显示界面,或 ...

最新文章

  1. MySQL删除关联表的数据
  2. ambari hdfs 启动报错_HDFS 运维常见问题处理
  3. html 访问节点,HTML DOM 访问节点
  4. hdu3790最短路径问题(迪杰斯特拉算法+详解+代码)
  5. 北京房租到底有多高? | 爬取北京海淀区一居室租房信息
  6. 【机器学习】适用于机器学习初学者的8个小项目
  7. firefly-rk3288开发板Linux驱动——LED驱动
  8. navicat连接postgresql时报错:authentication method 10 not supported
  9. 苹果笔记本显卡性能测试软件,测试结果来了!新款Macbook Pro显卡性能怎样?
  10. 路由器和三层交换机的搞笑文章
  11. 徐家骏:华为十年感悟(转载)
  12. 百度度地图总是提示key 验证出错 请在 AndroidManifest xml 文件中检查 key 设置解决办法
  13. Python学习笔记——绘图设置(二)填色图与等值线图
  14. 如何有效开展小组教学_如何有效的开展小组合作,用小组合作活动推进教学——徐倩虹...
  15. Stateflow使用C语言结构体,关于使用Stateflow调用外部C代码的教程介绍
  16. 3天怒肝5万字!阿里P7大佬手写MySQL超全笔记,还担心学不会吗?
  17. 怎样获取苹果APP里的资源图片
  18. 电脑文件之批量重命名
  19. 央行叫停支付宝虚拟信用卡及二维码支付
  20. 加速 Web 开发的 23 款前端开发工具

热门文章

  1. 家用监控系统需要服务器吗,家庭监控系统实现(一)
  2. 〖Python语法进阶篇②〗- 线程与多线程概述
  3. springboot+FreeMarker制作word模板
  4. 微型计算机系统与接口重要吗,微型计算机系统与接口 马宏锋 等编著 第六章
  5. idea 自动同步文件本地内容设置
  6. 微信小程序真机调试:createEvent is not a function
  7. win+D无法回到桌面
  8. JAVA学习笔记(6)——接口与多态
  9. 华为防火墙通用配置详解
  10. Java网课笔记整理