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