Android開源:1行代碼讓你的ViewGroup擁有華麗的布局動畫

DenWJG 7年前發布 | 7K 次閱讀 安卓開發 開源 Android開發 移動開發

直接上動圖:

ILayoutAnimationController錄屏.gif

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)方法無效!

 

 

 本文由用戶 DenWJG 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!