玩安卓从 0 到 1 之列表一键置顶

news/2024/9/18 7:27:45/

前言

系列文章

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

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 ,感激不尽!

就这样,下回再见!!!


http://www.ppmy.cn/news/646449.html

相关文章

梦幻西游手游版找不到服务器,梦幻西游手游无法选择服务器怎么办 解决方法...

梦幻西游手游最近公测&#xff0c;很多玩家都加入了游戏&#xff0c;那么当出现无法选择服务器的情况该怎么办呢&#xff1f;下面就请看小编为大家带来的攻略吧&#xff01; 梦幻西游手游无法选择服务器怎么版 解决方法 首先选择网络&#xff0c;不要用默认&#xff0c;如果不行…

jzoj1082劲乐团

劲乐团是这样一个游戏&#xff1a; 当游戏开始时&#xff0c;一边播放背景音乐&#xff0c;一边从上至下不断随着音乐掉落Note。&#xff08;Note是音乐游戏的术语&#xff09;当该Note掉落至最底部时&#xff0c;则按下对应的键就可以击中该Note并得分。 击中的时间越准确得分…

拒绝再玩

无意中看了哥哥的国语现场版《拒绝再玩》,我被哥哥开场的表演逗笑了,哈哈,你不妨看一下,若你没找到资源,问我要吧,我这百度云收集了很多。其中有句歌词是,拒绝再玩,不重复同样的错误。 说起来容易,其实我们很多时候都是在重复同样的错误,而且还会一错再错。我之前也…

CC2530 串口配置步骤

一、并行通信与串行通信 微控制器与外设之间的数据通信,根据连线结构和传送方式的不同,可以分为两种:并行通信和串行通信。 并行通信:指数据的各位同时发送或接收,每个数据位使用单独的一条导线。传输速度快、效率高,但需要的数据线较多,成本高。 串行通信:指数据一…

本地生活服务平台加盟

本地生活服务商平台市场前景非常广阔。随着人们对便利和高效的需求增加&#xff0c;本地生活服务行业迅速发展。这种平台连接了消费者与各种本地服务提供者&#xff0c;如餐厅、快递、修理、清洁等&#xff0c;为用户提供了更方便、更快捷的方式来获取所需的服务。 市场前景…

mysql时差计算

select DATEDIFF(2022-03-30,2022-03-1) as 相差天数 select TIMEDIFF(2022-03-30 18:00:00,2022-03-30 16:03:11) as 相差时分秒 参数1 减 参数2 差值

天黑时间跟经度还是纬度有关_时差的具体由来,时差由纬度还是经度决定?

时差是由经度决定的。经度不同,地方时不同&#xff1b;同一经度的地方时相同&#xff1b;东边经度比西边经度的地方时早。经度每相差1时间就相差4分钟,每相差15度时间就相差1小时。 时差的具体由来 我们对时间的度量是人为制定的标准&#xff0c;首先我们根据地球的自转周期将一…

时差怎么理解_英国与中国的时差为什么隔8小时(英国与中国的时差解读)

每一国家的时差都是不一样的&#xff0c;每一个国家城市里面的时间也是有一定的差距的&#xff0c;所以我们看见有的地方亮的比较早&#xff0c;有的地方黑的比较晚也是比较正常的。一年四季时间也是在不断的进行变化的&#xff0c;毕竟地球在不断的转动。同样的东西半球的时间…

格林威治时间和北京时间的时差

图片说明更清晰&#xff1a; 如果有兴趣仔细了解格林威治时间&#xff0c;可以看百度百科对该名词的介绍&#xff1a;格林威治时间&#xff0c;另外格林威治时间和格林尼治时间都指代世界时&#xff0c;只是音译不同 拓展&#xff1a; 如果你使用f12键打开控制台&#xff0c;…

时差怎么理解_时差是怎么形成的?

展开全部 各国的时间使用地方时&#xff0c;没有统一换算方法&#xff0c;给交通和通讯带来不便。(时差的意识在此前就有&#xff0c;只是没32313133353236313431303231363533e59b9ee7ad9431333431353266有形成完善制度)为了统一&#xff0c;世界采取了时差制度并且遵循此制度&…

时区缩写与UTC(GMT)时差对照表

做海外产品时&#xff0c;经常碰到的问题就是不同时区的问题&#xff0c;下面是各种时区缩写和0时区世间的对照表&#xff0c;供大家参考&#xff1a; Abbreviation Offset A UTC 1 ACDT UTC 10:30 ACST UTC 9:30 ACT UTC -5 ACT UTC 9:30 / 10:30 ACWST UTC 8:45…

Java计算两个时间的小时差

/**** 计算两段时间的小时差* module* author SJT* date 2022/12/28* param startTime* param endTime* return: java.lang.Integer*/public static Integer calculateHourDiff(String startTime,String endTime) {try {SimpleDateFormat simpleFormat new SimpleDateFormat(&…

C语言求两个时间的时差

#include<stdio.h>int main() { int hour1,minute1;int hour2,minute2;scanf("%d %d",&hour1,&minute1);scanf("%d %d",&hour2,&minute2);int hchour2-hour1;int mcminute2-minute1;if(mc<0){mc60mc;hc--;}printf("时间差是…

pmp 总时差 自由时差 说明 和计算

总浮动时间LS-ES 或 LF-EF 总浮动时间是针对同一个活动来说的 自由浮动时间是针对两个紧邻活动来说的 自由活动时间紧后活动的最早开始时间-紧前活动的最早结束时间 总时差同一个活动的最晚开始-最早开始 或者 最晚结束-最早结束 的正差值 LS:最晚开始&#xff0c;ES&a…

电商系统架构设计系列(四):流量大、数据多的「商品详情页系统」该如何设计?

一个电商的商品系统&#xff0c;主要功能就是增删改查商品信息。 上篇文章中&#xff0c;我给你留了一个思考题&#xff1a;流量大、数据多的商品详情页系统该如何设计&#xff1f; 今天这篇文章&#xff0c;主要聊一下&#xff0c;如何设计一个快速、可靠的存储架构支撑商品系…

时差问题

Problem4&#xff1a;时差问题。一个地方和北京相差17个小时&#xff08;比北京慢17h&#xff09;&#xff0c;输入北京时间&#xff0c;输出当地时间;输入格式&#xff1a;年 月 日 时 分&#xff0c;输出格式一样。此题注意输出格式控制&#xff08;后四项数字位数为两位&…

(九)Linux算时差的方法

学习日志&#xff08;九&#xff09; Linux算时差的方法 时间函数 函数原型及头文件 #include<sys/time.h> int gettimeofday(struct timeval *tv,struct timezone *tz )&#xff1b;结构体原型&#xff1a; struct timeval {long tv_sec;/*秒*/long tv_usec;/*微妙*…

关键路径、工期、总时差和自由时差精讲

关键路径法是在进度模型中&#xff0c;估算项目最短工期&#xff0c;确定逻辑网络路径进度灵活性大小的一种方法。 ①计算原理 a.计算ES、EF&#xff1a;从网络计划起点节点开始&#xff0c;沿箭线方向依次向前推算&#xff0c;数值取大。 b.计算LS、LF&#xff1a;从网络计划终…

关于总时差和自由时差的作用及理由

时差的利用    ①如果延期的工作位于关键线路上&#xff0c;不管延期多长时间&#xff0c;对总工期和后续工作都有影响&#xff1b;    ②如果延期的工作不在关键线路上&#xff0c;对总工期和后续工作是否有影响&#xff0c;取决于延期的时间与总时差和自由时差的关系&…

夏时制英国和中国的时差是多少?伦敦与北京时差是多少?

夏时制英国和中国的时差是多少&#xff1a;7小时 冬时制英国和中国的时差是多少&#xff1a;8小时 比如现在中国北京时间是&#xff1a;16:00 那么现在英国伦敦的时间&#xff1a;9:00 因为现在是夏时制&#xff0c;如果现在不是夏时制&#xff0c;那么现在英国伦敦的时间&…