Android开源:1行代码让你的ViewGroup拥有华丽的布局动画

DenWJG 8年前
   <p>直接上动图:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/749cf551e728aa5584387ab288523469.gif"></p>    <p style="text-align:center">ILayoutAnimationController录屏.gif</p>    <p>1:ILayoutAnimationController是什么?其实现思路是?</p>    <ul>     <li>LayoutAnimationController大家应该都了解,应用于ViewGroup实例的布局动画,但Android原生布局动画,仅支持顺序、倒序、随机3种动画执行顺序!</li>     <li>ILayoutAnimationController是一个自定义LayoutAnimationController,通过重写其 <strong>getTransformedIndex</strong> 方法, <strong>1行代码即可任意定制布局动画的执行顺序</strong> ,实现不同展示效果!</li>    </ul>    <p>2:使用方法:</p>    <p>方法一:1行代码直接搞定,以下两种方法任选其一</p>    <ul>     <li> <p>ILayoutAnimationController.setLayoutAnimation(@NonNull ViewGroup viewGroup, <strong>@NonNull Animation animation</strong> , float delay, @Nullable final IndexAlgorithm indexAlgorithm)</p> </li>     <li> <p>ILayoutAnimationController.setLayoutAnimation(@NonNull ViewGroup viewGroup, <strong>@AnimRes int animResId</strong> , float delay,@Nullable final IndexAlgorithm indexAlgorithm)</p> </li>    </ul>    <p>方法二:首先创建ILayoutAnimationController实例,然后将此实例作为参数为ViewGroup设置布局动画</p>    <ul>     <li> <p>ILayoutAnimationController.generateController(@NonNull Animation animation, float delay, @Nullable final IndexAlgorithm indexAlgorithm)</p> </li>     <li> <p>ViewGroup.setLayoutAnimation(LayoutAnimationController controller)</p> </li>    </ul>    <p>3:示例代码:</p>    <pre>  <code class="language-java">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);</code></pre>    <p>4:ILayoutAnimationController部分代码:</p>    <pre>  <code class="language-java">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;              }          }      }  **略**  }</code></pre>    <p>注意:</p>    <ul>     <li><em>使用ILayoutAnimationController获取的ILayoutAnimationController实例,调用setOrder(int order)方法无效!</em></li>    </ul>    <p> </p>    <p> </p>