Android ListView的下拉刷新
- 好久没有写博客了,今天我就写一个listview的下拉刷新分享给大家,希望对大家学习或者工作上有所帮助,其实呢,大家都知道,在现在的app当中,下拉刷新是比较常用的功能,用到的地方太多了,所以,今天我也就结合自己的思想给家真理一下,那么好,接下来,让我们一起学习,让你分分钟写出自己想要的自定义listview下拉刷新
一:实现思路
1.实现将listview添加头部view,也就是下拉要出现是头部布局
2.将头部的view给隐藏(这点需要特别注意)
3.给listview设置滑动监听(用于判断是否到头部)
4.设置手势事件,手指移动的时候的所做的操作
二:源码实例
1.自定义控件
- package com.zengtao.refreshview;
- import java.text.SimpleDateFormat;
- import java.util.Date;
- import android.annotation.SuppressLint;
- import android.content.Context;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.MotionEvent;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.animation.RotateAnimation;
- import android.widget.AbsListView;
- import android.widget.AbsListView.OnScrollListener;
- import android.widget.ImageView;
- import android.widget.ListView;
- import android.widget.ProgressBar;
- import android.widget.TextView;
- import com.zengtao.pulltorefreshtest.R;
- /**
- * 下拉刷新listview
- *
- * @author zengtao 2015年3月17日 下午7:13:55
- */
- public class RefreshableView extends ListView implements OnScrollListener {
- /** 下拉刷新的头部 */
- private View headerView;
- /** 头部的箭头 */
- private ImageView arrawImage;
- /** 更新刷新之后的时间 */
- private TextView lastUpdatTime;
- /** 刷新的一个状态 */
- private TextView stateMessage;
- /** 加载进度 */
- private ProgressBar progressBar;
- /** 获取头部文件的高度 */
- private int headerHeight;
- /** 当前第一个可见的位置 */
- private int firstVisibleItem;
- /** 标记当前是否能刷新 */
- private boolean isReflash;
- /** 按下的y值 */
- private int startY;
- /** 下拉的状态 */
- private int state;
- /** 正常状态 */
- private final int NONE = 0;
- /** 提示下拉刷新状态 */
- private final int PULL = 1;
- /** 提示释放刷新状态 */
- private final int REFPULL = 2;
- /** 提示正在刷新 */
- private final int LOADING = 3;
- /** ListView 当前滚动位置 */
- private int scorellStatep;
- /** 数据回调接口 */
- private IReflashLinster iReflashLinster;
- public RefreshableView(Context context) {
- super(context);
- initView(context);
- }
- public RefreshableView(Context context, AttributeSet attrs, int defStyle) {
- super(context, attrs, defStyle);
- initView(context);
- }
- public RefreshableView(Context context, AttributeSet attrs) {
- super(context, attrs);
- initView(context);
- }
- /**
- * 作用:初始化下拉刷新的头部
- *
- * @param context
- * :上下文
- */
- @SuppressLint("InflateParams")
- private void initView(Context context) {
- headerView = LayoutInflater.from(context).inflate(
- R.layout.pull_to_refresh, null);
- // 初始化试图
- arrawImage = (ImageView) headerView.findViewById(R.id.iv_arrow);
- stateMessage = (TextView) headerView.findViewById(R.id.pull_state);
- lastUpdatTime = (TextView) headerView.findViewById(R.id.lastupdatetime);
- progressBar = (ProgressBar) headerView.findViewById(R.id.progress_bar);
- // 通知父布局,才能取到多高,否则为0
- measureView(headerView);
- headerHeight = headerView.getMeasuredHeight();
- topPadding(-headerHeight);
- this.addHeaderView(headerView);
- this.setOnScrollListener(this);
- }
- /**
- * 通知父布局我该占取多少的height 和 width
- *
- * @param view
- * :试图布局
- */
- private void measureView(View view) {
- ViewGroup.LayoutParams p = view.getLayoutParams();
- if (p == null) {
- p = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
- ViewGroup.LayoutParams.WRAP_CONTENT);
- }
- int width = ViewGroup.getChildMeasureSpec(0, 0, p.width);
- int tempHeight = p.height;
- int height;
- if (tempHeight > 0) {
- height = MeasureSpec.makeMeasureSpec(tempHeight,
- MeasureSpec.EXACTLY);
- } else {
- height = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
- }
- view.measure(width, height);
- }
- /**
- * 设置header布局的上边距
- *
- * @param topHeight
- * : 上边距高度
- */
- private void topPadding(int topPadding) {
- headerView.setPadding(headerView.getPaddingLeft(), topPadding,
- headerView.getPaddingRight(), headerView.getPaddingBottom());
- headerView.invalidate();
- }
- @Override
- public void onScrollStateChanged(AbsListView view, int scrollState) {
- this.scorellStatep = scrollState;
- }
- @Override
- public void onScroll(AbsListView view, int firstVisibleItem,
- int visibleItemCount, int totalItemCount) {
- this.firstVisibleItem = firstVisibleItem;
- }
- @SuppressLint("ClickableViewAccessibility")
- @Override
- public boolean onTouchEvent(MotionEvent ev) {
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- // listview 已经滑到头部
- if (firstVisibleItem == 0) {
- isReflash = true;
- startY = (int) ev.getY();
- }
- break;
- case MotionEvent.ACTION_MOVE:
- // 移动的时候所做的操作
- onMove(ev);
- break;
- case MotionEvent.ACTION_UP:
- // 松开的时候看是处于什么状态
- if (state == REFPULL) {
- state = LOADING; // 可以加载数据了
- reflashViewBySate();
- reflashComplete();
- iReflashLinster.reflash();
- } else if (state == PULL) {
- state = NONE;
- isReflash = false;
- reflashViewBySate();
- }
- break;
- }
- return super.onTouchEvent(ev);
- }
- /**
- * 手指移动的时候的所做的操作
- *
- * @param ev
- */
- private void onMove(MotionEvent ev) {
- // 是不是能刷新
- if (!isReflash) {
- return;
- }
- // 当前移动的位置
- int tempY = (int) ev.getY();
- int spance = tempY - startY;
- // 顶部布局是一点一点的显示出来,所以要不停的设置顶部布局
- int topPadding = spance - headerHeight;
- switch (state) {
- case NONE:
- // 当用户更下拉的时候状态:提示下拉状态
- if (spance > 0) {
- state = PULL;
- }
- break;
- case PULL:
- topPadding(topPadding);
- // 用户下拉超过一定并且处于滑动滚动的的时候:提示松开刷新状态
- if (spance > headerHeight + 20
- && scorellStatep == SCROLL_STATE_TOUCH_SCROLL) {
- state = REFPULL;
- reflashViewBySate();
- }
- break;
- case REFPULL:
- topPadding(topPadding);
- // 当用户回滚到低于一定高度的时候:提示下拉刷新状态
- if (spance < headerHeight + 20) {
- state = PULL;
- reflashViewBySate();
- } else if (spance <= 0) {
- state = NONE;
- isReflash = false;
- reflashViewBySate();
- }
- }
- }
- /**
- * 根据状态:在去决定是否刷新数据和加载布局
- */
- private void reflashViewBySate() {
- // 动画效果
- RotateAnimation animation = new RotateAnimation(0, 180,
- RotateAnimation.RELATIVE_TO_SELF, 0.5f,
- RotateAnimation.RELATIVE_TO_SELF, 0.5f);
- animation.setDuration(500);
- animation.setFillAfter(true);
- // 动画效果
- RotateAnimation animation1 = new RotateAnimation(180, 0,
- RotateAnimation.RELATIVE_TO_SELF, 0.5f,
- RotateAnimation.RELATIVE_TO_SELF, 0.5f);
- animation1.setDuration(500);
- animation1.setFillAfter(true);
- switch (state) {
- case NONE:
- topPadding(-headerHeight);
- arrawImage.clearAnimation();
- break;
- case PULL:
- arrawImage.setVisibility(View.VISIBLE);
- progressBar.setVisibility(View.GONE);
- stateMessage.setText("下拉可以刷新");
- arrawImage.clearAnimation();
- arrawImage.setAnimation(animation1);
- break;
- case REFPULL:
- arrawImage.setVisibility(View.VISIBLE);
- progressBar.setVisibility(View.GONE);
- stateMessage.setText("松开可以刷新");
- arrawImage.clearAnimation();
- arrawImage.setAnimation(animation);
- break;
- case LOADING:
- topPadding(50);
- progressBar.setVisibility(View.VISIBLE);
- arrawImage.setVisibility(View.GONE);
- stateMessage.setText("正在刷新...");
- arrawImage.clearAnimation();
- break;
- }
- }
- /**
- * 刷新完成之后,更改刷新时间
- */
- @SuppressLint("SimpleDateFormat")
- public void reflashComplete() {
- state = NONE;
- isReflash = false;
- reflashViewBySate();
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss");
- Date date = new Date(System.currentTimeMillis());
- String time = sdf.format(date);
- lastUpdatTime.setText(time);
- }
- public interface IReflashLinster {
- public void reflash();
- }
- public void setIReflashLinster(IReflashLinster iReflashLinster) {
- this.iReflashLinster = iReflashLinster;
- }
2.Maintivity 在主界面中的使用
- package com.zengtao.pulltorefreshtest;
- import android.app.Activity;
- import android.os.Bundle;
- import android.os.Handler;
- import android.view.Window;
- import android.widget.ArrayAdapter;
- import com.zengtao.refreshview.RefreshableView;
- import com.zengtao.refreshview.RefreshableView.IReflashLinster;
- public class MainActivity extends Activity implements IReflashLinster {
- private RefreshableView listView;
- private ArrayAdapter<String> Adapter;
- private String[] str = { "傻逼才是王道 1", "傻逼才是王道 2", "text 3", "傻逼才是王道 4", "傻逼才是王道 5",
- "傻逼才是王道 6", "傻逼才是王道 7", "傻逼才是王道 8", "傻逼才是王道 9", "傻逼才是王道 10", "傻逼才是王道 11",
- "傻逼才是王道 12", "傻逼才是王道 13", "傻逼才是王道 14", "傻逼才是王道 1", "傻逼才是王道 2", "傻逼才是王道 3",
- "傻逼才是王道 4", "傻逼才是王道 5", "傻逼才是王道 6", "傻逼才是王道 7", "傻逼才是王道 8", "傻逼才是王道 9",
- "傻逼才是王道 10", "傻逼才是王道 11", "傻逼才是王道 12", "傻逼才是王道 13", "傻逼才是王道 14" };
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- setContentView(R.layout.activity_main);
- initView();
- }
- private void initView() {
- listView = (RefreshableView) findViewById(R.id.listview);
- listView.setIReflashLinster(this);
- Adapter = new ArrayAdapter<String>(this,
- android.R.layout.simple_list_item_1, str);
- listView.setAdapter(Adapter);
- }
- @Override
- public void reflash() {
- Handler handler = new Handler();
- handler.postDelayed(new Runnable() {
- @Override
- public void run() {
- }
- }, 3000);
- }
- }
以上变可完成一个自定义的listview的自定义和使用,希望对大家有所帮助,我写的不好,大家请勿怪。


浙公网安备 33010602011771号