Ultra-Pull-To-Refresh-自定义头部

来源:互联网 发布:一千个哈姆雷特 知乎 编辑:程序博客网 时间:2024/05/10 07:55

本篇项目github源码地址

推荐阅读:

liaohuqiu/android-Ultra-Pull-To-Refresh
我眼中的下拉刷新
android-Ultra-Pull-To-Refresh 源码解析
Ultra-Pull-To-Refresh 自定义下拉刷新视差动画
android-Ultra-Pull-To-Refresh/SwipeRefreshLayout嵌套ViewPager/ScrollView滑动冲突解决

准备工作,添加依赖:

    //刷新    compile 'in.srain.cube:ultra-ptr:1.0.11'    //    compile 'com.jakewharton:butterknife:8.5.1'    annotationProcessor 'com.jakewharton:butterknife-compiler:8.5.1'

一、自定义刷新头部viewgroup实现PtrUIHandler接口:

/** * step0:下拉/准备下拉状态 * step1:下拉->可刷新状态 * step2:刷新状态 * step3:刷新结束状态 */public class PtrMeiTuanHeader extends LinearLayout implements PtrUIHandler {    private static final String TAG = PtrMeiTuanHeader.class.getSimpleName();    @BindView(R.id.ivFirst)    ImageView ivFirst;    @BindView(R.id.ivSecond)    ImageView ivSecond;    @BindView(R.id.ivThird)    ImageView ivThird;    @BindView(R.id.tvMsg)    TextView tvMsg;    private Matrix mMatrix = new Matrix();    private AnimationDrawable mSecondAnimation;    private AnimationDrawable mThirdAnimation;    public PtrMeiTuanHeader(Context context) {        this(context, null);    }    public PtrMeiTuanHeader(Context context, AttributeSet attrs) {        this(context, attrs, 0);    }    public PtrMeiTuanHeader(Context context, AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        View headerView = LayoutInflater.from(context).inflate(R.layout.header_meituan, this);//        ButterKnife.bind(headerView);        init();    }    /**     * 初始化帧动画     */    private void init() {        mSecondAnimation = (AnimationDrawable) ivSecond.getDrawable();        mThirdAnimation = (AnimationDrawable) ivThird.getDrawable();    }    /**     * 刷新准备 : Header 将要出现时调用。     *     * @param frame     */    @Override    public void onUIRefreshPrepare(PtrFrameLayout frame) {//调用1        Log.e("111111","onUIRefreshPrepare");        pullStep0(0.0f);    }    /**     * 开始刷新 : Header 进入刷新状态之前调用。     *     * @param frame     */    @Override    public void onUIRefreshBegin(PtrFrameLayout frame) {//调用4        Log.e("111111","onUIRefreshBegin");        pullStep2();    }    /**     * 刷新结束 : Header 开始向上移动之前调用。     *     * @param frame     */    @Override    public void onUIRefreshComplete(PtrFrameLayout frame) {//调用5        Log.e("111111","onUIRefreshComplete");        pullStep3();    }    /**     * 刷新重置 : Content重新回到顶部Header消失,重置 View。     *     * @param frame     */    @Override    public void onUIReset(PtrFrameLayout frame) {//调用6        Log.e("111111","onUIReset");        resetView();    }    /**     * isUnderTouch: 是否松手(true、false)     * status: 状态(1:init、2:prepare、3:loading、4:complete)     */    @Override    public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {        final int mOffsetToRefresh = frame.getOffsetToRefresh();//可释放刷新位置        final int currentPos = ptrIndicator.getCurrentPosY();//当前位置        final int lastPos = ptrIndicator.getLastPosY();//前一个位置        if (isUnderTouch) {//下拉过程的两个阶段:到达可释放刷新位置前后            if (lastPos < currentPos && currentPos < mOffsetToRefresh) {//调用2                Log.e("111111","onUIPositionChange ----");                float scale = lastPos / (float) mOffsetToRefresh;                pullStep0(scale);            } else {//调用3                Log.e("111111","onUIPositionChange ++++");                pullStep1(frame);            }        }    }    private void pullStep0(float scale) {        ivFirst.setVisibility(View.VISIBLE);        ivSecond.setVisibility(View.INVISIBLE);        ivThird.setVisibility(View.INVISIBLE);        scaleImage(scale);        tvMsg.setText(getResources().getString(R.string.cube_ptr_pull_down_to_refresh));    }    private void pullStep1(PtrFrameLayout frame) {        if (!frame.isPullToRefresh()) {            ivFirst.setVisibility(View.INVISIBLE);            ivSecond.setVisibility(View.VISIBLE);            ivThird.setVisibility(View.INVISIBLE);            mSecondAnimation.start();            tvMsg.setText(getResources().getString(R.string.cube_ptr_release_to_refresh));        }    }    private void pullStep2() {        ivFirst.setVisibility(View.INVISIBLE);        ivSecond.setVisibility(View.INVISIBLE);        ivThird.setVisibility(View.VISIBLE);        cancelAnimationSecond();        mThirdAnimation.start();        tvMsg.setText(R.string.cube_ptr_refreshing);    }    private void pullStep3() {        ivFirst.setVisibility(View.INVISIBLE);        ivSecond.setVisibility(View.INVISIBLE);        ivThird.setVisibility(View.VISIBLE);        cancelAnimationThird();        tvMsg.setText(getResources().getString(R.string.cube_ptr_refresh_complete));    }    private void scaleImage(float scale) {        mMatrix.setScale(scale, scale, ivFirst.getWidth() / 2, ivFirst.getHeight() / 2);        ivFirst.setImageMatrix(mMatrix);    }    @Override    protected void onDetachedFromWindow() {        super.onDetachedFromWindow();        resetView();    }    private void resetView() {        cancelAnimations();    }    private void cancelAnimations() {        cancelAnimationSecond();        cancelAnimationThird();    }    private void cancelAnimationSecond() {        if (mSecondAnimation != null && mSecondAnimation.isRunning()) {            mSecondAnimation.stop();        }    }    private void cancelAnimationThird() {        if (mThirdAnimation != null && mThirdAnimation.isRunning()) {            mThirdAnimation.stop();        }    }}

二、自定义刷新viewgroup继承PtrFrameLayout

1、添加头布局setHeaderView
2、实现头部监听addPtrUIHandler

public class PtrlMeiTuanFrameLayout extends PtrFrameLayout {    public PtrlMeiTuanFrameLayout(Context context) {        super(context);        init();    }    public PtrlMeiTuanFrameLayout(Context context, AttributeSet attrs) {        super(context, attrs);        init();    }    public PtrlMeiTuanFrameLayout(Context context, AttributeSet attrs, int defStyle) {        super(context, attrs, defStyle);        init();    }    private void init() {        PtrMeiTuanHeader mHeaderView = new PtrMeiTuanHeader(getContext());        setHeaderView(mHeaderView);        addPtrUIHandler(mHeaderView);    }}

3、布局中使用刷新viewgroup:

<?xml version="1.0" encoding="utf-8"?><com.example.lenovo.myptrrefreshtest.view.PtrlMeiTuanFrameLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/ptrFrame_custom"    android:layout_width="match_parent"    android:layout_height="match_parent">    <LinearLayout        android:layout_width="match_parent"        android:layout_height="match_parent"        android:orientation="vertical">        <TextView            android:id="@+id/tvDrag"            android:layout_width="match_parent"            android:layout_height="40dp"            android:gravity="center"            android:text="@string/meituan"            android:textSize="16sp" />    </LinearLayout></com.example.lenovo.myptrrefreshtest.view.PtrlMeiTuanFrameLayout>

4、代码中设置刷新:

 ptrFrame.setPtrHandler(new PtrHandler() {            @Override            public boolean checkCanDoRefresh(PtrFrameLayout frame, View content, View header) {                return true;            }            @Override            public void onRefreshBegin(PtrFrameLayout frame) {                ptrFrame.postDelayed(new Runnable() {                    @Override                    public void run() {                        //请求数据                        Log.e("111111","请求数据");                        //刷新结束                        ptrFrame.refreshComplete();                    }                }, 2000);            }        });

其他:

1、完整的一次下拉刷新,打印log如下:

onUIRefreshPrepareonUIPositionChange ----onUIPositionChange ----onUIPositionChange ----onUIPositionChange ----onUIPositionChange ----onUIPositionChange ----onUIPositionChange ----onUIPositionChange ++++onUIPositionChange ++++onUIPositionChange ++++onUIPositionChange ++++onUIPositionChange ++++onUIPositionChange ++++onUIRefreshBegin请求数据onUIRefreshCompleteonUIReset

注:PtrFrameLayout.getOffsetToRefresh:到达这个位置,释放后才会执行”请求数据”

2、在一次完整的下拉刷新过程中实现PtrUIHandler接口的方法调用图:

这里写图片描述

3、onUIPositionChange的参数isUnderTouch,status在一次完整的下拉刷新过程中值得变化图:

isUnderTouch:手指是否触摸屏幕,下拉过程中一直为true,释放为false。
status:在PtrFrameLayout中有定义:

    public final static byte PTR_STATUS_INIT = 1;    private byte mStatus = PTR_STATUS_INIT;    public final static byte PTR_STATUS_PREPARE = 2;    public final static byte PTR_STATUS_LOADING = 3;    public final static byte PTR_STATUS_COMPLETE = 4;

这里写图片描述

参考:

自定义下拉刷新控件-仿美团刷新效果

使用 Ultra Pull To Refresh 定制自己的下拉刷新头部