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 
17 package com.android.documentsui.dirlist;
18 
19 import androidx.annotation.IntDef;
20 import androidx.fragment.app.FragmentTransaction;
21 
22 import android.content.Context;
23 import android.os.Bundle;
24 import android.util.AttributeSet;
25 import android.widget.LinearLayout;
26 
27 import com.android.documentsui.R;
28 import com.android.documentsui.base.Shared;
29 
30 import java.lang.annotation.Retention;
31 import java.lang.annotation.RetentionPolicy;
32 
33 /**
34  * This class exists solely to support animated transition of our directory fragment.
35  * The structure of this class is tightly coupled with the static animations defined in
36  * res/animator, specifically the "position" property referenced by
37  * res/animator/dir_{enter,leave}.xml.
38  */
39 public class AnimationView extends LinearLayout {
40 
41     @IntDef(flag = true, value = {
42             ANIM_NONE,
43             ANIM_SIDE,
44             ANIM_LEAVE,
45             ANIM_ENTER
46     })
47     @Retention(RetentionPolicy.SOURCE)
48     public @interface AnimationType {}
49     public static final int ANIM_NONE = 1;
50     public static final int ANIM_SIDE = 2;
51     public static final int ANIM_LEAVE = 3;
52     public static final int ANIM_ENTER = 4;
53 
54     private float mPosition = 0f;
55 
56     // The distance the animation will cover...currently matches the height of the
57     // content area.
58     private int mSpan;
59 
AnimationView(Context context)60     public AnimationView(Context context) {
61         super(context);
62     }
63 
AnimationView(Context context, AttributeSet attrs)64     public AnimationView(Context context, AttributeSet attrs) {
65         super(context, attrs);
66     }
67 
68     @Override
onSizeChanged(int w, int h, int oldw, int oldh)69     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
70         super.onSizeChanged(w, h, oldw, oldh);
71         mSpan = h;
72         setPosition(mPosition);
73     }
74 
getPosition()75     public float getPosition() {
76         return mPosition;
77     }
78 
setPosition(float position)79     public void setPosition(float position) {
80         mPosition = position;
81         // Warning! If we ever decide to switch this to setX (slide left/right)
82         // please remember to add RLT variations of the animations under res/animator-ldrtl.
83         setY((mSpan > 0) ? (mPosition * mSpan) : 0);
84 
85         if (mPosition != 0) {
86             setTranslationZ(getResources().getDimensionPixelSize(R.dimen.dir_elevation));
87         } else {
88             setTranslationZ(0);
89         }
90     }
91 
92     /**
93      * Configures custom animations on the transaction according to the specified
94      * @AnimationType.
95      */
setupAnimations( FragmentTransaction ft, @AnimationType int anim, Bundle args)96     static void setupAnimations(
97             FragmentTransaction ft, @AnimationType int anim, Bundle args) {
98         switch (anim) {
99             case AnimationView.ANIM_SIDE:
100                 args.putBoolean(Shared.EXTRA_IGNORE_STATE, true);
101                 break;
102             case AnimationView.ANIM_ENTER:
103                 // TODO: Document which behavior is being tailored
104                 //     by passing this bit. Remove if possible.
105                 args.putBoolean(Shared.EXTRA_IGNORE_STATE, true);
106                 ft.setCustomAnimations(R.animator.dir_enter, R.animator.fade_out);
107                 break;
108             case AnimationView.ANIM_LEAVE:
109                 ft.setCustomAnimations(R.animator.fade_in, R.animator.dir_leave);
110                 break;
111         }
112     }
113 }
114