• 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 strings
41    * 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    *
64    * @deprecated - Please use {@link androidx.test.espresso.util.HumanReadables#describe(View)}
65    */
66   @Override
67   @Deprecated
dump(PrintStream out, int indent)68   public void dump(PrintStream out, int indent) {
69     dumpFirstPart(out, indent);
70     if (realViewGroup.getChildCount() > 0) {
71       out.println(">");
72 
73       for (int i = 0; i < realViewGroup.getChildCount(); i++) {
74         View child = realViewGroup.getChildAt(i);
75         ShadowView shadowChild = Shadow.extract(child);
76         shadowChild.dump(out, indent + 2);
77       }
78 
79       dumpIndent(out, indent);
80       out.println("</" + realView.getClass().getSimpleName() + ">");
81     } else {
82       out.println("/>");
83     }
84   }
85 
86   @Implementation
requestDisallowInterceptTouchEvent(boolean disallowIntercept)87   protected void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
88     reflector(ViewGroupReflector.class, realViewGroup)
89         .requestDisallowInterceptTouchEvent(disallowIntercept);
90     disallowInterceptTouchEvent = disallowIntercept;
91   }
92 
getDisallowInterceptTouchEvent()93   public boolean getDisallowInterceptTouchEvent() {
94     return disallowInterceptTouchEvent;
95   }
96 
removedChild(View child)97   protected void removedChild(View child) {
98     if (isAttachedToWindow()) {
99       ShadowView shadowView = Shadow.extract(child);
100       shadowView.callOnDetachedFromWindow();
101     }
102   }
103 
getInterceptedTouchEvent()104   public MotionEvent getInterceptedTouchEvent() {
105     return interceptedTouchEvent;
106   }
107 
108   @Implementation
onInterceptTouchEvent(MotionEvent ev)109   protected boolean onInterceptTouchEvent(MotionEvent ev) {
110     interceptedTouchEvent = ev;
111     return false;
112   }
113 
114   @ForType(ViewGroup.class)
115   interface ViewGroupReflector {
116 
117     @Direct
addView(View child, int index, ViewGroup.LayoutParams params)118     void addView(View child, int index, ViewGroup.LayoutParams params);
119 
120     @Direct
requestDisallowInterceptTouchEvent(boolean disallowIntercept)121     void requestDisallowInterceptTouchEvent(boolean disallowIntercept);
122   }
123 }
124