TextViewCompat.java revision bf14265885d1cb7ecd6db9b0109a8b033181747b
1/* 2 * Copyright (C) 2015 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 17package android.support.v4.widget; 18 19import android.graphics.drawable.Drawable; 20import android.os.Build; 21import android.support.annotation.DrawableRes; 22import android.support.annotation.NonNull; 23import android.support.annotation.Nullable; 24import android.support.annotation.StyleRes; 25import android.widget.TextView; 26 27/** 28 * Helper for accessing features in {@link TextView} introduced after API level 29 * 4 in a backwards compatible fashion. 30 */ 31public final class TextViewCompat { 32 33 // Hide constructor 34 private TextViewCompat() {} 35 36 interface TextViewCompatImpl { 37 void setCompoundDrawablesRelative(@NonNull TextView textView, 38 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, 39 @Nullable Drawable bottom); 40 void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView, 41 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, 42 @Nullable Drawable bottom); 43 void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView, 44 @DrawableRes int start, @DrawableRes int top, @DrawableRes int end, 45 @DrawableRes int bottom); 46 int getMaxLines(TextView textView); 47 int getMinLines(TextView textView); 48 void setTextAppearance(@NonNull TextView textView, @StyleRes int resId); 49 Drawable[] getCompoundDrawablesRelative(@NonNull TextView textView); 50 } 51 52 static class BaseTextViewCompatImpl implements TextViewCompatImpl { 53 @Override 54 public void setCompoundDrawablesRelative(@NonNull TextView textView, 55 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, 56 @Nullable Drawable bottom) { 57 textView.setCompoundDrawables(start, top, end, bottom); 58 } 59 60 @Override 61 public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView, 62 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, 63 @Nullable Drawable bottom) { 64 textView.setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom); 65 } 66 67 @Override 68 public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView, 69 @DrawableRes int start, @DrawableRes int top, @DrawableRes int end, 70 @DrawableRes int bottom) { 71 textView.setCompoundDrawablesWithIntrinsicBounds(start, top, end, bottom); 72 } 73 74 @Override 75 public int getMaxLines(TextView textView) { 76 return TextViewCompatGingerbread.getMaxLines(textView); 77 } 78 79 @Override 80 public int getMinLines(TextView textView) { 81 return TextViewCompatGingerbread.getMinLines(textView); 82 } 83 84 @Override 85 public void setTextAppearance(TextView textView, @StyleRes int resId) { 86 TextViewCompatGingerbread.setTextAppearance(textView, resId); 87 } 88 89 @Override 90 public Drawable[] getCompoundDrawablesRelative(@NonNull TextView textView) { 91 return TextViewCompatGingerbread.getCompoundDrawablesRelative(textView); 92 } 93 } 94 95 static class JbTextViewCompatImpl extends BaseTextViewCompatImpl { 96 @Override 97 public int getMaxLines(TextView textView) { 98 return TextViewCompatJb.getMaxLines(textView); 99 } 100 101 @Override 102 public int getMinLines(TextView textView) { 103 return TextViewCompatJb.getMinLines(textView); 104 } 105 } 106 107 static class JbMr1TextViewCompatImpl extends JbTextViewCompatImpl { 108 @Override 109 public void setCompoundDrawablesRelative(@NonNull TextView textView, 110 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, 111 @Nullable Drawable bottom) { 112 TextViewCompatJbMr1.setCompoundDrawablesRelative(textView, start, top, end, bottom); 113 } 114 115 @Override 116 public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView, 117 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, 118 @Nullable Drawable bottom) { 119 TextViewCompatJbMr1.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, 120 start, top, end, bottom); 121 } 122 123 @Override 124 public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView, 125 @DrawableRes int start, @DrawableRes int top, @DrawableRes int end, 126 @DrawableRes int bottom) { 127 TextViewCompatJbMr1.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, 128 start, top, end, bottom); 129 } 130 131 @Override 132 public Drawable[] getCompoundDrawablesRelative(@NonNull TextView textView) { 133 return TextViewCompatJbMr1.getCompoundDrawablesRelative(textView); 134 } 135 } 136 137 static class JbMr2TextViewCompatImpl extends JbMr1TextViewCompatImpl { 138 @Override 139 public void setCompoundDrawablesRelative(@NonNull TextView textView, 140 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, 141 @Nullable Drawable bottom) { 142 TextViewCompatJbMr2.setCompoundDrawablesRelative(textView, start, top, end, bottom); 143 } 144 145 @Override 146 public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView, 147 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, 148 @Nullable Drawable bottom) { 149 TextViewCompatJbMr2 150 .setCompoundDrawablesRelativeWithIntrinsicBounds(textView, start, top, end, 151 bottom); 152 } 153 154 @Override 155 public void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView, 156 @DrawableRes int start, @DrawableRes int top, @DrawableRes int end, 157 @DrawableRes int bottom) { 158 TextViewCompatJbMr2.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, 159 start, top, end, bottom); 160 } 161 } 162 163 static class Api23TextViewCompatImpl extends JbMr2TextViewCompatImpl { 164 @Override 165 public void setTextAppearance(@NonNull TextView textView, @StyleRes int resId) { 166 TextViewCompatApi23.setTextAppearance(textView, resId); 167 } 168 } 169 170 static final TextViewCompatImpl IMPL; 171 172 static { 173 final int version = Build.VERSION.SDK_INT; 174 if (version >= 23) { 175 IMPL = new Api23TextViewCompatImpl(); 176 } else if (version >= 18) { 177 IMPL = new JbMr2TextViewCompatImpl(); 178 } else if (version >= 17) { 179 IMPL = new JbMr1TextViewCompatImpl(); 180 } else if (version >= 16) { 181 IMPL = new JbTextViewCompatImpl(); 182 } else { 183 IMPL = new BaseTextViewCompatImpl(); 184 } 185 } 186 187 /** 188 * Sets the Drawables (if any) to appear to the start of, above, to the end 189 * of, and below the text. Use {@code null} if you do not want a Drawable 190 * there. The Drawables must already have had {@link Drawable#setBounds} 191 * called. 192 * <p/> 193 * Calling this method will overwrite any Drawables previously set using 194 * {@link TextView#setCompoundDrawables} or related methods. 195 * 196 * @param textView The TextView against which to invoke the method. 197 * @attr name android:drawableStart 198 * @attr name android:drawableTop 199 * @attr name android:drawableEnd 200 * @attr name android:drawableBottom 201 */ 202 public static void setCompoundDrawablesRelative(@NonNull TextView textView, 203 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, 204 @Nullable Drawable bottom) { 205 IMPL.setCompoundDrawablesRelative(textView, start, top, end, bottom); 206 } 207 208 /** 209 * Sets the Drawables (if any) to appear to the start of, above, to the end 210 * of, and below the text. Use {@code null} if you do not want a Drawable 211 * there. The Drawables' bounds will be set to their intrinsic bounds. 212 * <p/> 213 * Calling this method will overwrite any Drawables previously set using 214 * {@link TextView#setCompoundDrawables} or related methods. 215 * 216 * @param textView The TextView against which to invoke the method. 217 * @attr name android:drawableStart 218 * @attr name android:drawableTop 219 * @attr name android:drawableEnd 220 * @attr name android:drawableBottom 221 */ 222 public static void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView, 223 @Nullable Drawable start, @Nullable Drawable top, @Nullable Drawable end, 224 @Nullable Drawable bottom) { 225 IMPL.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, start, top, end, bottom); 226 } 227 228 /** 229 * Sets the Drawables (if any) to appear to the start of, above, to the end 230 * of, and below the text. Use 0 if you do not want a Drawable there. The 231 * Drawables' bounds will be set to their intrinsic bounds. 232 * <p/> 233 * Calling this method will overwrite any Drawables previously set using 234 * {@link TextView#setCompoundDrawables} or related methods. 235 * 236 * @param textView The TextView against which to invoke the method. 237 * @param start Resource identifier of the start Drawable. 238 * @param top Resource identifier of the top Drawable. 239 * @param end Resource identifier of the end Drawable. 240 * @param bottom Resource identifier of the bottom Drawable. 241 * @attr name android:drawableStart 242 * @attr name android:drawableTop 243 * @attr name android:drawableEnd 244 * @attr name android:drawableBottom 245 */ 246 public static void setCompoundDrawablesRelativeWithIntrinsicBounds(@NonNull TextView textView, 247 @DrawableRes int start, @DrawableRes int top, @DrawableRes int end, 248 @DrawableRes int bottom) { 249 IMPL.setCompoundDrawablesRelativeWithIntrinsicBounds(textView, start, top, end, bottom); 250 } 251 252 /** 253 * Returns the maximum number of lines displayed in the given TextView, or -1 if the maximum 254 * height was set in pixels instead. 255 */ 256 public static int getMaxLines(@NonNull TextView textView) { 257 return IMPL.getMaxLines(textView); 258 } 259 260 /** 261 * Returns the minimum number of lines displayed in the given TextView, or -1 if the minimum 262 * height was set in pixels instead. 263 */ 264 public static int getMinLines(@NonNull TextView textView) { 265 return IMPL.getMinLines(textView); 266 } 267 268 /** 269 * Sets the text appearance from the specified style resource. 270 * <p> 271 * Use a framework-defined {@code TextAppearance} style like 272 * {@link android.R.style#TextAppearance_Material_Body1 @android:style/TextAppearance.Material.Body1}. 273 * 274 * @param textView The TextView against which to invoke the method. 275 * @param resId The resource identifier of the style to apply. 276 */ 277 public static void setTextAppearance(@NonNull TextView textView, @StyleRes int resId) { 278 IMPL.setTextAppearance(textView, resId); 279 } 280 281 /** 282 * Returns drawables for the start, top, end, and bottom borders from the given text view. 283 */ 284 public static Drawable[] getCompoundDrawablesRelative(@NonNull TextView textView) { 285 return IMPL.getCompoundDrawablesRelative(textView); 286 } 287} 288