Android自定义控件ListView下拉刷新的代码

作者:pigdreams 时间:2023-04-07 23:51:06 

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图,于是就将这个状态图画出来了。

Android自定义控件ListView下拉刷新的代码

来源:https://blog.csdn.net/pigdreams/article/details/52447322

标签:android,listview,下拉,刷新
0
投稿

猜你喜欢

  • android 更改TextView中任意位置字体大小和颜色的方法

    2021-10-21 01:51:43
  • C#的Excel导入、导出

    2023-09-10 01:00:24
  • 利用Spring Boot操作MongoDB的方法教程

    2023-11-29 11:14:27
  • Android设计模式系列之工厂方法模式

    2023-08-16 19:10:17
  • Java中volatile关键字实现原理

    2023-09-30 14:20:58
  • Java获取当前操作系统的信息实例代码

    2023-03-07 20:00:08
  • 基于javaWeb 项目SSM配置要点及可能遇到的问题和解决方法

    2023-10-27 21:45:16
  • Spring Boot Gradle发布war到tomcat的方法示例

    2021-09-24 11:36:57
  • 详解SpringBoot的事务管理

    2022-01-15 13:39:26
  • Hibernate的一对一,一对多/多对一关联保存的实现

    2022-03-13 12:41:08
  • Android APK应用安装原理解析之AndroidManifest使用PackageParser.parserPackage原理分析

    2023-05-19 23:58:18
  • Java中的静态绑定和动态绑定详细介绍

    2023-01-18 19:54:06
  • C#操作JSON(序列化与反序列化)的方法详解

    2022-01-27 20:15:10
  • android实现软件自动更新的步骤

    2022-12-27 00:48:17
  • WPF实现窗体亚克力效果的示例代码

    2022-07-25 10:38:08
  • 三行Android代码实现白天夜间模式流畅切换

    2021-06-11 08:15:12
  • 详解Android性能优化之启动优化

    2023-07-16 06:00:07
  • c#使用file.copy实现文件备份示例

    2021-06-03 05:13:13
  • C语言中各种操作符的详细介绍(纯干货!)

    2022-07-22 08:34:40
  • java8 如何实现分组计算数量和计算总数

    2022-05-05 01:17:32
  • asp之家 软件编程 m.aspxhome.com