Android自定义控件ListView下拉刷新的代码
作者:pigdreams 发布时间:2023-04-07 23:51:06
标签:android,listview,下拉,刷新
ListView在实际实用中,一般都会有下新刷新和上拉加载的动态效果,今天要学的就是如何自定义带下拉刷新的ListView。
原理解析:一般将有下拉刷新的listview分成四种不同的状态来进行不同的显示效果。
1.完成状态done:listview正常显示状态
2.下拉状态pull:listview正在下拉时的状态
3.释放状态release:listview下拉后松开的状态
4.更新状态refreshing:listview下拉后加载数据时的状态
实现步骤:
自定义CustomListView继承自ListView,添加headerView,里面的布局是有下拉刷新的文字与图片
为listview创建适配器,随便弄一些数据做一些数据源放入到listview的适配器中,好测试显示。
自定义的带有头部的ListView首先要将头部视图隐藏掉,添加头视图的代码是listview.addHeaderView()。
注意:这里并不能用headerView对象的setVisibility()来实现隐藏的效果,当你调用这个添加头部视图的方法时,头部位置不管有没有视图都会占据一个位置。所以得用setPadding()的TOP为负数来实现这个功能。
具体代码实现
package com.hapzhu.customlv;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
public class CustomListview extends ListView {
View headerView;
int height;
private TextView tvActionTip;
private ImageView ivArrow;
private ProgressBar pbRefreshing;
final static int STATE_DONE = 1;
final static int STATE_PULL = 2;
final static int STATE_RELEASE = 3;
final static int STATE_REFRESHING = 4;
int currentState;
int downY;
public CustomListview(Context context, AttributeSet attrs) {
super(context, attrs);
headerView = View.inflate(context, R.layout.listview_header, null);
this.addHeaderView(headerView);
// 用setPadding方法设置Top的大小来把headerview隐藏掉
// 不能用GetHeight方法来实现,因为这个方法只能用来测试可见的控件
// 要用measureHeight的方法来实现测试,这个方法要先测试0,0的位置
headerView.measure(0, 0);
height = headerView.getMeasuredHeight();
headerView.setPadding(0, -height, 0, 0);
initView();
// 设置第一个状态
currentState = STATE_DONE;
}
private void initView() {
tvActionTip = (TextView) headerView.findViewById(R.id.tv_state);
ivArrow = (ImageView) headerView.findViewById(R.id.iv_arrow);
pbRefreshing = (ProgressBar) headerView.findViewById(R.id.progressBar);
}
boolean isRefresh = false;
@Override
public boolean onTouchEvent(MotionEvent ev) {
try {
// 事件类型
int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:// 往下滑的手势
if (currentState == STATE_DONE) {// 只有在完成状态时才会有业务动作
// 触发下拉手势的Y坐标
downY = (int) ev.getY();
// 切换状态
currentState = STATE_PULL;
}
break;
case MotionEvent.ACTION_MOVE:// 正在拖动的手势
if (currentState == STATE_PULL) {// 只有在下拉状态时才会有动作
int currentY = (int) ev.getY();// 得到正在不断改变的当前Y坐标
int top = currentY - downY - height;// 这个值是下拉时头部视图的高度显示,要慢慢变化
headerView.setPadding(0, top, 0, 0);
if (currentY - downY > height) {// 如果下拉的高度超过了头视图的高度,则改变状态
currentState = STATE_RELEASE;
tvActionTip.setText("松开刷新");
}
}
break;
case MotionEvent.ACTION_UP:
if (currentState == STATE_RELEASE) {// 只有在释放状态时才进行刷新动作
tvActionTip.setText("刷新中");// 改变文字 提示
currentState = STATE_REFRESHING;// 改变状态,变为刷新状态
ivArrow.setVisibility(GONE);// 箭头隐藏
pbRefreshing.setVisibility(VISIBLE);// 进度条显示
isRefresh = true;
if(onRefreshListener!=null){
//如果回调接口不为空,则进行更新的事务
onRefreshListener.OnRefresh(this);
}
} else {
if (!isRefresh) {
// 如果当前的下拉距离小于高度时,再把头部视图隐藏
headerView.setPadding(0, -height, 0, 0);
// 一定要记得把状态改回去,不然会没法再次向下拉
currentState = STATE_DONE;
}
}
break;
}
} catch (Exception e) {
}
return super.onTouchEvent(ev);
}
// 1定义接口
interface OnRefreshListener {
// 在主程序中使用框架中的Custom来改变数据更新完之后的界面
public void OnRefresh(CustomListview customLv);
}
// 2.申明接口
OnRefreshListener onRefreshListener;
// 3.传递接口
public void setOnRefreshListener(OnRefreshListener onRefreshListener) {
this.onRefreshListener = onRefreshListener;
}
public void refreshComplete(){
isRefresh=false;
//更新数据结果后,再回调这个方法
headerView.setPadding(0, -height, 0, 0);
// 一定要记得把状态改回去,不然会没法再次向下拉
currentState = STATE_DONE;
//将进度条设为不可见,将箭头设为可见,将文字改回去
ivArrow.setVisibility(VISIBLE);// 箭头显示
pbRefreshing.setVisibility(GONE);// 进度条隐去
tvActionTip.setText("下拉刷新");// 改变文字 提示
}
}
今天新学了UML图,于是就将这个状态图画出来了。
来源:https://blog.csdn.net/pigdreams/article/details/52447322


猜你喜欢
- 实例如下:public class DataTypeChangeHelper { /** * 将一个单字节的b
- 本文汇总了高效C#编码常见的优化原则,对于进行C#程序设计来说有很大的参考借鉴作用。具体列出如下:1.foreach VS for 语句Fo
- 对于有Java开发经验的朋友都知道,Java中不需要手动的申请和释放内存,JVM会自动进行垃圾回收;而使用的内存是由JVM控制的。那么,什么
- MyBatis简介MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。 MyBatis 消除了几乎所有的 JDBC
- 当我们在做前后端分离的开发时,在使用fetch交换数据的时候,提示Access-Control-Allow-Origin跨域问题,解决方案跟
- 值传递当调用方法进行值传递时,方法内部会产生一个局部变量,在方法内部使用局部变量的值,并不影响传入原来数据的值,包括在使用基本数据类型的包装
- SpringMVC用Post方式重定向正常会以return "redirect:/XXX"这种方式直接重定向,但是这种方
- 本文实例为大家分享了UGUI绘制平滑曲线的具体代码,供大家参考,具体内容如下绘制实现自定义的MaskableGraphic挂载在UGUI的U
- 需要装一个插件:File - Settings- Plugins - 搜索gson 安装GsonFromat;如下两张图安装完成后 ,新建一
- 在学习使用Scroller之前,需要明白scrollTo()、scrollBy()方法。一、View的scrollTo()、scrollBy
- java操作json对象出现StackOverflow错误今天在做项目的时候,遇到一个非常怪异的问题。一个java实体类中存在多个属性,每一
- 本文实例为大家分享了Android实现歌词滚动效果的具体代码,供大家参考,具体内容如下自定义TextViewpublic class Ver
- 本文实例为大家分享了Unity3d简易五子棋源码,供大家参考,具体内容如下Unity3d部分对C#源码进行了改写简化:using Unity
- 问题之前研究了Java通过执行cmd命令从而触发Android打包的思路,但是发现Android打包成功之后,后面的代码逻辑就不走了(连输出
- 占位符Placeholder的使用xml中的配置:<?xml version="1.0" encoding=&qu
- 废话不多说了,直接给大家贴代码了,具体代码如下所示:package wxapi.WxHelper; import java.io.Buffe
- 在Android开发过程中,我们有时候需要获取当前的Activity实例,比如弹出Dialog操作,必须要用到这个。关于如何实现由很多种思路
- view plaincopy to clipboardprint?//手动保存图片 &nbs
- 引言使用微信时我们会发现,首次进入微信的好友列表时,会加载好友头像,但是再次进入时,就不用重新加载了,而且其他页面都不用重新加载,说明微信的
- 本文实例讲述了C#获取项目指定目录下文件的方法。分享给大家供大家参考。具体如下:public List<FileInfo> Ge