美文网首页Android日记andnroidAndroid之界面
Android开源之ILayoutAnimationContro

Android开源之ILayoutAnimationContro

作者: 幻海流心 | 来源:发表于2017-03-13 00:09 被阅读2083次

    直接上动图:

    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 !

    相关文章

      网友评论

      • AWeiLoveAndroid:看少年 思路清晰 骨骼惊奇 实乃可造之材:joy:
      • 布谷鸟也会编程:老哥你好~如果我用RecyclerView使用,但是每次改变数据也想用动画,是每次都要notify的时候都重新设置一下吗?
        幻海流心:@布谷鸟也会编程 不建议这样,我觉得,布局动画展示一次就够了,你如果真的需要可以试试,我没试过
      • JJGO:很好!很强势,有用PullToRefreshListView的朋友要转换为ListView才可以使用。
      • 5aa43c7d9fd5:已star,留着备用
        幻海流心:@默小二 :grin:
      • 1cf2c90a5564::+1: 老哥稳,眼前一亮的感觉!
        幻海流心: @Yaren_Android 那我就承认了😂
      • ProgrammerOz:老哥,我是第一个star的,求你的项目不坑哈
        幻海流心:@ProgrammerOz 一共只有2个文件,还需要引用依赖的话有点没必要了
        ProgrammerOz:@幻海流心 只能通过下载引入项目么?有没有依赖的方式?
        幻海流心:O(∩_∩)O~ 多谢支持!你可以看看代码,使用起来应该很方便。你想定制新的执行顺序,在工具类里面新写一个方法,然后在Controller里面对应一下就好!

      本文标题:Android开源之ILayoutAnimationContro

      本文链接:https://www.haomeiwen.com/subject/cxgxnttx.html