Android开源之ILayoutAnimationController,1行代码让你的ViewGroup拥有华丽的布局动画!

直接上动图:

ILayoutAnimationController录屏.gif

源码及DEMO已上传至GitHub:ILayoutAnimationController,欢迎大家提Bug,喜欢的话记得Star或Fork下哈!

1:ILayoutAnimationController是什么?其实现思路是?

  • LayoutAnimationController大家应该都了解,应用于ViewGroup实例的布局动画,但Android原生布局动画,仅支持顺序、倒序、随机3种动画执行顺序!
  • ILayoutAnimationController是一个自定义LayoutAnimationController,通过重写其getTransformedIndex方法,1行代码即可任意定制布局动画的执行顺序,实现不同展示效果!

2:使用方法:

方法一:1行代码直接搞定,以下两种方法任选其一
  • ILayoutAnimationController.setLayoutAnimation(@NonNull ViewGroup viewGroup, @NonNull Animation animation, float delay, @Nullable final IndexAlgorithm indexAlgorithm)

  • ILayoutAnimationController.setLayoutAnimation(@NonNull ViewGroup viewGroup,@AnimRes int animResId, float delay,@Nullable final IndexAlgorithm indexAlgorithm)

方法二:首先创建ILayoutAnimationController实例,然后将此实例作为参数为ViewGroup设置布局动画
  • ILayoutAnimationController.generateController(@NonNull Animation animation, float delay, @Nullable final IndexAlgorithm indexAlgorithm)

  • ViewGroup.setLayoutAnimation(LayoutAnimationController controller)

3:示例代码:

LinearLayout ll = (LinearLayout) findViewById(R.id.ll);
//两行代码设置布局动画:
ILayoutAnimationController controller = 
  ILayoutAnimationController.generateController(
    AnimationUtils.loadAnimation(this,R.anim.activity_open_enter),
    0.8f,
    ILayoutAnimationController.IndexAlgorithm.INDEXSIMPLEPENDULUM);
ll.setLayoutAnimation(controller);

//一行代码直接搞定:
ILayoutAnimationController.setLayoutAnimation(
    ll,
    R.anim.activity_open_enter,
    0.8f,
    ILayoutAnimationController.IndexAlgorithm.INDEXSIMPLEPENDULUM);

4:ILayoutAnimationController部分代码:

public class ILayoutAnimationController extends LayoutAnimationController {
    private Callback onIndexListener;
    public void setOnIndexListener(Callback onIndexListener) {
        this.onIndexListener = onIndexListener;
    }
    public ILayoutAnimationController(Context context, AttributeSet attrs) {
        super(context, attrs);
    }
    public ILayoutAnimationController(Animation animation) {
        super(animation);
    }
    public ILayoutAnimationController(Animation animation, float delay) {
        super(animation, delay);
    }
    @Override
    protected int getTransformedIndex(AnimationParameters params) {
        if (onIndexListener!=null){
            return onIndexListener.getTransformedIndex(
              this,
              params.count,
              params.index);
        }else{
            return super.getTransformedIndex(params);
        }
    }
    /**
     * callback for get play animation order
     */
    public interface Callback{
        public int getTransformedIndex(
          ILayoutAnimationController controller, 
          int count, 
          int index);
    }
    /**
     * 根据当前枚举类型的值,确定在setOnIndexListener方法中的
     * CustomLayoutAnimationController.Callback
     * 实例的getTransformedIndex方法调用GetTransformedIndexUtils中的那种方法
     */
    public enum IndexAlgorithm{
        INDEX1325476,
        INDEX135246,
        INDEX246135,
        INDEXSIMPLEPENDULUM,
        MIDDLETOEDGE,
        INDEX15263748,
        INDEX1325476REVERSE,
        INDEX135246REVERSE,
        INDEX246135REVERSE,
        INDEXSIMPLEPENDULUMREVERSE,
        INDEXMIDDLETOEDGEREVERSE,
        INDEX15263748REVERSE
    }
    public static ILayoutAnimationController generateController(
        Animation animation, float delay){
        return generateController(animation,delay,null);
    }
    /**
     * 根据指定的动画、单个子View动画延时、
     * 子View动画执行顺序算法枚举值,
     * 创建一个新的CustomLayoutAnimationController实例
     * @param animation the animation to use on each child of the view group
     * @param delay the delay by which each child's animation must be offset
     * @param indexAlgorithm 子View动画执行顺序算法枚举值
     * @return
     */
    public static ILayoutAnimationController generateController(
        @NonNull Animation animation, 
        float delay, 
        @Nullable final IndexAlgorithm indexAlgorithm){
        ILayoutAnimationController controller = 
          new ILayoutAnimationController(animation,delay);
        controller.setOnIndexListener(new Callback() {
            @Override
            public int getTransformedIndex(
              ILayoutAnimationController controller, int count, int index) {
                if(indexAlgorithm != null){
                    switch (indexAlgorithm){
                        case INDEX1325476:
                            return GetTransformedIndexUtils
                                    .getTransformedIndex1325476(count,index);
                        case INDEX135246:
                            return GetTransformedIndexUtils
                                    .getTransformedIndex135246(count,index);
                        case INDEX246135:
                            return GetTransformedIndexUtils
                                    .getTransformedIndex246135(count,index);
                        case INDEXSIMPLEPENDULUM:
                            return GetTransformedIndexUtils
                                    .getTransformedIndexSimplePendulum(
                                      count,index);
                        case MIDDLETOEDGE:
                            return GetTransformedIndexUtils
                                    .getTransformedIndexMiddleToEdge(
                                      count,index);
                        case INDEX15263748:
                            return GetTransformedIndexUtils
                                    .getTransformedIndex15263748(count,index);
                        case INDEX1325476REVERSE:
                            return GetTransformedIndexUtils
                                    .getTransformedIndex1325476REVERSE(
                                      count,index);
                        case INDEX135246REVERSE:
                            return GetTransformedIndexUtils
                                    .getTransformedIndex135246REVERSE(
                                      count,index);
                        case INDEX246135REVERSE:
                            return GetTransformedIndexUtils
                                    .getTransformedIndex246135REVERSE(
                                      count,index);
                        case INDEXSIMPLEPENDULUMREVERSE:
                            return GetTransformedIndexUtils
                                    .getTransformedIndexSimplePendulumREVERSE(
                                      count,index);
                        case INDEXMIDDLETOEDGEREVERSE:
                            return GetTransformedIndexUtils
                                    .getTransformedIndexMiddleToEdgeREVERSE(
                                      count,index);
                        case INDEX15263748REVERSE:
                            return GetTransformedIndexUtils
                                    .getTransformedIndex15263748REVERSE(
                                      count,index);
                        default:
                            break;
                    }
                }
                return index;
            }
        });
        return controller;
    }

    /**
     * 根据指定的动画、单个子View动画延时、
     * 子View动画执行顺序算法枚举值,
     * 创建一个新的CustomLayoutAnimationController实例,
     * 将此实例作为参数为viewGroup设置布局动画
     * @param viewGroup
     * @param animation
     * @param delay
     * @param indexAlgorithm
     */
    public static void setLayoutAnimation(
        @NonNull ViewGroup viewGroup, 
        @NonNull Animation animation, 
        float delay, 
        @Nullable final IndexAlgorithm indexAlgorithm){
        ILayoutAnimationController controller = 
          generateController(animation,delay,indexAlgorithm);
        viewGroup.setLayoutAnimation(controller);
    }

    /**
     * 根据传入的动画资源ID、单个子View动画延时、
     * 子View动画执行顺序算法枚举值,
     * 创建一个新的CustomLayoutAnimationController实例,
     * 将此实例作为参数为viewGroup设置布局动画
     * @param viewGroup
     * @param animResId
     * @param delay
     * @param indexAlgorithm
     */
    public static void setLayoutAnimation(
        @NonNull ViewGroup viewGroup,
        @AnimRes int animResId, 
        float delay,
        @Nullable final IndexAlgorithm indexAlgorithm){
        Animation animation = AnimationUtils.loadAnimation(
          viewGroup.getContext(),animResId);
        setLayoutAnimation(viewGroup,animation,delay,indexAlgorithm);
    }
}

public final class GetTransformedIndexUtils {
**略**
    /**
     * 先执行第1项 的布局动画,
     * 然后执行第3项 的布局动画,然后执行第2项 的布局动画,
     * 然后执行第5项 的布局动画,然后执行第4项 的布局动画,
     * 然后执行第7项 的布局动画,然后执行第6项 的布局动画---
     * @param count
     * @param index
     * @return
     */
    public static int getTransformedIndex1325476(int count, int index){
        if ((index + 1) % 2 != 0) {
            if (index == 0) {
                return index;
            } else {
                return index - 1;
            }
        } else {
            if (index == count - 1) {
                return index;
            } else {
                return index + 1;
            }
        }
    }

    /**
     * 先执行奇数项 的布局动画,再执行偶数项 的布局动画
     * @param count
     * @param index
     * @return
     */
    public static int getTransformedIndex135246(int count, int index){
        if (index%2==0){
            //1:奇数项
            return index/2;
        }else {
            //2:偶数项
            if(count%2==0){
                //2.1:当总项数是偶数
                return (count/2-1) + (index+1)/2;
            }else {
                //2.2:当总项数是奇数
                return (count/2) + (index+1)/2;
            }
        }
    }
**略**
}

注意:

  • 使用ILayoutAnimationController获取的ILayoutAnimationController实例,调用setOrder(int order)方法无效!

LayoutAnimation基础知识:

就不再详述,不太了解的同学可以看看这篇博客,CSDN上随意搜就好多:
Android 动画之LayoutAnimation


源码及DEMO已上传至GitHub:ILayoutAnimationController,欢迎大家提Bug,喜欢的话记得Star或Fork下哈!

That's all !

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,513评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,312评论 1 305
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 111,124评论 0 254
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,529评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,937评论 3 295
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,913评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,084评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,816评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,593评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,788评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,267评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,601评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,265评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,158评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,953评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,066评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,852评论 2 277

推荐阅读更多精彩内容