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 18package android.support.v4.view; 19 20import android.graphics.Rect; 21import android.os.Build; 22import android.view.Gravity; 23 24/** 25 * Compatibility shim for accessing newer functionality from {@link android.view.Gravity}. 26 */ 27public class GravityCompat { 28 interface GravityCompatImpl { 29 int getAbsoluteGravity(int gravity, int layoutDirection); 30 void apply(int gravity, int w, int h, Rect container, Rect outRect, int layoutDirection); 31 void apply(int gravity, int w, int h, Rect container, int xAdj, int yAdj, 32 Rect outRect, int layoutDirection); 33 void applyDisplay(int gravity, Rect display, Rect inoutObj, int layoutDirection); 34 } 35 36 static class GravityCompatImplBase implements GravityCompatImpl { 37 @Override 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 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 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 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 64 public int getAbsoluteGravity(int gravity, int layoutDirection) { 65 return GravityCompatJellybeanMr1.getAbsoluteGravity(gravity, layoutDirection); 66 } 67 68 @Override 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 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 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 */ 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 */ 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 */ 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 */ 200 public static int getAbsoluteGravity(int gravity, int layoutDirection) { 201 return IMPL.getAbsoluteGravity(gravity, layoutDirection); 202 } 203} 204