仿美團外賣下拉刷新效果

yzf1990 7年前發布 | 14K 次閱讀 安卓開發 Android開發 移動開發

我們經常看到有一些app有著炫酷的下拉刷新動畫,比如美團外賣是騎著電車的袋鼠飛馳在路上,如下圖:

美團外賣下拉刷新

我們的下拉刷新的效果是在android-Ultra-Pull-To-Refresh框架上做的擴展,這是一款非常強大的下拉刷新框架,有著默認的下拉刷新動畫,當然如果我們要實現一些復雜的效果就需要我們自己動手了。android-Ultra-Pull-To-Refresh是支持修改下拉刷新頭部布局的。

首先我們自定義一個view繼承FrameLayout并實現PtrUIHandler接口,在構造方法中加載需要的布局文件,

public MeituanRefreshHeader(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    private void initView() {
        View view = LayoutInflater.from(getContext()).inflate(R.layout.meituanptr_head, null);
        ptrHead = (ImageView) view.findViewById(R.id.ptr_iv);
        addView(view);
    }

PtrUIHandler接口的作用就是提供下拉過程中每部分所調用的方法,我們只需要在這些回調的方法中實現自己的效果就可以了。這里我們主要用到的有:

onUIRefreshPrepare

onUIRefreshBegin

onUIRefreshComplete

onUIPositionChange

四個方法。

這里比較重要的是onUIPositionChange這個方法,在這個方法中我們可以獲取到下拉刷新的比例,然后對控件進行縮放,

public void onUIPositionChange(PtrFrameLayout frame, boolean isUnderTouch, byte status, PtrIndicator ptrIndicator) {
        switch (state) {
            case JdRefreshHeader.STATE_PREPARE:
                if (ptrIndicator.getCurrentPercent() < 1.0f) {
                    ptrHead.setScaleX(ptrIndicator.getCurrentPercent());
                    ptrHead.setScaleY(ptrIndicator.getCurrentPercent());
                }
                break;
        }
    }

在我們松開手之后會調用onUIRefreshBegin方法,這時候只是一張圖片就不行了,需要我們將控件背景修改成一幅動態的畫面

@Override
    public void onUIRefreshBegin(PtrFrameLayout frame) {
        state = JdRefreshHeader.STATE_BEGIN;
        ptrHead.setBackgroundResource(R.drawable.meituan_head);
        drawable = (AnimationDrawable) ptrHead.getBackground();
        if (!drawable.isRunning()) {
            drawable.start();
        }
    }

當然這里的背景是由animation-list實現的,這里不再多說,在完成之后會調用onUIRefreshComplete,我們需要將動畫停止并換到之前的圖片:

@Override
    public void onUIRefreshComplete(PtrFrameLayout frame, boolean isHeader) {
        if (drawable != null && drawable.isRunning()) {
            drawable.stop();
        }
        ptrHead.setBackgroundResource(R.mipmap.a5n);
    }

最后我們自定義類繼承PtrClassicFrameLayout,并在構造方法中添加布局和監聽:

public JdRefreshLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    /**
     * 初始化view
     */
    private void initView() {
        MeituanRefreshHeader mHeaderView = new MeituanRefreshHeader(getContext());
        setHeaderView(mHeaderView);
        addPtrUIHandler(mHeaderView);
        setResistance(3);
    }

ok,我們看一下效果:

效果圖

美團外賣下拉刷新

仔細對比一下就會發現我們現在做的并沒有下圖的效果好,因為下圖是從下拉開始就可以看到袋鼠在一點一點的放大,而上圖確是下拉到一定程度之后才能看到袋鼠的下半身,這又是什么原因造成的呢?

首先我們要知道下拉刷新的頭布局是有一定高度的,當我們下拉的時候,頭布局的底部先出來,而在下拉刷新剛開始的時候,頭布局的控件會縮放的非常小,而setScaleX方法默認是以控件的中心縮放的,所以在下拉的時候控件會以中心逐漸放大,所以會像上圖一樣慢慢看到袋鼠的全部。那么怎樣才能像下圖一樣從一開始就可以看到袋鼠的全部呢,剛才我們說了,安卓中setScaleX默認是以控件的中心縮放的,我們完全可以將他的中心點修改成最底部并且水平居中,這樣一來在下拉的時候袋鼠就會從底部向上開始放大,于是就有了下圖的效果:

if (ptrIndicator.getCurrentPercent() < 1.0f) {
       ptrHead.setPivotX(ptrHead.getWidth() / 2);
       ptrHead.setPivotY(ptrHead.getHeight());
       ptrHead.setScaleX(ptrIndicator.getCurrentPercent());
       ptrHead.setScaleY(ptrIndicator.getCurrentPercent());
   }

需要注意的是setPivotX的參數是以像素為單位的,到這里就大功告成了。

 

來自:http://www.jianshu.com/p/433f42cffa18

 

 本文由用戶 yzf1990 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!