1 /* 2 * Copyright (C) 2019 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 package com.android.car.apps.common; 18 19 import android.car.drivingstate.CarUxRestrictions; 20 import android.content.Context; 21 import android.graphics.Rect; 22 import android.text.method.TransformationMethod; 23 import android.util.AttributeSet; 24 import android.view.View; 25 import android.widget.TextView; 26 27 import com.android.car.ui.utils.CarUxRestrictionsUtil; 28 29 /** 30 * UX Restrictions compliant TextView. 31 * This class will automatically listen to Car UXRestrictions and truncate text accordingly. 32 * 33 * Attributes that trigger {@link TextView#setTransformationMethod} should NOT be set and calls to 34 * the method should NOT be made to prevent overriding UX Restrictions. 35 * This includes, but is not limited to: 36 * {@link TextView#setInputType} 37 * {@link TextView#setAllCaps} 38 * {@link TextView#setSingleLine} 39 * android:inputType="textPassword" 40 * android:textAllCaps="true" 41 * android:singleLine="true" 42 */ 43 public class UxrTextView extends TextView { 44 private CarUxRestrictionsUtil mCarUxRestrictionsUtil; 45 private CarUxRestrictions mCarUxRestrictions; 46 private CarUxRestrictionsUtil.OnUxRestrictionsChangedListener mListener; 47 UxrTextView(Context context)48 public UxrTextView(Context context) { 49 super(context); 50 init(context); 51 } 52 UxrTextView(Context context, AttributeSet attrs)53 public UxrTextView(Context context, AttributeSet attrs) { 54 super(context, attrs); 55 init(context); 56 } 57 UxrTextView(Context context, AttributeSet attrs, int defStyleAttr)58 public UxrTextView(Context context, AttributeSet attrs, int defStyleAttr) { 59 super(context, attrs, defStyleAttr); 60 init(context); 61 } 62 UxrTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes)63 public UxrTextView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 64 super(context, attrs, defStyleAttr, defStyleRes); 65 init(context); 66 } 67 init(Context context)68 private void init(Context context) { 69 mCarUxRestrictionsUtil = CarUxRestrictionsUtil.getInstance(context); 70 mListener = this::updateCarUxRestrictions; 71 } 72 updateCarUxRestrictions(CarUxRestrictions carUxRestrictions)73 private void updateCarUxRestrictions(CarUxRestrictions carUxRestrictions) { 74 mCarUxRestrictions = carUxRestrictions; 75 76 // setTransformationMethod doesn't do anything when passed the same instance... 77 setTransformationMethod(new UXRTransformationMethod()); 78 } 79 80 @Override onAttachedToWindow()81 protected void onAttachedToWindow() { 82 super.onAttachedToWindow(); 83 mCarUxRestrictionsUtil.register(mListener); 84 } 85 86 @Override onDetachedFromWindow()87 protected void onDetachedFromWindow() { 88 super.onDetachedFromWindow(); 89 mCarUxRestrictionsUtil.unregister(mListener); 90 } 91 92 @Override setAllCaps(boolean b)93 public void setAllCaps(boolean b) { 94 // NOP 95 } 96 97 @Override setSingleLine(boolean b)98 public void setSingleLine(boolean b) { 99 // NOP 100 } 101 102 @Override setInputType(int i)103 public void setInputType(int i) { 104 // NOP 105 } 106 107 private class UXRTransformationMethod implements TransformationMethod { 108 @Override getTransformation(CharSequence source, View view)109 public CharSequence getTransformation(CharSequence source, View view) { 110 if (source == null) { 111 return ""; 112 } 113 return CarUxRestrictionsUtil.complyString(getContext(), source.toString(), 114 mCarUxRestrictions); 115 } 116 117 @Override onFocusChanged(View view, CharSequence sourceText, boolean focused, int direction, Rect previouslyFocusedRect)118 public void onFocusChanged(View view, CharSequence sourceText, boolean focused, 119 int direction, Rect previouslyFocusedRect) { 120 // Not used 121 } 122 } 123 } 124