TextViewBindingAdapter.java revision fead9ca09b117136b35bc5bf137340a754f9eddd
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 */ 16package android.databinding.adapters; 17 18import android.databinding.BindingAdapter; 19import android.databinding.BindingMethod; 20import android.databinding.BindingMethods; 21import android.graphics.drawable.Drawable; 22import android.os.Build; 23import android.text.InputFilter; 24import android.text.InputType; 25import android.text.method.DialerKeyListener; 26import android.text.method.DigitsKeyListener; 27import android.text.method.KeyListener; 28import android.text.method.PasswordTransformationMethod; 29import android.text.method.TextKeyListener; 30import android.util.Log; 31import android.util.TypedValue; 32import android.widget.TextView; 33 34@BindingMethods({ 35 @BindingMethod(type = "android.widget.TextView", attribute = "android:autoLink", method = "setAutoLinkMask"), 36 @BindingMethod(type = "android.widget.TextView", attribute = "android:drawablePadding", method = "setCompoundDrawablePadding"), 37 @BindingMethod(type = "android.widget.TextView", attribute = "android:editorExtras", method = "setInputExtras"), 38 @BindingMethod(type = "android.widget.TextView", attribute = "android:inputType", method = "setRawInputType"), 39 @BindingMethod(type = "android.widget.TextView", attribute = "android:scrollHorizontally", method = "setHorizontallyScrolling"), 40 @BindingMethod(type = "android.widget.TextView", attribute = "android:textAllCaps", method = "setAllCaps"), 41 @BindingMethod(type = "android.widget.TextView", attribute = "android:textColorHighlight", method = "setHighlightColor"), 42 @BindingMethod(type = "android.widget.TextView", attribute = "android:textColorHint", method = "setHintTextColor"), 43 @BindingMethod(type = "android.widget.TextView", attribute = "android:textColorLink", method = "setLinkTextColor"), 44}) 45public class TextViewBindingAdapter { 46 47 private static final String TAG = "TextViewBindingAdapters"; 48 49 public static final int INTEGER = 0x01; 50 51 public static final int SIGNED = 0x03; 52 53 public static final int DECIMAL = 0x05; 54 55 @BindingAdapter("android:autoText") 56 public static void setAutoText(TextView view, boolean autoText) { 57 KeyListener listener = view.getKeyListener(); 58 59 TextKeyListener.Capitalize capitalize = TextKeyListener.Capitalize.NONE; 60 61 int inputType = listener != null ? listener.getInputType() : 0; 62 if ((inputType & InputType.TYPE_TEXT_FLAG_CAP_CHARACTERS) != 0) { 63 capitalize = TextKeyListener.Capitalize.CHARACTERS; 64 } else if ((inputType & InputType.TYPE_TEXT_FLAG_CAP_WORDS) != 0) { 65 capitalize = TextKeyListener.Capitalize.WORDS; 66 } else if ((inputType & InputType.TYPE_TEXT_FLAG_CAP_SENTENCES) != 0) { 67 capitalize = TextKeyListener.Capitalize.SENTENCES; 68 } 69 view.setKeyListener(TextKeyListener.getInstance(autoText, capitalize)); 70 } 71 72 @BindingAdapter("android:capitalize") 73 public static void setCapitalize(TextView view, TextKeyListener.Capitalize capitalize) { 74 KeyListener listener = view.getKeyListener(); 75 76 int inputType = listener.getInputType(); 77 boolean autoText = (inputType & InputType.TYPE_TEXT_FLAG_AUTO_CORRECT) != 0; 78 view.setKeyListener(TextKeyListener.getInstance(autoText, capitalize)); 79 } 80 81 @BindingAdapter("android:bufferType") 82 public static void setBufferType(TextView view, TextView.BufferType bufferType) { 83 view.setText(view.getText(), bufferType); 84 } 85 86 @BindingAdapter("android:digits") 87 public static void setDigits(TextView view, CharSequence digits) { 88 if (digits != null) { 89 view.setKeyListener(DigitsKeyListener.getInstance(digits.toString())); 90 } else if (view.getKeyListener() instanceof DigitsKeyListener) { 91 view.setKeyListener(null); 92 } 93 } 94 95 @BindingAdapter("android:numeric") 96 public static void setNumeric(TextView view, int numeric) { 97 view.setKeyListener(DigitsKeyListener.getInstance((numeric & SIGNED) != 0, 98 (numeric & DECIMAL) != 0)); 99 } 100 101 @BindingAdapter("android:phoneNumber") 102 public static void setPhoneNumber(TextView view, boolean phoneNumber) { 103 if (phoneNumber) { 104 view.setKeyListener(DialerKeyListener.getInstance()); 105 } else if (view.getKeyListener() instanceof DialerKeyListener) { 106 view.setKeyListener(null); 107 } 108 } 109 110 @BindingAdapter("android:drawableBottom") 111 public static void setDrawableBottom(TextView view, Drawable drawable) { 112 Drawable[] drawables = view.getCompoundDrawables(); 113 view.setCompoundDrawables(drawables[0], drawables[1], drawables[2], drawable); 114 } 115 116 @BindingAdapter("android:drawableLeft") 117 public static void setDrawableLeft(TextView view, Drawable drawable) { 118 Drawable[] drawables = view.getCompoundDrawables(); 119 view.setCompoundDrawables(drawable, drawables[1], drawables[2], drawables[3]); 120 } 121 122 @BindingAdapter("android:drawableRight") 123 public static void setDrawableRight(TextView view, Drawable drawable) { 124 Drawable[] drawables = view.getCompoundDrawables(); 125 view.setCompoundDrawables(drawables[0], drawables[1], drawable, drawables[3]); 126 } 127 128 @BindingAdapter("android:drawableTop") 129 public static void setDrawableTop(TextView view, Drawable drawable) { 130 Drawable[] drawables = view.getCompoundDrawables(); 131 view.setCompoundDrawables(drawables[0], drawable, drawables[2], drawables[3]); 132 } 133 134 @BindingAdapter("android:drawableStart") 135 public static void setDrawableStart(TextView view, Drawable drawable) { 136 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { 137 setDrawableLeft(view, drawable); 138 } else { 139 Drawable[] drawables = view.getCompoundDrawablesRelative(); 140 view.setCompoundDrawablesRelative(drawable, drawables[1], drawables[2], drawables[3]); 141 } 142 } 143 144 @BindingAdapter("android:drawableEnd") 145 public static void setDrawableEnd(TextView view, Drawable drawable) { 146 if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) { 147 setDrawableRight(view, drawable); 148 } else { 149 Drawable[] drawables = view.getCompoundDrawablesRelative(); 150 view.setCompoundDrawablesRelative(drawables[0], drawables[1], drawable, drawables[3]); 151 } 152 } 153 154 @BindingAdapter("android:imeActionLabel") 155 public static void setImeActionLabel(TextView view, CharSequence value) { 156 view.setImeActionLabel(value, view.getImeActionId()); 157 } 158 159 @BindingAdapter("android:imeActionId") 160 public static void setImeActionLabel(TextView view, int value) { 161 view.setImeActionLabel(view.getImeActionLabel(), value); 162 } 163 164 @BindingAdapter("android:inputMethod") 165 public static void setInputMethod(TextView view, CharSequence inputMethod) { 166 try { 167 Class<?> c = Class.forName(inputMethod.toString()); 168 view.setKeyListener((KeyListener) c.newInstance()); 169 } catch (ClassNotFoundException e) { 170 Log.e(TAG, "Could not create input method: " + inputMethod, e); 171 } catch (InstantiationException e) { 172 Log.e(TAG, "Could not create input method: " + inputMethod, e); 173 } catch (IllegalAccessException e) { 174 Log.e(TAG, "Could not create input method: " + inputMethod, e); 175 } 176 } 177 178 @BindingAdapter("android:lineSpacingExtra") 179 public static void setLineSpacingExtra(TextView view, float value) { 180 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 181 view.setLineSpacing(value, view.getLineSpacingMultiplier()); 182 } else { 183 view.setLineSpacing(value, 1); 184 } 185 } 186 187 @BindingAdapter("android:lineSpacingMultiplier") 188 public static void setLineSpacingMultiplier(TextView view, float value) { 189 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 190 view.setLineSpacing(view.getLineSpacingExtra(), value); 191 } else { 192 view.setLineSpacing(0, value); 193 } 194 } 195 196 @BindingAdapter("android:maxLength") 197 public static void setMaxLength(TextView view, int value) { 198 InputFilter[] filters = view.getFilters(); 199 if (filters == null) { 200 filters = new InputFilter[]{ 201 new InputFilter.LengthFilter(value) 202 }; 203 } else { 204 boolean foundMaxLength = false; 205 for (int i = 0; i < filters.length; i++) { 206 InputFilter filter = filters[i]; 207 if (filter instanceof InputFilter.LengthFilter) { 208 foundMaxLength = true; 209 boolean replace = true; 210 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 211 replace = ((InputFilter.LengthFilter) filter).getMax() != value; 212 } 213 if (replace) { 214 filters[i] = new InputFilter.LengthFilter(value); 215 } 216 break; 217 } 218 } 219 if (!foundMaxLength) { 220 // can't use Arrays.copyOf -- it shows up in API 9 221 InputFilter[] oldFilters = filters; 222 filters = new InputFilter[oldFilters.length + 1]; 223 System.arraycopy(oldFilters, 0, filters, 0, oldFilters.length); 224 filters[filters.length - 1] = new InputFilter.LengthFilter(value); 225 } 226 } 227 view.setFilters(filters); 228 } 229 230 @BindingAdapter("android:password") 231 public static void setPassword(TextView view, boolean password) { 232 if (password) { 233 view.setTransformationMethod(PasswordTransformationMethod.getInstance()); 234 } else if (view.getTransformationMethod() instanceof PasswordTransformationMethod) { 235 view.setTransformationMethod(null); 236 } 237 } 238 239 @BindingAdapter("android:shadowColor") 240 public static void setShadowColor(TextView view, int color) { 241 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 242 float dx = view.getShadowDx(); 243 float dy = view.getShadowDy(); 244 float r = view.getShadowRadius(); 245 view.setShadowLayer(r, dx, dy, color); 246 } 247 } 248 249 @BindingAdapter("android:shadowDx") 250 public static void setShadowDx(TextView view, float dx) { 251 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 252 int color = view.getShadowColor(); 253 float dy = view.getShadowDy(); 254 float r = view.getShadowRadius(); 255 view.setShadowLayer(r, dx, dy, color); 256 } 257 } 258 259 @BindingAdapter("android:shadowDy") 260 public static void setShadowDy(TextView view, float dy) { 261 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 262 int color = view.getShadowColor(); 263 float dx = view.getShadowDx(); 264 float r = view.getShadowRadius(); 265 view.setShadowLayer(r, dx, dy, color); 266 } 267 } 268 269 @BindingAdapter("android:shadowRadius") 270 public static void setShadowRadius(TextView view, float r) { 271 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 272 int color = view.getShadowColor(); 273 float dx = view.getShadowDx(); 274 float dy = view.getShadowDy(); 275 view.setShadowLayer(r, dx, dy, color); 276 } 277 } 278 279 @BindingAdapter("android:textSize") 280 public static void setTextSize(TextView view, float size) { 281 view.setTextSize(TypedValue.COMPLEX_UNIT_PX, size); 282 } 283} 284