当前位置: 移动技术网 > 移动技术>移动开发>Android > Android自定义控件ListView下拉刷新的代码

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

2019年07月30日  | 移动技术网移动技术  | 我要评论

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

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对移动技术网的支持。如果你想了解更多相关内容请查看下面相关链接

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网