下拉刷新动画研究

昨天公司提了一个需求。说是要有自己特色的下拉刷新上拉载入很多其它,随后就去万能的github上面看看自己之前存过的那些。偶然间看到这个Android-AnimatePullToRefreshListView,这玩意能够使用gif图片或者帧动画去运行headview动画载入,而且是基于chrisbanes的Android-PullToRefresh,这样还方便与我项目无缝衔接

上一张效果图

大体上简单说明下:

1.gif与帧动画播放採用的是android-gif-drawable

2.主题上是改动了RotateLoadingLayout类。看代码

//帧动画三张图
private int[] mGifRes = {
            R.drawable.dropdown_loading_00,
            R.drawable.dropdown_loading_01,
            R.drawable.dropdown_loading_02,
    };
//通过下拉的scale比例,去计算应该显示哪张图片(下拉距离/headview高度)
protected void onPullImpl(float scaleOfLayout) {
    int index = (int) (scaleOfLayout / 1f * 10);
    if (index == mPrevIndex) {
        return;
    } else {
        if (index > 10) {
            index = 10;
        }
        int res = getResources().getIdentifier(String.format("dropdown_anim_%02d",  index), "drawable", getContext().getPackageName());
        mHeaderImage.setImageResource(res);
        mPrevIndex = index;
    }
}
//正在刷新,就播放一下动画
@Override
protected void refreshingImpl() {
       if (mGifAnimation == null) {
           mGifAnimation = new GifAnimation(mHeaderImage, mGifRes);
       }
       mGifAnimation.start();
   }

//刷新结束,就停止动画播放
@Override
protected void resetImpl() {
       mHeaderImage.clearAnimation();
       if (mGifAnimation != null) {
           mGifAnimation.stop();
       }
}

在PullToRefreshBase中能够看到

/**
     * Actions a Pull Event
     *
     * @return true if the Event has been handled, false if there has been no
     * change
     */
    private void pullEvent() {
        final int newScrollValue;
        final int itemDimension;
        final float initialMotionValue, lastMotionValue;

        switch (getPullToRefreshScrollDirection()) {
            case HORIZONTAL:
                initialMotionValue = mInitialMotionX;
                lastMotionValue = mLastMotionX;
                break;
            case VERTICAL:
            default:
                initialMotionValue = mInitialMotionY;
                lastMotionValue = mLastMotionY;
                break;
        }
        //得到对应的高度
        switch (mCurrentMode) {
            case PULL_FROM_END:
                newScrollValue = Math.round(Math.max(initialMotionValue
                        - lastMotionValue, 0)
                        / FRICTION);
                itemDimension = getFooterSize();
                break;
            case PULL_FROM_START:
            default:
                newScrollValue = Math.round(Math.min(initialMotionValue
                        - lastMotionValue, 0)
                        / FRICTION);
                itemDimension = getHeaderSize();
                break;
        }

        setHeaderScroll(newScrollValue);

        if (newScrollValue != 0 && !isRefreshing()) {
            //通过当前移动的比例跟view自身的高度,计算出scale
            float scale = Math.abs(newScrollValue) / (float) itemDimension;
            //不管你设置的是何种mode。都会有对应的回调
            switch (mCurrentMode) {
                case PULL_FROM_END:
                    mFooterLayout.onPull(scale);
                    break;
                case PULL_FROM_START:
                default:
                    mHeaderLayout.onPull(scale);
                    break;
            }
            //前台接口回调
            if (mState != State.PULL_TO_REFRESH
                    && itemDimension >= Math.abs(newScrollValue)) {
                setState(State.PULL_TO_REFRESH);
            } else if (mState == State.PULL_TO_REFRESH
                    && itemDimension < Math.abs(newScrollValue)) {
                setState(State.RELEASE_TO_REFRESH);
            }
        }
    }

只是这边有个情况要考虑下,就是之前我们能够直接使用ptrDrawable、ptrDrawableStart、ptrDrawableEnd去替换上拉下拉不同的图片

<!-- Drawable to use as Loading Indicator. Changes both Header and Footer. -->
        <attr name="ptrDrawable" format="reference" />

        <!-- Drawable to use as Loading Indicator in the Header View. Overrides value set in ptrDrawable. -->
        <attr name="ptrDrawableStart" format="reference" />

        <!-- Drawable to use as Loading Indicator in the Footer View. Overrides value set in ptrDrawable. -->
        <attr name="ptrDrawableEnd" format="reference" />

可是通过如今代码去构建view的话。这些自己定义属性是不具备这个能力,所以要自行替换foot和head

// We need to create now layouts now
        mHeaderLayout = createLoadingLayout(context, Mode.PULL_FROM_START, a);
        mFooterLayout = createLoadingLayout(context, Mode.PULL_FROM_END, a);

//创建视图的方法
protected LoadingLayout createLoadingLayout(Context context, Mode mode, TypedArray attrs) {
        LoadingLayout layout = mLoadingAnimationStyle.createLoadingLayout(
                context, mode, getPullToRefreshScrollDirection(), attrs);
        layout.setVisibility(View.INVISIBLE);
        return layout;
    }

//能够改造这个枚举。返回须要的layout
public static enum AnimationStyle {
    /**
     * This is the default for Android-PullToRefresh. Allows you to use any
     * drawable, which is automatically rotated and used as a Progress Bar.
     */
    ROTATE,

    /**
     * This is the old default, and what is commonly used on iOS. Uses an
     * arrow image which flips depending on where the user has scrolled.
     */
    FLIP,

    GIF;

    static AnimationStyle getDefault() {
        return ROTATE;
    }

    /**
     * Maps an int to a specific mode. This is needed when saving state, or
     * inflating the view from XML where the mode is given through a attr
     * int.
     *
     * @param modeInt - int to map a Mode to
     * @return Mode that modeInt maps to, or ROTATE by default.
     */
    static AnimationStyle mapIntToValue(int modeInt) {
        switch (modeInt) {
            case 0x0:
            default:
                return ROTATE;
            case 0x1:
                return FLIP;
            case 0x10:
                return GIF;
        }
    }

    LoadingLayout createLoadingLayout(Context context, Mode mode,
                                      Orientation scrollDirection, TypedArray attrs) {
        switch (this) {
            case ROTATE:
            default:
                return new RotateLoadingLayout(context, mode, scrollDirection,
                        attrs);
            case FLIP:
                return new FlipLoadingLayout(context, mode, scrollDirection,
                        attrs);
            case GIF:
                return new GifLoadingLayout(context, mode, scrollDirection,
                        attrs);
        }
    }
}

仅仅有这样才干创建出不同的head与foot

OK,今天就说这么多,有疑问大家一起交流

时间: 2024-12-30 00:20:17

下拉刷新动画研究的相关文章

Android源码解析--超好看的下拉刷新动画

本篇博客代码下载地址:https://github.com/Yalantis/Taurus 最近在github上看到了好多高端.大气.上档次的动画效果,如果给你的项目中加上这些动画,相信你的app一定很优秀,今天给大家分析一下来自Yalantis的一个超好看的下拉刷新动画. 首先我们看一下效果如何: 怎么样?是不是很高大上?接下来我们看一下代码: 一.首先我们需要自定义刷新的动态RefreshView(也就是下拉时候的头) 1.初始化头所占用的Dimens private void initia

Android UI- PullToRrefresh自定义下拉刷新动画

Android UI- PullToRrefresh自定义下拉刷新动画 如果觉得本文不错,麻烦投一票,2014年博客之星投票地址:http://vote.blog.csdn.net/blogstar2014/details?username=wwj_748#content 本篇博文要给大家分享的是如何使用修改开源项目PullToRrefresh下拉刷新的动画,来满足我们开发当中特定的需求,我们比较常见的一种下拉刷新样式可能是以下这种: 就是下拉列表的时候两个箭头上下翻转,更改日期文本和刷新状态,

Android PullToRrefresh 自定义下拉刷新动画 (listview、scrollview等)

PullToRefreshScrollView 自定义下拉刷新动画,只需改一处. 以下部分转载自http://blog.csdn.net/superjunjin/article/details/45022595 一,定义刷新动画的layout 在library下的com.handmark.pulltorefresh.library.internal包中的FlipLoadingLayout和RotateLoadingLayout FlipLoadingLayout为ios风格的箭头颠倒的刷新动画

Android自定义下拉刷新动画--仿百度外卖下拉刷新

好久没写博客了,小编之前一段时间一直在找工作,从天津来到了我们的大帝都,感觉还不错.好了废话不多说了,开始我们今天的主题吧.现如今的APP各式各样,同样也带来了各种需求,一个下拉刷新都能玩出花样了,前两天订饭的时候不经意间看到了"百度外卖"的下拉刷新,今天的主题就是它–自定义下拉刷新动画. 看一下实现效果吧: 动画 我们先来看看Android中的动画吧: Android中的动画分为三种: Tween动画,这一类的动画提供了旋转.平移.缩放等效果. Alpha – 淡入淡出 Scale

Xamarin.Form 下拉刷新动画

好像园子里对 Xamarin 感兴趣的人很少啊... 来, 先给各位爷们逗个笑, 本山大爷本色出演: 照例, 上源码: https://github.com/gruan01/ListViewExtend 目前只有 WP 的效果, Android 还在研究, IOS 的还没计划. ------------------------------------------------------ Xamarin.Form 的 ListView 只支持下拉刷新 (这里有用法), 上拉 加载更多 没有对应的事

快速下拉刷新动画

-(void)setupTableview{ //添加下拉的动画图片 //设置下拉刷新回调 [self.tableView addGifHeaderWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; //设置普通状态的动画图片 NSMutableArray *idleImages = [NSMutableArray array]; for (NSUInteger i = 1; i<=60; ++i) { // U

用贝塞尔曲线做的一个下拉刷新动画

以前就一直觉得ios 上的 mail 的下拉刷新的动画非常酷炫,但是一直不知道那种"滴虫"效果是怎么实现的.直到前段时间看到的贝塞尔曲线,感觉很神奇.如下图: 看起来和滴虫动画有点像,然后就花了点时间做了一个下拉刷新出来. 项目地址:https://github.com/ufo22940268/DropRefreshView 欢迎围观

PullToRrefresh自定义下拉刷新动画

首先,下载著名的刷新框架https://github.com/chrisbanes/Android-PullToRefresh,其中simple为demo,library和extras作为项目包导入到simple中 一,定义刷新动画的layout 在library下的com.handmark.pulltorefresh.library.internal包中的FlipLoadingLayout和RotateLoadingLayout FlipLoadingLayout为ios风格的箭头颠倒的刷新动

一款Android开源的下拉刷新动画

无意间在GitHub看到的,就Down了下来.但是作者是用AndroidStudio开发的,这边移动Eclipse供小伙伴们下载使用. 截图 这么好的东西因为字数不够不让分享,得了,贴段代码吧 package com.example.pullrefersh; import android.content.Context; import android.content.res.TypedArray; import android.support.v4.view.MotionEventCompat;