1 package org.robolectric.shadows; 2 3 import static org.robolectric.shadow.api.Shadow.directlyOn; 4 5 import android.content.Context; 6 import android.graphics.Typeface; 7 import android.text.InputFilter; 8 import android.text.TextPaint; 9 import android.text.TextWatcher; 10 import android.text.method.MovementMethod; 11 import android.text.method.TransformationMethod; 12 import android.view.KeyEvent; 13 import android.view.View; 14 import android.view.inputmethod.EditorInfo; 15 import android.widget.TextView; 16 import java.io.PrintStream; 17 import java.util.ArrayList; 18 import java.util.List; 19 import java.util.Locale; 20 import org.robolectric.annotation.HiddenApi; 21 import org.robolectric.annotation.Implementation; 22 import org.robolectric.annotation.Implements; 23 import org.robolectric.annotation.RealObject; 24 25 @SuppressWarnings({"UnusedDeclaration"}) 26 @Implements(TextView.class) 27 public class ShadowTextView extends ShadowView { 28 @RealObject TextView realTextView; 29 30 private CharSequence text = ""; 31 private TextView.BufferType bufferType = TextView.BufferType.NORMAL; 32 private Integer textColorHexValue; 33 private Integer hintColorHexValue; 34 private float textSize = 14.0f; 35 private boolean autoLinkPhoneNumbers; 36 private int autoLinkMask; 37 private CharSequence hintText; 38 private CharSequence errorText; 39 private int compoundDrawablePadding; 40 private MovementMethod movementMethod; 41 private boolean linksClickable; 42 private int gravity; 43 private int imeOptions = EditorInfo.IME_NULL; 44 private TextView.OnEditorActionListener onEditorActionListener; 45 private int textAppearanceId; 46 private TransformationMethod transformationMethod; 47 private int inputType; 48 private int lines; 49 protected int selectionStart = -1; 50 protected int selectionEnd = -1; 51 private Typeface typeface; 52 private InputFilter[] inputFilters; 53 private TextPaint textPaint = new TextPaint(); 54 55 private List<TextWatcher> watchers = new ArrayList<>(); 56 private List<Integer> previousKeyCodes = new ArrayList<>(); 57 private List<KeyEvent> previousKeyEvents = new ArrayList<>(); 58 private int paintFlags; 59 private int compoundDrawablesWithIntrinsicBoundsLeft; 60 private int compoundDrawablesWithIntrinsicBoundsTop; 61 private int compoundDrawablesWithIntrinsicBoundsRight; 62 private int compoundDrawablesWithIntrinsicBoundsBottom; 63 64 @Implementation setTextAppearance(Context context, int resid)65 protected void setTextAppearance(Context context, int resid) { 66 textAppearanceId = resid; 67 directlyOn(realTextView, TextView.class).setTextAppearance(context, resid); 68 } 69 70 @Implementation onKeyDown(int keyCode, KeyEvent event)71 protected boolean onKeyDown(int keyCode, KeyEvent event) { 72 previousKeyCodes.add(keyCode); 73 previousKeyEvents.add(event); 74 return directlyOn(realTextView, TextView.class).onKeyDown(keyCode, event); 75 } 76 77 @Implementation onKeyUp(int keyCode, KeyEvent event)78 protected boolean onKeyUp(int keyCode, KeyEvent event) { 79 previousKeyCodes.add(keyCode); 80 previousKeyEvents.add(event); 81 return directlyOn(realTextView, TextView.class).onKeyUp(keyCode, event); 82 } 83 getPreviousKeyCode(int index)84 public int getPreviousKeyCode(int index) { 85 return previousKeyCodes.get(index); 86 } 87 getPreviousKeyEvent(int index)88 public KeyEvent getPreviousKeyEvent(int index) { 89 return previousKeyEvents.get(index); 90 } 91 92 /** 93 * Returns the text string of this {@code TextView}. 94 * 95 * Robolectric extension. 96 */ 97 @Override innerText()98 public String innerText() { 99 CharSequence text = realTextView.getText(); 100 return (text == null || realTextView.getVisibility() != View.VISIBLE) ? "" : text.toString(); 101 } 102 getTextAppearanceId()103 public int getTextAppearanceId() { 104 return textAppearanceId; 105 } 106 107 @Implementation addTextChangedListener(TextWatcher watcher)108 protected void addTextChangedListener(TextWatcher watcher) { 109 this.watchers.add(watcher); 110 directlyOn(realTextView, TextView.class).addTextChangedListener(watcher); 111 } 112 113 @Implementation removeTextChangedListener(TextWatcher watcher)114 protected void removeTextChangedListener(TextWatcher watcher) { 115 this.watchers.remove(watcher); 116 directlyOn(realTextView, TextView.class).removeTextChangedListener(watcher); 117 } 118 119 /** 120 * @return the list of currently registered watchers/listeners 121 */ getWatchers()122 public List<TextWatcher> getWatchers() { 123 return watchers; 124 } 125 126 @HiddenApi @Implementation getTextServicesLocale()127 public Locale getTextServicesLocale() { 128 return Locale.getDefault(); 129 } 130 131 @Override dumpAttributes(PrintStream out)132 protected void dumpAttributes(PrintStream out) { 133 super.dumpAttributes(out); 134 CharSequence text = realTextView.getText(); 135 if (text != null && text.length() > 0) { 136 dumpAttribute(out, "text", text.toString()); 137 } 138 } 139 140 @Implementation getPaintFlags()141 protected int getPaintFlags() { 142 return paintFlags; 143 } 144 145 @Implementation setPaintFlags(int paintFlags)146 protected void setPaintFlags(int paintFlags) { 147 this.paintFlags = paintFlags; 148 } 149 150 @Implementation setOnEditorActionListener(TextView.OnEditorActionListener l)151 protected void setOnEditorActionListener(TextView.OnEditorActionListener l) { 152 this.onEditorActionListener = l; 153 directlyOn(realTextView, TextView.class).setOnEditorActionListener(l); 154 } 155 getOnEditorActionListener()156 public TextView.OnEditorActionListener getOnEditorActionListener() { 157 return onEditorActionListener; 158 } 159 160 @Implementation setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom)161 protected void setCompoundDrawablesWithIntrinsicBounds(int left, int top, int right, int bottom) { 162 this.compoundDrawablesWithIntrinsicBoundsLeft = left; 163 this.compoundDrawablesWithIntrinsicBoundsTop = top; 164 this.compoundDrawablesWithIntrinsicBoundsRight = right; 165 this.compoundDrawablesWithIntrinsicBoundsBottom = bottom; 166 directlyOn(realTextView, TextView.class).setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom); 167 } 168 getCompoundDrawablesWithIntrinsicBoundsLeft()169 public int getCompoundDrawablesWithIntrinsicBoundsLeft() { 170 return compoundDrawablesWithIntrinsicBoundsLeft; 171 } 172 getCompoundDrawablesWithIntrinsicBoundsTop()173 public int getCompoundDrawablesWithIntrinsicBoundsTop() { 174 return compoundDrawablesWithIntrinsicBoundsTop; 175 } 176 getCompoundDrawablesWithIntrinsicBoundsRight()177 public int getCompoundDrawablesWithIntrinsicBoundsRight() { 178 return compoundDrawablesWithIntrinsicBoundsRight; 179 } 180 getCompoundDrawablesWithIntrinsicBoundsBottom()181 public int getCompoundDrawablesWithIntrinsicBoundsBottom() { 182 return compoundDrawablesWithIntrinsicBoundsBottom; 183 } 184 } 185