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>