• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 static com.android.documentsui.util.FlagUtils.isUseMaterial3FlagEnabled;
20 
21 import android.content.Context;
22 import android.os.Bundle;
23 import android.util.AttributeSet;
24 import android.widget.LinearLayout;
25 
26 import androidx.annotation.IntDef;
27 import androidx.fragment.app.FragmentTransaction;
28 
29 import com.android.documentsui.R;
30 import com.android.documentsui.base.Shared;
31 
32 import java.lang.annotation.Retention;
33 import java.lang.annotation.RetentionPolicy;
34 import java.util.ArrayList;
35 
36 /**
37  * This class exists solely to support animated transition of our directory fragment.
38  * The structure of this class is tightly coupled with the static animations defined in
39  * res/animator, specifically the "position" property referenced by
40  * res/animator/dir_{enter,leave}.xml.
41  */
42 public class AnimationView extends LinearLayout {
43 
44     @IntDef(flag = true, value = {
45             ANIM_NONE,
46             ANIM_SIDE,
47             ANIM_LEAVE,
48             ANIM_ENTER
49     })
50     @Retention(RetentionPolicy.SOURCE)
51     public @interface AnimationType {}
52     public static final int ANIM_NONE = 1;
53     public static final int ANIM_SIDE = 2;
54     public static final int ANIM_LEAVE = 3;
55     public static final int ANIM_ENTER = 4;
56 
57     private final ArrayList<OnSizeChangedListener> mOnSizeChangedListeners = new ArrayList<>();
58 
59     private float mPosition = 0f;
60 
61     // The distance the animation will cover...currently matches the height of the
62     // content area.
63     private int mSpan;
64 
AnimationView(Context context)65     public AnimationView(Context context) {
66         super(context);
67     }
68 
AnimationView(Context context, AttributeSet attrs)69     public AnimationView(Context context, AttributeSet attrs) {
70         super(context, attrs);
71     }
72 
73     /**
74      * A listener of the onSizeChanged method.
75      */
76     public interface OnSizeChangedListener {
77         /**
78          * Called on the View's onSizeChanged.
79          */
onSizeChanged()80         void onSizeChanged();
81     }
82 
83     /**
84      * Adds a listener of the onSizeChanged method.
85      */
addOnSizeChangedListener(OnSizeChangedListener listener)86     public void addOnSizeChangedListener(OnSizeChangedListener listener) {
87         if (isUseMaterial3FlagEnabled()) {
88             mOnSizeChangedListeners.add(listener);
89         }
90     }
91 
92     /**
93      * Removes a listener of the onSizeChanged method.
94      */
removeOnSizeChangedListener(OnSizeChangedListener listener)95     public void removeOnSizeChangedListener(OnSizeChangedListener listener) {
96         if (isUseMaterial3FlagEnabled()) {
97             mOnSizeChangedListeners.remove(listener);
98         }
99     }
100 
101 
102     @Override
onSizeChanged(int w, int h, int oldw, int oldh)103     protected void onSizeChanged(int w, int h, int oldw, int oldh) {
104         super.onSizeChanged(w, h, oldw, oldh);
105         mSpan = h;
106         setPosition(mPosition);
107         if (isUseMaterial3FlagEnabled()) {
108             for (int i = mOnSizeChangedListeners.size() - 1; i >= 0; --i) {
109                 mOnSizeChangedListeners.get(i).onSizeChanged();
110             }
111         }
112     }
113 
getPosition()114     public float getPosition() {
115         return mPosition;
116     }
117 
setPosition(float position)118     public void setPosition(float position) {
119         mPosition = position;
120         // Warning! If we ever decide to switch this to setX (slide left/right)
121         // please remember to add RLT variations of the animations under res/animator-ldrtl.
122         setY((mSpan > 0) ? (mPosition * mSpan) : 0);
123 
124         if (mPosition != 0) {
125             setTranslationZ(getResources().getDimensionPixelSize(R.dimen.dir_elevation));
126         } else {
127             setTranslationZ(0);
128         }
129     }
130 
131     /**
132      * Configures custom animations on the transaction according to the specified
133      * @AnimationType.
134      */
setupAnimations( FragmentTransaction ft, @AnimationType int anim, Bundle args)135     static void setupAnimations(
136             FragmentTransaction ft, @AnimationType int anim, Bundle args) {
137         switch (anim) {
138             case AnimationView.ANIM_SIDE:
139                 args.putBoolean(Shared.EXTRA_IGNORE_STATE, true);
140                 break;
141             case AnimationView.ANIM_ENTER:
142                 // TODO: Document which behavior is being tailored
143                 //     by passing this bit. Remove if possible.
144                 args.putBoolean(Shared.EXTRA_IGNORE_STATE, true);
145                 ft.setCustomAnimations(R.animator.dir_enter, R.animator.fade_out);
146                 break;
147             case AnimationView.ANIM_LEAVE:
148                 ft.setCustomAnimations(R.animator.fade_in, R.animator.dir_leave);
149                 break;
150         }
151     }
152 }
153