自定义控件RefreshListView

本文介绍了一种基于Android的自定义ListView——RefreshListView的实现方法,该组件支持下拉刷新功能。文章详细阐述了从初始化头控件、处理触摸事件逻辑到回调刷新状态等步骤,并提供了完整的代码示例。
摘要由CSDN通过智能技术生成

RefreshListView下拉刷新

1.RefreshListView继承ListView
2.在构造方法初始化头控件和相应的动画
3.在onTouchEvent中判断逻辑:

1.判断滑动方向
2.处理滑动各个状态相应的控件属性和动画

4.回调接口:

1.在正在刷新的状态时候判断接口是否为空
2.回调接口方法,通知刷新状态

5.刷新结束,更新刷新时间:

1.方法设置传入context参数
2.开启子线程睡眠模拟刷新耗时(可省略)
3.开启通过context.runOnUiThread初始化头布局
4.更新刷新时间
HeaderView效果图:
这里写图片描述
这里写图片描述
这里写图片描述

代码如下:
package com.cf.zhbj.view;

import android.app.Activity;
import android.content.Context;
import android.os.SystemClock;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.cf.zhbj.R;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Created by chenfan on 2016/7/19.
 */
public class RefreshListView extends ListView {
    View mHeraderView;
    int mHeraderViewHeight;

    private static final int STATE_PULL_TO_REFRESH=0;//下拉刷新状态
    private static final int STATE_RELEASE_TO_REFRESH =1;//松开刷新
    private static final int STATE_REFRESH=2;//正在刷新

    private int mCurrentState=STATE_PULL_TO_REFRESH;//默认是下拉刷新状态

    private TextView tvState;
    private TextView tvTime;
    private ImageView ivArrow;
    private ProgressBar pbLoading;
    private RotateAnimation animUp;
    private RotateAnimation animDown;

    public RefreshListView(Context context) {
        this(context,null);
    }

    public RefreshListView(Context context, AttributeSet attrs) {
        this(context, attrs,-1);
    }

    public RefreshListView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initHeaderView();
    }
    //初始化头布局
    private void initHeaderView(){
        mHeraderView = View.inflate(getContext(), R.layout.pull_to_refresh_header,null);
        addHeaderView(mHeraderView);//给ListView添加头布局

        tvState= (TextView) mHeraderView.findViewById(R.id.tv_state);
        tvTime= (TextView) mHeraderView.findViewById(R.id.tv_time);
        ivArrow= (ImageView) mHeraderView.findViewById(R.id.iv_arrow);
        pbLoading= (ProgressBar) mHeraderView.findViewById(R.id.pb_loading);

        //隐藏头布局
        //获取当前头布局高度,然后设置负paddingTop,布局就会向上走
        mHeraderView.measure(0,0);//手动测量,宽高传0
        mHeraderViewHeight =mHeraderView.getMeasuredHeight();
        //System.out.println("height"+ mHeraderViewHeight);
        mHeraderView.setPadding(0,-mHeraderViewHeight,0,0);
        //初始化动画
        initArrowAnim();
    }
    private int startY=-1;
    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        switch (ev.getAction()){
            case MotionEvent.ACTION_DOWN:
                startY = (int)ev.getY();
                break;
            case MotionEvent.ACTION_MOVE:
                if(startY==-1){//没有获取到按下的事件(按住头条新闻滑动时,按下ViewPager消费了)
                    startY= (int) ev.getY();//重新获取起点位置
                }
                int endY= (int) ev.getY();
                int dy=endY-startY;
                if(mCurrentState==STATE_REFRESH){
                    //如果正在刷新,什么都不做
                    break;
                }
                int firstVisiblePosition = this.getFirstVisiblePosition();//当前显示第一个Item的位置
                if(dy>0&&firstVisiblePosition==0){
                    //下拉动作&当前在ListView的顶部
                    int padding=-mHeraderViewHeight+dy;

                    if(padding>0&&mCurrentState!=STATE_RELEASE_TO_REFRESH){
                        //切换到松开刷新状态
                        mCurrentState= STATE_RELEASE_TO_REFRESH;
                        refreshState();
                    }else if(padding<=0&&mCurrentState!=STATE_PULL_TO_REFRESH){
                        //切换到下拉刷新状态
                        mCurrentState=STATE_PULL_TO_REFRESH;
                        refreshState();
                    }
                    //通过修改padding来设置当前控件刷新的位置
                    mHeraderView.setPadding(0,padding,0,0);
                    return true;//消耗掉事件
                }
                break;
            case MotionEvent.ACTION_UP://离开触摸时
                startY=-1;//起始位置归0
                if(mCurrentState==STATE_RELEASE_TO_REFRESH){
                    //切换成正在刷新
                    mCurrentState=STATE_REFRESH;
                    //回到起始位置
                    mHeraderView.setPadding(0,0,0,0);
                    refreshState();
                }else if(mCurrentState==STATE_PULL_TO_REFRESH){
                    //隐藏刷新控件
                    mHeraderView.setPadding(0,-mHeraderViewHeight,0,0);
                }
                break;
        }
        return super.onTouchEvent(ev); //ListView原生滑动处理
    }
    private void  initArrowAnim(){
        //箭头向上
        animUp=new RotateAnimation(0,-180, Animation.RELATIVE_TO_SELF,0.5f,
                Animation.RELATIVE_TO_SELF,0.5f);
        animUp.setDuration(300);
        animUp.setFillAfter(true);//保持动画结束的状态

        //箭头向下
       animDown=new RotateAnimation(-180,0, Animation.RELATIVE_TO_SELF,0.5f,
                Animation.RELATIVE_TO_SELF,0.5f);
        animDown.setDuration(300);
        animDown.setFillAfter(true);//保持动画结束的状态
    }
    private void refreshState() {
        switch (mCurrentState){
            case STATE_PULL_TO_REFRESH:
                tvState.setText("下拉刷新");
                pbLoading.setVisibility(View.INVISIBLE);
                ivArrow.setVisibility(View.VISIBLE);
                ivArrow.startAnimation(animDown);
                break;
            case STATE_RELEASE_TO_REFRESH:
                tvState.setText("松开刷新");
                pbLoading.setVisibility(View.INVISIBLE);
                ivArrow.setVisibility(View.VISIBLE);
                ivArrow.startAnimation(animUp);
                break;
            case STATE_REFRESH:
                tvState.setText("正在刷新...");
                pbLoading.setVisibility(View.VISIBLE);
                ivArrow.clearAnimation();//清理掉动画才能隐藏
                ivArrow.setVisibility(View.INVISIBLE);

                //回调下拉刷新
                if(mListener!=null){
                    mListener.onRefresh();
                }
                break;
        }
    }
    //刷新结束,隐藏控件
    public void onRefreshComplete(final Activity activity){
        new Thread(){
            @Override
            public void run() {
                SystemClock.sleep(1000);//模拟耗时
                activity.runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        mHeraderView.setPadding(0,-mHeraderViewHeight,0,0);
                        //初始化状态
                        tvState.setText("下拉刷新");
                        pbLoading.setVisibility(View.INVISIBLE);
                        ivArrow.setVisibility(View.VISIBLE);
                        mCurrentState=STATE_PULL_TO_REFRESH;
                        //更新刷新时间
                        setRefreshTime();
                    }
                });
            }
        }.start();
    }

    private OnRefreshListener mListener;
    public void setOnRefreshListener(OnRefreshListener listener){
        mListener=listener;
    }

    //回调接口,通知刷新状态
    public interface OnRefreshListener{
        //下拉刷新的回调
        public void onRefresh();
    }
    private void setRefreshTime(){
        SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String time = format.format(new Date());
        tvTime.setText(time);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值