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.os.Build; 21 import android.view.ViewGroup; 22 23 /** 24 * Helper for accessing API features in 25 * {@link android.view.ViewGroup.MarginLayoutParams MarginLayoutParams} added after API 4. 26 */ 27 public class MarginLayoutParamsCompat { 28 interface MarginLayoutParamsCompatImpl { getMarginStart(ViewGroup.MarginLayoutParams lp)29 int getMarginStart(ViewGroup.MarginLayoutParams lp); getMarginEnd(ViewGroup.MarginLayoutParams lp)30 int getMarginEnd(ViewGroup.MarginLayoutParams lp); setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart)31 void setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart); setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd)32 void setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd); isMarginRelative(ViewGroup.MarginLayoutParams lp)33 boolean isMarginRelative(ViewGroup.MarginLayoutParams lp); getLayoutDirection(ViewGroup.MarginLayoutParams lp)34 int getLayoutDirection(ViewGroup.MarginLayoutParams lp); setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection)35 void setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection); resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection)36 void resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection); 37 } 38 39 static class MarginLayoutParamsCompatImplBase implements MarginLayoutParamsCompatImpl { 40 41 @Override getMarginStart(ViewGroup.MarginLayoutParams lp)42 public int getMarginStart(ViewGroup.MarginLayoutParams lp) { 43 return lp.leftMargin; 44 } 45 46 @Override getMarginEnd(ViewGroup.MarginLayoutParams lp)47 public int getMarginEnd(ViewGroup.MarginLayoutParams lp) { 48 return lp.rightMargin; 49 } 50 51 @Override setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart)52 public void setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart) { 53 lp.leftMargin = marginStart; 54 } 55 56 @Override setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd)57 public void setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd) { 58 lp.rightMargin = marginEnd; 59 } 60 61 @Override isMarginRelative(ViewGroup.MarginLayoutParams lp)62 public boolean isMarginRelative(ViewGroup.MarginLayoutParams lp) { 63 return false; 64 } 65 66 @Override getLayoutDirection(ViewGroup.MarginLayoutParams lp)67 public int getLayoutDirection(ViewGroup.MarginLayoutParams lp) { 68 return ViewCompat.LAYOUT_DIRECTION_LTR; 69 } 70 71 @Override setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection)72 public void setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection) { 73 // No-op 74 } 75 76 @Override resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection)77 public void resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection) { 78 // No-op 79 } 80 } 81 82 static class MarginLayoutParamsCompatImplJbMr1 implements MarginLayoutParamsCompatImpl { 83 84 @Override getMarginStart(ViewGroup.MarginLayoutParams lp)85 public int getMarginStart(ViewGroup.MarginLayoutParams lp) { 86 return MarginLayoutParamsCompatJellybeanMr1.getMarginStart(lp); 87 } 88 89 @Override getMarginEnd(ViewGroup.MarginLayoutParams lp)90 public int getMarginEnd(ViewGroup.MarginLayoutParams lp) { 91 return MarginLayoutParamsCompatJellybeanMr1.getMarginEnd(lp); 92 } 93 94 @Override setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart)95 public void setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart) { 96 MarginLayoutParamsCompatJellybeanMr1.setMarginStart(lp, marginStart); 97 } 98 99 @Override setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd)100 public void setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd) { 101 MarginLayoutParamsCompatJellybeanMr1.setMarginEnd(lp, marginEnd); 102 } 103 104 @Override isMarginRelative(ViewGroup.MarginLayoutParams lp)105 public boolean isMarginRelative(ViewGroup.MarginLayoutParams lp) { 106 return MarginLayoutParamsCompatJellybeanMr1.isMarginRelative(lp); 107 } 108 109 @Override getLayoutDirection(ViewGroup.MarginLayoutParams lp)110 public int getLayoutDirection(ViewGroup.MarginLayoutParams lp) { 111 return MarginLayoutParamsCompatJellybeanMr1.getLayoutDirection(lp); 112 } 113 114 @Override setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection)115 public void setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection) { 116 MarginLayoutParamsCompatJellybeanMr1.setLayoutDirection(lp, layoutDirection); 117 } 118 119 @Override resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection)120 public void resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection) { 121 MarginLayoutParamsCompatJellybeanMr1.resolveLayoutDirection(lp, layoutDirection); 122 } 123 } 124 125 static final MarginLayoutParamsCompatImpl IMPL; 126 static { 127 final int version = Build.VERSION.SDK_INT; 128 if (version >= 17) { // jb-mr1 129 IMPL = new MarginLayoutParamsCompatImplJbMr1(); 130 } else { 131 IMPL = new MarginLayoutParamsCompatImplBase(); 132 } 133 } 134 135 /** 136 * Get the relative starting margin that was set. 137 * 138 * <p>On platform versions supporting bidirectional text and layouts 139 * this value will be resolved into the LayoutParams object's left or right 140 * margin as appropriate when the associated View is attached to a window 141 * or when the layout direction of that view changes.</p> 142 * 143 * @param lp LayoutParams to query 144 * @return the margin along the starting edge in pixels 145 */ getMarginStart(ViewGroup.MarginLayoutParams lp)146 public static int getMarginStart(ViewGroup.MarginLayoutParams lp) { 147 return IMPL.getMarginStart(lp); 148 } 149 150 /** 151 * Get the relative ending margin that was set. 152 * 153 * <p>On platform versions supporting bidirectional text and layouts 154 * this value will be resolved into the LayoutParams object's left or right 155 * margin as appropriate when the associated View is attached to a window 156 * or when the layout direction of that view changes.</p> 157 * 158 * @param lp LayoutParams to query 159 * @return the margin along the ending edge in pixels 160 */ getMarginEnd(ViewGroup.MarginLayoutParams lp)161 public static int getMarginEnd(ViewGroup.MarginLayoutParams lp) { 162 return IMPL.getMarginEnd(lp); 163 } 164 165 /** 166 * Set the relative start margin. 167 * 168 * <p>On platform versions supporting bidirectional text and layouts 169 * this value will be resolved into the LayoutParams object's left or right 170 * margin as appropriate when the associated View is attached to a window 171 * or when the layout direction of that view changes.</p> 172 * 173 * @param lp LayoutParams to query 174 * @param marginStart the desired start margin in pixels 175 */ setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart)176 public static void setMarginStart(ViewGroup.MarginLayoutParams lp, int marginStart) { 177 IMPL.setMarginStart(lp, marginStart); 178 } 179 180 /** 181 * Set the relative end margin. 182 * 183 * <p>On platform versions supporting bidirectional text and layouts 184 * this value will be resolved into the LayoutParams object's left or right 185 * margin as appropriate when the associated View is attached to a window 186 * or when the layout direction of that view changes.</p> 187 * 188 * @param lp LayoutParams to query 189 * @param marginEnd the desired end margin in pixels 190 */ setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd)191 public static void setMarginEnd(ViewGroup.MarginLayoutParams lp, int marginEnd) { 192 IMPL.setMarginEnd(lp, marginEnd); 193 } 194 195 /** 196 * Check if margins are relative. 197 * 198 * @return true if either marginStart or marginEnd has been set. 199 */ isMarginRelative(ViewGroup.MarginLayoutParams lp)200 public static boolean isMarginRelative(ViewGroup.MarginLayoutParams lp) { 201 return IMPL.isMarginRelative(lp); 202 } 203 204 /** 205 * Retuns the layout direction. Can be either {@link ViewCompat#LAYOUT_DIRECTION_LTR} or 206 * {@link ViewCompat#LAYOUT_DIRECTION_RTL}. 207 * 208 * @return the layout direction. 209 */ getLayoutDirection(ViewGroup.MarginLayoutParams lp)210 public static int getLayoutDirection(ViewGroup.MarginLayoutParams lp) { 211 return IMPL.getLayoutDirection(lp); 212 } 213 214 /** 215 * Set the layout direction. 216 * 217 * @param layoutDirection the layout direction. 218 * Should be either {@link ViewCompat#LAYOUT_DIRECTION_LTR} 219 * or {@link ViewCompat#LAYOUT_DIRECTION_RTL}. 220 */ setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection)221 public static void setLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection) { 222 IMPL.setLayoutDirection(lp, layoutDirection); 223 } 224 225 /** 226 * This will be called by {@link android.view.View#requestLayout()}. Left and Right margins 227 * may be overridden depending on layout direction. 228 */ resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, int layoutDirection)229 public static void resolveLayoutDirection(ViewGroup.MarginLayoutParams lp, 230 int layoutDirection) { 231 IMPL.resolveLayoutDirection(lp, layoutDirection); 232 } 233 } 234