继承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

相关文章

hdu1043(八数码问题,广搜 + hash(实现状态压缩) )

利用康拓展开将一个排列映射成一个自然数,然后就变成了普通的广搜题。 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#include<stdlib.h>#include<ctype.h>#inclu

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

让树莓派智能语音助手实现定时提醒功能

最初的时候是想直接在rasa 的chatbot上实现,因为rasa本身是带有remindschedule模块的。不过经过一番折腾后,忽然发现,chatbot上实现的定时,语音助手不一定会有响应。因为,我目前语音助手的代码设置了长时间无应答会结束对话,这样一来,chatbot定时提醒的触发就不会被语音助手获悉。那怎么让语音助手也具有定时提醒功能呢? 我最后选择的方法是用threading.Time

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略

Kubernetes PodSecurityPolicy:PSP能实现的5种主要安全策略 1. 特权模式限制2. 宿主机资源隔离3. 用户和组管理4. 权限提升控制5. SELinux配置 💖The Begin💖点点关注,收藏不迷路💖 Kubernetes的PodSecurityPolicy(PSP)是一个关键的安全特性,它在Pod创建之前实施安全策略,确保P

工厂ERP管理系统实现源码(JAVA)

工厂进销存管理系统是一个集采购管理、仓库管理、生产管理和销售管理于一体的综合解决方案。该系统旨在帮助企业优化流程、提高效率、降低成本,并实时掌握各环节的运营状况。 在采购管理方面,系统能够处理采购订单、供应商管理和采购入库等流程,确保采购过程的透明和高效。仓库管理方面,实现库存的精准管理,包括入库、出库、盘点等操作,确保库存数据的准确性和实时性。 生产管理模块则涵盖了生产计划制定、物料需求计划、

Flutter 进阶:绘制加载动画

绘制加载动画:由小圆组成的大圆 1. 定义 LoadingScreen 类2. 实现 _LoadingScreenState 类3. 定义 LoadingPainter 类4. 总结 实现加载动画 我们需要定义两个类:LoadingScreen 和 LoadingPainter。LoadingScreen 负责控制动画的状态,而 LoadingPainter 则负责绘制动画。

C++——stack、queue的实现及deque的介绍

目录 1.stack与queue的实现 1.1stack的实现  1.2 queue的实现 2.重温vector、list、stack、queue的介绍 2.1 STL标准库中stack和queue的底层结构  3.deque的简单介绍 3.1为什么选择deque作为stack和queue的底层默认容器  3.2 STL中对stack与queue的模拟实现 ①stack模拟实现