继承SwipeRefreshLayout实现上拉加载更多功能

2024-02-13 19:08

本文主要是介绍继承SwipeRefreshLayout实现上拉加载更多功能,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android 的SwipeRefreshLayout是一个比较好的下拉刷新控件,现在已经有越来越多的企业开始使用这个控件了。但是遗憾的是这个控件并没有上拉加载更多的功能,所以自己抽空,根据网上已有的例子,自己写了一个。

首先必须要做的是创建一个类继承SwipeRefreshLayout,这里我把它命名为:XZHRefreshLayout

/*** TODO:Created by XuZhenhao on 2016/12/6.*/public class XZHRefreshLayout extends SwipeRefreshLayout {private boolean isLoading = false;private ListView mListView;private View mListFooter;private OnLoadListener mLoadListener;public XZHRefreshLayout(Context context) {this(context, null);}public XZHRefreshLayout(Context context, AttributeSet attrs) {super(context, attrs);//这里初始化FooterView,并给里面的一个菊花图片添加一个动画mListFooter = LayoutInflater.from(context).inflate(R.layout.list_footer, null, false);Animation anim = AnimationUtils.loadAnimation(context, R.anim.img_animation);LinearInterpolator lin = new LinearInterpolator();anim.setInterpolator(lin);mListFooter.findViewById(R.id.progress_iv).startAnimation(anim);}//这里set回调函数public void setOnLoadListener(OnLoadListener loadListener) {this.mLoadListener = loadListener;}@Overrideprotected void onLayout(boolean changed, int left, int top, int right, int bottom) {super.onLayout(changed, left, top, right, bottom);//这里判断ViewGroup里面是不是有个子View,并且第一个是不是ListViewint childCount = getChildCount();if (childCount > 0) {View child = getChildAt(0);if (child instanceof ListView) {mListView = (ListView) child;}}}//用于添加和移除FooterViewpublic void setLoad(boolean isLoad) {isLoading = isLoad;if (isLoad) {mListView.addFooterView(mListFooter);} else {mListView.removeFooterView(mListFooter);}}//记录手指触摸屏幕的上一个Y坐标值private float lastY;@Overridepublic boolean onInterceptTouchEvent(MotionEvent ev) {int action = ev.getAction();float currentY = ev.getY();switch (action) {case MotionEvent.ACTION_DOWN:break;case MotionEvent.ACTION_MOVE://如果当前的Y坐标小于上一个Y坐标的值说明是向上滑动,,并且子ListView不为null,并且没有FooterViewif (currentY < lastY && mListView != null && mListView.getFooterViewsCount() == 0) {//如果当前listView的最后一个item的position等于可见范围内最后一个item的position,
//并且屏幕中的item总数小于11,当前没有加载FooterViewif (mListView.getAdapter().getCount() - 1 == mListView.getLastVisiblePosition() 
&& mListView.getChildCount() >= 11 && !isLoading) {setLoad(true);//添加FooterViewmLoadListener.onLoad();//执行回调函数}}break;}lastY = currentY;return super.onInterceptTouchEvent(ev);}//回调public interface OnLoadListener {void onLoad();}
}

最核心的代码已经实现了,网上有很多Demo是在onScroll方法中实现的,但是我发现在滑动到底部时,onScroll方法一直在执行,那么这样的话会导致我们一直的执行回调函数,因为这里的回调函数是用来加载数据的,从而会导致不停地获取数据,不停的添加和移除FooterView,并且导致ListView的点击事件失效,所以我将其移到了onInterceptTouchEvent(MotionEvent ev)里面去执行。



下面上Activity的代码:

public class MessageListActivity extends AppCompatActivity {private Toolbar SMSToolbar;private XZHRefreshLayout refreshLayout;private ListView lvSMSList;private MessageListAdapter adapter;private List smsList;private MRLTDao dao;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_message_list);initData();initView();}/*** TODO: 初始化控件*/private void initView() {SMSToolbar = (Toolbar) findViewById(R.id.sms_list_toolbar);SMSToolbar.setTitle("短信列表");SMSToolbar.setNavigationIcon(ContextCompat.getDrawable(this, R.mipmap.btn_back));SMSToolbar.setNavigationOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {onBackPressed();}});//实现我们自定义的下拉刷新控件refreshLayout = (XZHRefreshLayout) findViewById(R.id.refresh_sms_ly);refreshLayout.setColorSchemeColors(ContextCompat.getColor(this, android.R.color.holo_blue_bright),ContextCompat.getColor(this, android.R.color.holo_green_light),ContextCompat.getColor(this, android.R.color.holo_orange_light),ContextCompat.getColor(this, android.R.color.holo_red_light));//监听下拉刷新事件refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {@Overridepublic void onRefresh() {new Handler().postDelayed(new Runnable() {@Overridepublic void run() {smsList.clear();smsList.addAll(dao.querySMSALL(0));adapter.notifyDataSetChanged();refreshLayout.setRefreshing(false);}}, 1500);}});//我们写的回调函数,在里面做查找数据的方法refreshLayout.setOnLoadListener(new XZHRefreshLayout.OnLoadListener() {@Overridepublic void onLoad() {new Handler().postDelayed(new Runnable() {@Overridepublic void run() {//我这里是用了一个Sqlite,大家可以根据自己的实际应用在这里做数据的查询,相信大家一般都不可能会有问题。if (dao != null && smsList != null) {List<SmsEntity> datas = dao.querySMSALL(smsList.size());if (datas.size() > 0) {//如果查询到有数据,就添加到数据源里面去。smsList.addAll(datas);adapter.notifyDataSetChanged();}else{//如果没有数据,就弹一个吐司MyToast.show(MessageListActivity.this,"没有更多数据!");}}refreshLayout.setLoad(false);}}, 1000);}});lvSMSList = (ListView) findViewById(R.id.sms_list_lv);adapter = new MessageListAdapter(this, smsList);lvSMSList.setAdapter(adapter);lvSMSList.setOnItemClickListener(new AdapterView.OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position, long id) {SmsEntity entity = (SmsEntity) adapter.getItem(position);showSMSDialog(entity);}});}/*** TODO: 初始化数据*/private void initData() {if (smsList == null)smsList = new ArrayList<>();if (dao == null)dao = new MRLTDao(getApplicationContext());smsList = dao.querySMSALL(0);}@Overrideprotected void onDestroy() {super.onDestroy();}//点击item弹一个Dialog,显示当前Item的内容private void showSMSDialog(SmsEntity entity) {if (entity == null) {return;}final AlertDialog.Builder builder = new AlertDialog.Builder(this);builder.setTitle(entity.getSendcode());builder.setMessage("接收时间:"+entity.getCreate_time()+"\n"+entity.getContent());builder.setPositiveButton("知道了", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {dialog.cancel();}});builder.create().show();}
}

总的来说Activity里面完全没有啥技术含量,只是有可能代码写的其丑无比。

下面上XML:

1.Activity的XML文件

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"xmlns:app="http://schemas.android.com/apk/res-auto"android:id="@+id/activity_message_list"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.yihuacomputer.sdmrlt.ui.MessageListActivity"><android.support.v7.widget.Toolbarandroid:id="@+id/sms_list_toolbar"android:layout_width="match_parent"android:layout_height="50dp"android:background="@color/cpb_blue"app:titleTextColor="@color/cpb_white" />
<com.yihuacomputer.sdmrlt.ui.view.XZHRefreshLayoutandroid:id="@+id/refresh_sms_ly"android:layout_width="match_parent"android:layout_height="match_parent"android:layout_below="@+id/sms_list_toolbar"><ListViewandroid:id="@+id/sms_list_lv"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingLeft="12dp"android:paddingRight="12dp"android:scrollbars="none"></ListView>
</com.yihuacomputer.sdmrlt.ui.view.XZHRefreshLayout></RelativeLayout>

2.ListView的Item的XML

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:gravity="center_vertical"android:orientation="horizontal"android:paddingBottom="4dp"android:paddingTop="4dp"android:weightSum="10"><ImageViewandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="1"android:src="@mipmap/will" /><RelativeLayoutandroid:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="9"android:layout_marginLeft="4dp"><TextViewandroid:id="@+id/item_sms_rvd_tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/colorPrimaryDark"android:maxLength="15"android:textSize="16sp" /><TextViewandroid:id="@+id/item_sms_time_tv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/colorPrimaryDark"android:textSize="16sp"android:layout_alignParentTop="true"android:layout_alignParentEnd="true" /><TextViewandroid:id="@+id/item_sms_content_tv"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_below="@+id/item_sms_rvd_tv"android:maxLines="1"android:textColor="@color/menu_fragment_background"android:textSize="14sp" /></RelativeLayout>
</LinearLayout>

3.FooterView的XML文件

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="45dp"android:gravity="center"android:orientation="horizontal"><ImageViewandroid:id="@+id/progress_iv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@mipmap/gpu" /><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="正在加载..."/></LinearLayout>

所有的XML文件里面就用到了两个Image,大家随便去找两个就可以了,我是解压了手机QQ的App后这里面找的。

好了所有的东西基本已经实现,大家还可以在这个基础上扩展一下,比如加一个动画,让FooterView被移除的时候好看一点,不要那么突兀的就消失了,如果大家实现了,希望能留个言让我学习学习!!!公司没有录屏工具,我就不上图了。

这篇关于继承SwipeRefreshLayout实现上拉加载更多功能的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/706377

相关文章

Python实现终端清屏的几种方式详解

《Python实现终端清屏的几种方式详解》在使用Python进行终端交互式编程时,我们经常需要清空当前终端屏幕的内容,本文为大家整理了几种常见的实现方法,有需要的小伙伴可以参考下... 目录方法一:使用 `os` 模块调用系统命令方法二:使用 `subprocess` 模块执行命令方法三:打印多个换行符模拟

SpringBoot+EasyPOI轻松实现Excel和Word导出PDF

《SpringBoot+EasyPOI轻松实现Excel和Word导出PDF》在企业级开发中,将Excel和Word文档导出为PDF是常见需求,本文将结合​​EasyPOI和​​Aspose系列工具实... 目录一、环境准备与依赖配置1.1 方案选型1.2 依赖配置(商业库方案)二、Excel 导出 PDF

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并