• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 android.view.animation;
18 
19 import android.content.Context;
20 import android.content.res.TypedArray;
21 import android.graphics.Insets;
22 import android.util.AttributeSet;
23 import android.view.WindowInsets;
24 
25 /**
26  * An animation that controls the outset of an object.
27  *
28  * @hide
29  */
30 public class ExtendAnimation extends Animation {
31     protected Insets mFromInsets = Insets.NONE;
32     protected Insets mToInsets = Insets.NONE;
33 
34     private int mFromLeftType = ABSOLUTE;
35     private int mFromTopType = ABSOLUTE;
36     private int mFromRightType = ABSOLUTE;
37     private int mFromBottomType = ABSOLUTE;
38 
39     private int mToLeftType = ABSOLUTE;
40     private int mToTopType = ABSOLUTE;
41     private int mToRightType = ABSOLUTE;
42     private int mToBottomType = ABSOLUTE;
43 
44     private float mFromLeftValue;
45     private float mFromTopValue;
46     private float mFromRightValue;
47     private float mFromBottomValue;
48 
49     private float mToLeftValue;
50     private float mToTopValue;
51     private float mToRightValue;
52     private float mToBottomValue;
53 
54     /**
55      * Constructor used when an ExtendAnimation is loaded from a resource.
56      *
57      * @param context Application context to use
58      * @param attrs Attribute set from which to read values
59      */
ExtendAnimation(Context context, AttributeSet attrs)60     public ExtendAnimation(Context context, AttributeSet attrs) {
61         super(context, attrs);
62 
63         TypedArray a = context.obtainStyledAttributes(attrs,
64                 com.android.internal.R.styleable.ExtendAnimation);
65 
66         Description d = Description.parseValue(a.peekValue(
67                 com.android.internal.R.styleable.ExtendAnimation_fromExtendLeft), context);
68         mFromLeftType = d.type;
69         mFromLeftValue = d.value;
70 
71         d = Description.parseValue(a.peekValue(
72                 com.android.internal.R.styleable.ExtendAnimation_fromExtendTop), context);
73         mFromTopType = d.type;
74         mFromTopValue = d.value;
75 
76         d = Description.parseValue(a.peekValue(
77                 com.android.internal.R.styleable.ExtendAnimation_fromExtendRight), context);
78         mFromRightType = d.type;
79         mFromRightValue = d.value;
80 
81         d = Description.parseValue(a.peekValue(
82                 com.android.internal.R.styleable.ExtendAnimation_fromExtendBottom), context);
83         mFromBottomType = d.type;
84         mFromBottomValue = d.value;
85 
86 
87         d = Description.parseValue(a.peekValue(
88                 com.android.internal.R.styleable.ExtendAnimation_toExtendLeft), context);
89         mToLeftType = d.type;
90         mToLeftValue = d.value;
91 
92         d = Description.parseValue(a.peekValue(
93                 com.android.internal.R.styleable.ExtendAnimation_toExtendTop), context);
94         mToTopType = d.type;
95         mToTopValue = d.value;
96 
97         d = Description.parseValue(a.peekValue(
98                 com.android.internal.R.styleable.ExtendAnimation_toExtendRight), context);
99         mToRightType = d.type;
100         mToRightValue = d.value;
101 
102         d = Description.parseValue(a.peekValue(
103                 com.android.internal.R.styleable.ExtendAnimation_toExtendBottom), context);
104         mToBottomType = d.type;
105         mToBottomValue = d.value;
106 
107         a.recycle();
108     }
109 
110     /**
111      * Constructor to use when building an ExtendAnimation from code
112      *
113      * @param fromInsets the insets to animate from
114      * @param toInsets the insets to animate to
115      */
ExtendAnimation(Insets fromInsets, Insets toInsets)116     public ExtendAnimation(Insets fromInsets, Insets toInsets) {
117         if (fromInsets == null || toInsets == null) {
118             throw new RuntimeException("Expected non-null animation outsets");
119         }
120         mFromLeftValue = -fromInsets.left;
121         mFromTopValue = -fromInsets.top;
122         mFromRightValue = -fromInsets.right;
123         mFromBottomValue = -fromInsets.bottom;
124 
125         mToLeftValue = -toInsets.left;
126         mToTopValue = -toInsets.top;
127         mToRightValue = -toInsets.right;
128         mToBottomValue = -toInsets.bottom;
129     }
130 
131     /**
132      * Constructor to use when building an ExtendAnimation from code
133      */
ExtendAnimation(int fromL, int fromT, int fromR, int fromB, int toL, int toT, int toR, int toB)134     public ExtendAnimation(int fromL, int fromT, int fromR, int fromB,
135             int toL, int toT, int toR, int toB) {
136         this(Insets.of(-fromL, -fromT, -fromR, -fromB), Insets.of(-toL, -toT, -toR, -toB));
137     }
138 
139     @Override
applyTransformation(float it, Transformation tr)140     protected void applyTransformation(float it, Transformation tr) {
141         int l = mFromInsets.left + (int) ((mToInsets.left - mFromInsets.left) * it);
142         int t = mFromInsets.top + (int) ((mToInsets.top - mFromInsets.top) * it);
143         int r = mFromInsets.right + (int) ((mToInsets.right - mFromInsets.right) * it);
144         int b = mFromInsets.bottom + (int) ((mToInsets.bottom - mFromInsets.bottom) * it);
145         tr.setInsets(l, t, r, b);
146     }
147 
148     @Override
willChangeTransformationMatrix()149     public boolean willChangeTransformationMatrix() {
150         return false;
151     }
152 
153     /** @hide */
154     @Override
155     @WindowInsets.Side.InsetsSide
getExtensionEdges()156     public int getExtensionEdges() {
157         return (mFromInsets.left < 0 || mToInsets.left < 0 ?  WindowInsets.Side.LEFT : 0)
158             | (mFromInsets.right < 0 || mToInsets.right < 0 ?  WindowInsets.Side.RIGHT : 0)
159             | (mFromInsets.top < 0 || mToInsets.top < 0 ?  WindowInsets.Side.TOP : 0)
160             | (mFromInsets.bottom < 0 || mToInsets.bottom < 0 ? WindowInsets.Side.BOTTOM : 0);
161     }
162 
163     @Override
initialize(int width, int height, int parentWidth, int parentHeight)164     public void initialize(int width, int height, int parentWidth, int parentHeight) {
165         super.initialize(width, height, parentWidth, parentHeight);
166         // We remove any negative extension (i.e. positive insets) and set those to 0
167         mFromInsets = Insets.min(Insets.of(
168                     -(int) resolveSize(mFromLeftType, mFromLeftValue, width, parentWidth),
169                     -(int) resolveSize(mFromTopType, mFromTopValue, height, parentHeight),
170                     -(int) resolveSize(mFromRightType, mFromRightValue, width, parentWidth),
171                     -(int) resolveSize(mFromBottomType, mFromBottomValue, height, parentHeight)
172                 ), Insets.NONE);
173         mToInsets = Insets.min(Insets.of(
174                     -(int) resolveSize(mToLeftType, mToLeftValue, width, parentWidth),
175                     -(int) resolveSize(mToTopType, mToTopValue, height, parentHeight),
176                     -(int) resolveSize(mToRightType, mToRightValue, width, parentWidth),
177                     -(int) resolveSize(mToBottomType, mToBottomValue, height, parentHeight)
178                 ), Insets.NONE);
179     }
180 }
181