• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 package org.robolectric.shadows;
2 
3 import static org.robolectric.shadows.ShadowLooper.shadowMainLooper;
4 import static org.robolectric.util.reflector.Reflector.reflector;
5 
6 import android.view.MotionEvent;
7 import android.view.View;
8 import android.view.ViewGroup;
9 import java.io.PrintStream;
10 import org.robolectric.annotation.Implementation;
11 import org.robolectric.annotation.Implements;
12 import org.robolectric.annotation.LooperMode.Mode;
13 import org.robolectric.annotation.RealObject;
14 import org.robolectric.shadow.api.Shadow;
15 import org.robolectric.util.reflector.Direct;
16 import org.robolectric.util.reflector.ForType;
17 
18 @SuppressWarnings({"UnusedDeclaration"})
19 @Implements(ViewGroup.class)
20 public class ShadowViewGroup extends ShadowView {
21   @RealObject protected ViewGroup realViewGroup;
22 
23   private boolean disallowInterceptTouchEvent = false;
24   private MotionEvent interceptedTouchEvent;
25 
26   @Implementation
addView(final View child, final int index, final ViewGroup.LayoutParams params)27   protected void addView(final View child, final int index, final ViewGroup.LayoutParams params) {
28     Runnable addViewRunnable =
29         () -> {
30           reflector(ViewGroupReflector.class, realViewGroup).addView(child, index, params);
31         };
32     if (ShadowLooper.looperMode() == Mode.LEGACY) {
33       shadowMainLooper().runPaused(addViewRunnable);
34     } else {
35       addViewRunnable.run();
36     }
37   }
38 
39   /**
40    * Returns a string representation of this {@code ViewGroup} by concatenating all of the
41    * strings contained in all of the descendants of this {@code ViewGroup}.
42    */
43   @Override
innerText()44   public String innerText() {
45     StringBuilder innerText = new StringBuilder();
46     String delimiter = "";
47 
48     for (int i = 0; i < realViewGroup.getChildCount(); i++) {
49       View child = realViewGroup.getChildAt(i);
50       ShadowView shadowView = Shadow.extract(child);
51       String childText = shadowView.innerText();
52       if (childText.length() > 0) {
53         innerText.append(delimiter);
54         delimiter = " ";
55       }
56       innerText.append(childText);
57     }
58     return innerText.toString();
59   }
60 
61   /**
62    * Dumps the state of this {@code ViewGroup} to {@code System.out}.
63    * @deprecated - Please use {@link androidx.test.espresso.util.HumanReadables#describe(View)}
64    */
65   @Override
66   @Deprecated
dump(PrintStream out, int indent)67   public void dump(PrintStream out, int indent) {
68     dumpFirstPart(out, indent);
69     if (realViewGroup.getChildCount() > 0) {
70       out.println(">");
71 
72       for (int i = 0; i < realViewGroup.getChildCount(); i++) {
73         View child = realViewGroup.getChildAt(i);
74         ShadowView shadowChild = Shadow.extract(child);
75         shadowChild.dump(out, indent + 2);
76       }
77 
78       dumpIndent(out, indent);
79       out.println("</" + realView.getClass().getSimpleName() + ">");
80     } else {
81       out.println("/>");
82     }
83   }
84 
85   @Implementation
requestDisallowInterceptTouchEvent(boolean disallowIntercept)86   protected void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
87     reflector(ViewGroupReflector.class, realViewGroup)
88         .requestDisallowInterceptTouchEvent(disallowIntercept);
89     disallowInterceptTouchEvent = disallowIntercept;
90   }
91 
getDisallowInterceptTouchEvent()92   public boolean getDisallowInterceptTouchEvent() {
93     return disallowInterceptTouchEvent;
94   }
95 
removedChild(View child)96   protected void removedChild(View child) {
97     if (isAttachedToWindow()) {
98       ShadowView shadowView = Shadow.extract(child);
99       shadowView.callOnDetachedFromWindow();
100     }
101   }
102 
getInterceptedTouchEvent()103   public MotionEvent getInterceptedTouchEvent() {
104     return interceptedTouchEvent;
105   }
106 
107   @Implementation
onInterceptTouchEvent(MotionEvent ev)108   protected boolean onInterceptTouchEvent(MotionEvent ev) {
109     interceptedTouchEvent = ev;
110     return false;
111   }
112 
113   @ForType(ViewGroup.class)
114   interface ViewGroupReflector {
115 
116     @Direct
addView(View child, int index, ViewGroup.LayoutParams params)117     void addView(View child, int index, ViewGroup.LayoutParams params);
118 
119     @Direct
requestDisallowInterceptTouchEvent(boolean disallowIntercept)120     void requestDisallowInterceptTouchEvent(boolean disallowIntercept);
121   }
122 }
123