• 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 
18 package android.support.v4.view;
19 
20 import android.graphics.Rect;
21 import android.os.Build;
22 import android.view.Gravity;
23 
24 /**
25  * Compatibility shim for accessing newer functionality from {@link android.view.Gravity}.
26  */
27 public class GravityCompat {
28     interface GravityCompatImpl {
getAbsoluteGravity(int gravity, int layoutDirection)29         int getAbsoluteGravity(int gravity, int layoutDirection);
apply(int gravity, int w, int h, Rect container, Rect outRect, int layoutDirection)30         void apply(int gravity, int w, int h, Rect container, Rect outRect, int layoutDirection);
apply(int gravity, int w, int h, Rect container, int xAdj, int yAdj, Rect outRect, int layoutDirection)31         void apply(int gravity, int w, int h, Rect container, int xAdj, int yAdj,
32                 Rect outRect, int layoutDirection);
applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection)33         void applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection);
34     }
35 
36     static class GravityCompatImplBase implements GravityCompatImpl {
37         @Override
getAbsoluteGravity(int gravity, int layoutDirection)38         public int getAbsoluteGravity(int gravity, int layoutDirection) {
39             // Just strip off the relative bit to get LEFT/RIGHT.
40             return gravity & ~RELATIVE_LAYOUT_DIRECTION;
41         }
42 
43         @Override
apply(int gravity, int w, int h, Rect container, Rect outRect, int layoutDirection)44         public void apply(int gravity, int w, int h, Rect container, Rect outRect,
45                 int layoutDirection) {
46             Gravity.apply(gravity, w, h, container, outRect);
47         }
48 
49         @Override
apply(int gravity, int w, int h, Rect container, int xAdj, int yAdj, Rect outRect, int layoutDirection)50         public void apply(int gravity, int w, int h, Rect container, int xAdj, int yAdj,
51                 Rect outRect, int layoutDirection) {
52             Gravity.apply(gravity, w, h, container, xAdj, yAdj, outRect);
53         }
54 
55         @Override
applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection)56         public void applyDisplay(int gravity, Rect display, Rect inoutObj,
57                 int layoutDirection) {
58             Gravity.applyDisplay(gravity, display, inoutObj);
59         }
60     }
61 
62     static class GravityCompatImplJellybeanMr1 implements GravityCompatImpl {
63         @Override
getAbsoluteGravity(int gravity, int layoutDirection)64         public int getAbsoluteGravity(int gravity, int layoutDirection) {
65             return GravityCompatJellybeanMr1.getAbsoluteGravity(gravity, layoutDirection);
66         }
67 
68         @Override
apply(int gravity, int w, int h, Rect container, Rect outRect, int layoutDirection)69         public void apply(int gravity, int w, int h, Rect container, Rect outRect,
70                 int layoutDirection) {
71             GravityCompatJellybeanMr1.apply(gravity, w, h, container, outRect, layoutDirection);
72         }
73 
74         @Override
apply(int gravity, int w, int h, Rect container, int xAdj, int yAdj, Rect outRect, int layoutDirection)75         public void apply(int gravity, int w, int h, Rect container, int xAdj, int yAdj,
76                 Rect outRect, int layoutDirection) {
77             GravityCompatJellybeanMr1.apply(gravity, w, h, container, xAdj, yAdj, outRect,
78                     layoutDirection);
79         }
80 
81         @Override
applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection)82         public void applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection) {
83             GravityCompatJellybeanMr1.applyDisplay(gravity, display, inoutObj, layoutDirection);
84         }
85     }
86 
87     static final GravityCompatImpl IMPL;
88     static {
89         final int version = Build.VERSION.SDK_INT;
90         if (version >= 17) {
91             IMPL = new GravityCompatImplJellybeanMr1();
92         } else {
93             IMPL = new GravityCompatImplBase();
94         }
95     }
96 
97     /** Raw bit controlling whether the layout direction is relative or not (START/END instead of
98      * absolute LEFT/RIGHT).
99      */
100     public static final int RELATIVE_LAYOUT_DIRECTION = 0x00800000;
101 
102     /** Push object to x-axis position at the start of its container, not changing its size. */
103     public static final int START = RELATIVE_LAYOUT_DIRECTION | Gravity.LEFT;
104 
105     /** Push object to x-axis position at the end of its container, not changing its size. */
106     public static final int END = RELATIVE_LAYOUT_DIRECTION | Gravity.RIGHT;
107 
108     /**
109      * Binary mask for the horizontal gravity and script specific direction bit.
110      */
111     public static final int RELATIVE_HORIZONTAL_GRAVITY_MASK = START | END;
112 
113     /**
114      * Apply a gravity constant to an object and take care if layout direction is RTL or not.
115      *
116      * @param gravity The desired placement of the object, as defined by the
117      *                constants in this class.
118      * @param w The horizontal size of the object.
119      * @param h The vertical size of the object.
120      * @param container The frame of the containing space, in which the object
121      *                  will be placed.  Should be large enough to contain the
122      *                  width and height of the object.
123      * @param outRect Receives the computed frame of the object in its
124      *                container.
125      * @param layoutDirection The layout direction.
126      *
127      * @see ViewCompat#LAYOUT_DIRECTION_LTR
128      * @see ViewCompat#LAYOUT_DIRECTION_RTL
129      */
apply(int gravity, int w, int h, Rect container, Rect outRect, int layoutDirection)130     public static void apply(int gravity, int w, int h, Rect container,
131             Rect outRect, int layoutDirection) {
132         IMPL.apply(gravity, w, h, container, outRect, layoutDirection);
133     }
134 
135     /**
136      * Apply a gravity constant to an object.
137      *
138      * @param gravity The desired placement of the object, as defined by the
139      *                constants in this class.
140      * @param w The horizontal size of the object.
141      * @param h The vertical size of the object.
142      * @param container The frame of the containing space, in which the object
143      *                  will be placed.  Should be large enough to contain the
144      *                  width and height of the object.
145      * @param xAdj Offset to apply to the X axis.  If gravity is LEFT this
146      *             pushes it to the right; if gravity is RIGHT it pushes it to
147      *             the left; if gravity is CENTER_HORIZONTAL it pushes it to the
148      *             right or left; otherwise it is ignored.
149      * @param yAdj Offset to apply to the Y axis.  If gravity is TOP this pushes
150      *             it down; if gravity is BOTTOM it pushes it up; if gravity is
151      *             CENTER_VERTICAL it pushes it down or up; otherwise it is
152      *             ignored.
153      * @param outRect Receives the computed frame of the object in its
154      *                container.
155      * @param layoutDirection The layout direction.
156      *
157      * @see ViewCompat#LAYOUT_DIRECTION_LTR
158      * @see ViewCompat#LAYOUT_DIRECTION_RTL
159      */
apply(int gravity, int w, int h, Rect container, int xAdj, int yAdj, Rect outRect, int layoutDirection)160     public static void apply(int gravity, int w, int h, Rect container,
161             int xAdj, int yAdj, Rect outRect, int layoutDirection) {
162         IMPL.apply(gravity, w, h, container, xAdj, yAdj, outRect, layoutDirection);
163     }
164 
165     /**
166      * Apply additional gravity behavior based on the overall "display" that an
167      * object exists in.  This can be used after
168      * {@link android.view.Gravity#apply(int, int, int, Rect, int, int, Rect)} to place the object
169      * within a visible display.  By default this moves or clips the object
170      * to be visible in the display; the gravity flags
171      * {@link android.view.Gravity#DISPLAY_CLIP_HORIZONTAL} and
172      * {@link android.view.Gravity#DISPLAY_CLIP_VERTICAL} can be used to change this behavior.
173      *
174      * @param gravity Gravity constants to modify the placement within the
175      * display.
176      * @param display The rectangle of the display in which the object is
177      * being placed.
178      * @param inoutObj Supplies the current object position; returns with it
179      * modified if needed to fit in the display.
180      * @param layoutDirection The layout direction.
181      *
182      * @see ViewCompat#LAYOUT_DIRECTION_LTR
183      * @see ViewCompat#LAYOUT_DIRECTION_RTL
184      */
applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection)185     public static void applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection) {
186         IMPL.applyDisplay(gravity, display, inoutObj, layoutDirection);
187     }
188 
189     /**
190      * <p>Convert script specific gravity to absolute horizontal value.</p>
191      *
192      * if horizontal direction is LTR, then START will set LEFT and END will set RIGHT.
193      * if horizontal direction is RTL, then START will set RIGHT and END will set LEFT.
194      *
195      *
196      * @param gravity The gravity to convert to absolute (horizontal) values.
197      * @param layoutDirection The layout direction.
198      * @return gravity converted to absolute (horizontal) values.
199      */
getAbsoluteGravity(int gravity, int layoutDirection)200     public static int getAbsoluteGravity(int gravity, int layoutDirection) {
201         return IMPL.getAbsoluteGravity(gravity, layoutDirection);
202     }
203 }
204