android自定义下拉控件的方法,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图,于是就将这个状态图画出来了。

048e8ac652d5f6d1d78fa2f2d066ebe3.png

总结

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值