1 package org.robolectric.shadows; 2 3 import static org.robolectric.shadow.api.Shadow.directlyOn; 4 5 import android.os.Looper; 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.RealObject; 13 import org.robolectric.shadow.api.Shadow; 14 import org.robolectric.util.ReflectionHelpers.ClassParameter; 15 16 @SuppressWarnings({"UnusedDeclaration"}) 17 @Implements(ViewGroup.class) 18 public class ShadowViewGroup extends ShadowView { 19 @RealObject protected ViewGroup realViewGroup; 20 21 private boolean disallowInterceptTouchEvent = false; 22 private MotionEvent interceptedTouchEvent; 23 24 @Implementation addView(final View child, final int index, final ViewGroup.LayoutParams params)25 protected void addView(final View child, final int index, final ViewGroup.LayoutParams params) { 26 ShadowLooper shadowLooper = Shadow.extract(Looper.getMainLooper()); 27 shadowLooper.runPaused(() -> 28 directlyOn(realViewGroup, ViewGroup.class, "addView", 29 ClassParameter.from(View.class, child), 30 ClassParameter.from(int.class, index), 31 ClassParameter.from(ViewGroup.LayoutParams.class, params))); 32 } 33 34 /** 35 * Returns a string representation of this {@code ViewGroup} by concatenating all of the 36 * strings contained in all of the descendants of this {@code ViewGroup}. 37 */ 38 @Override innerText()39 public String innerText() { 40 StringBuilder innerText = new StringBuilder(); 41 String delimiter = ""; 42 43 for (int i = 0; i < realViewGroup.getChildCount(); i++) { 44 View child = realViewGroup.getChildAt(i); 45 ShadowView shadowView = Shadow.extract(child); 46 String childText = shadowView.innerText(); 47 if (childText.length() > 0) { 48 innerText.append(delimiter); 49 delimiter = " "; 50 } 51 innerText.append(childText); 52 } 53 return innerText.toString(); 54 } 55 56 /** 57 * Dumps the state of this {@code ViewGroup} to {@code System.out}. 58 */ 59 @Override dump(PrintStream out, int indent)60 public void dump(PrintStream out, int indent) { 61 dumpFirstPart(out, indent); 62 if (realViewGroup.getChildCount() > 0) { 63 out.println(">"); 64 65 for (int i = 0; i < realViewGroup.getChildCount(); i++) { 66 View child = realViewGroup.getChildAt(i); 67 ShadowView shadowChild = Shadow.extract(child); 68 shadowChild.dump(out, indent + 2); 69 } 70 71 dumpIndent(out, indent); 72 out.println("</" + realView.getClass().getSimpleName() + ">"); 73 } else { 74 out.println("/>"); 75 } 76 } 77 78 @Implementation requestDisallowInterceptTouchEvent(boolean disallowIntercept)79 protected void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { 80 disallowInterceptTouchEvent = disallowIntercept; 81 } 82 getDisallowInterceptTouchEvent()83 public boolean getDisallowInterceptTouchEvent() { 84 return disallowInterceptTouchEvent; 85 } 86 removedChild(View child)87 protected void removedChild(View child) { 88 if (isAttachedToWindow()) { 89 ShadowView shadowView = Shadow.extract(child); 90 shadowView.callOnDetachedFromWindow(); 91 } 92 } 93 getInterceptedTouchEvent()94 public MotionEvent getInterceptedTouchEvent() { 95 return interceptedTouchEvent; 96 } 97 98 @Implementation onInterceptTouchEvent(MotionEvent ev)99 protected boolean onInterceptTouchEvent(MotionEvent ev) { 100 interceptedTouchEvent = ev; 101 return false; 102 } 103 } 104