1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.documentsui.dirlist;
18
19import android.annotation.IntDef;
20import android.app.FragmentTransaction;
21import android.content.Context;
22import android.os.Bundle;
23import android.util.AttributeSet;
24import android.widget.LinearLayout;
25
26import com.android.documentsui.R;
27import com.android.documentsui.Shared;
28
29import java.lang.annotation.Retention;
30import java.lang.annotation.RetentionPolicy;
31
32/**
33 * This class exists solely to support animated transition of our directory fragment.
34 * The structure of this class is tightly coupled with the static animations defined in
35 * res/animator, specifically the "position" property referenced by
36 * res/animator/dir_{enter,leave}.xml.
37 */
38public class AnimationView extends LinearLayout {
39
40    @IntDef(flag = true, value = {
41            ANIM_NONE,
42            ANIM_SIDE,
43            ANIM_LEAVE,
44            ANIM_ENTER
45    })
46    @Retention(RetentionPolicy.SOURCE)
47    public @interface AnimationType {}
48    public static final int ANIM_NONE = 1;
49    public static final int ANIM_SIDE = 2;
50    public static final int ANIM_LEAVE = 3;
51    public static final int ANIM_ENTER = 4;
52
53    private float mPosition = 0f;
54
55    // The distance the animation will cover...currently matches the height of the
56    // content area.
57    private int mSpan;
58
59    public AnimationView(Context context) {
60        super(context);
61    }
62
63    public AnimationView(Context context, AttributeSet attrs) {
64        super(context, attrs);
65    }
66
67    @Override
68    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
69        super.onSizeChanged(w, h, oldw, oldh);
70        mSpan = h;
71        setPosition(mPosition);
72    }
73
74    public float getPosition() {
75        return mPosition;
76    }
77
78    public void setPosition(float position) {
79        mPosition = position;
80        // Warning! If we ever decide to switch this to setX (slide left/right)
81        // please remember to add RLT variations of the animations under res/animator-ldrtl.
82        setY((mSpan > 0) ? (mPosition * mSpan) : 0);
83
84        if (mPosition != 0) {
85            setTranslationZ(getResources().getDimensionPixelSize(R.dimen.dir_elevation));
86        } else {
87            setTranslationZ(0);
88        }
89    }
90
91    /**
92     * Configures custom animations on the transaction according to the specified
93     * @AnimationType.
94     */
95    static void setupAnimations(
96            FragmentTransaction ft, @AnimationType int anim, Bundle args) {
97        switch (anim) {
98            case AnimationView.ANIM_SIDE:
99                args.putBoolean(Shared.EXTRA_IGNORE_STATE, true);
100                break;
101            case AnimationView.ANIM_ENTER:
102                // TODO: Document which behavior is being tailored
103                //     by passing this bit. Remove if possible.
104                args.putBoolean(Shared.EXTRA_IGNORE_STATE, true);
105                ft.setCustomAnimations(R.animator.dir_enter, R.animator.fade_out);
106                break;
107            case AnimationView.ANIM_LEAVE:
108                ft.setCustomAnimations(R.animator.fade_in, R.animator.dir_leave);
109                break;
110        }
111    }
112}
113