Home | History | Annotate | Download | only in shadows
      1 package com.xtremelabs.robolectric.shadows;
      2 
      3 import android.view.View;
      4 import android.view.ViewGroup;
      5 import android.view.animation.Animation.AnimationListener;
      6 import com.xtremelabs.robolectric.internal.Implementation;
      7 import com.xtremelabs.robolectric.internal.Implements;
      8 
      9 import java.io.PrintStream;
     10 import java.util.ArrayList;
     11 import java.util.List;
     12 
     13 import static com.xtremelabs.robolectric.Robolectric.shadowOf;
     14 
     15 /**
     16  * Shadow for {@code ViewGroup} that simulates its implementation
     17  */
     18 @SuppressWarnings({"UnusedDeclaration"})
     19 @Implements(ViewGroup.class)
     20 public class ShadowViewGroup extends ShadowView {
     21     private List<View> children = new ArrayList<View>();
     22     private AnimationListener animListener;
     23     private boolean disallowInterceptTouchEvent = false;
     24 
     25     @Implementation
     26     @Override
     27     public View findViewById(int id) {
     28         if (id == getId()) {
     29             return realView;
     30         }
     31 
     32         for (View child : children) {
     33             View found = child.findViewById(id);
     34             if (found != null) {
     35                 return found;
     36             }
     37         }
     38         return null;
     39     }
     40 
     41     @Implementation
     42     @Override
     43     public View findViewWithTag(Object obj) {
     44         if (obj.equals(realView.getTag())) {
     45             return realView;
     46         }
     47 
     48         for (View child : children) {
     49             View found = child.findViewWithTag(obj);
     50             if (found != null) {
     51                 return found;
     52             }
     53         }
     54 
     55         return null;
     56     }
     57 
     58     @Implementation
     59     public void addView(View child) {
     60         ((ViewGroup) realView).addView(child, -1);
     61     }
     62 
     63     @Implementation
     64     public void addView(View child, int index) {
     65         if (index == -1) {
     66             children.add(child);
     67         } else {
     68             children.add(index, child);
     69         }
     70         shadowOf(child).parent = this;
     71     }
     72 
     73     @Implementation
     74     public void addView(View child, int width, int height) {
     75         ((ViewGroup) realView).addView(child, -1);
     76     }
     77 
     78     @Implementation
     79     public void addView(View child, ViewGroup.LayoutParams params) {
     80         ((ViewGroup) realView).addView(child, -1);
     81     }
     82 
     83     @Implementation
     84     public void addView(View child, int index, ViewGroup.LayoutParams params) {
     85         ((ViewGroup) realView).addView(child, index);
     86     }
     87 
     88     @Implementation
     89     public int indexOfChild(View child) {
     90         int count = getChildCount();
     91         for (int i = 0; i < count; i++) {
     92             if (children.get(i) == child) {
     93                 return i;
     94             }
     95         }
     96         return -1;
     97     }
     98 
     99     @Implementation
    100     public int getChildCount() {
    101         return children.size();
    102     }
    103 
    104     @Implementation
    105     public View getChildAt(int index) {
    106     	if( index >= children.size() ){ return null; }
    107         return children.get(index);
    108     }
    109 
    110     @Implementation
    111     public void removeAllViews() {
    112         for (View child : children) {
    113             shadowOf(child).parent = null;
    114         }
    115         children.clear();
    116     }
    117 
    118     @Implementation
    119     public void removeViewAt(int position) {
    120         shadowOf(children.remove(position)).parent = null;
    121     }
    122 
    123     @Implementation
    124     public void removeView(View view) {
    125         removeViewInLayout(view);
    126     }
    127 
    128     @Implementation
    129     public void removeViewInLayout(View view) {
    130         int index = indexOfChild(view);
    131         if (index >= 0) {
    132             removeViewAt(index);
    133         }
    134     }
    135 
    136     @Implementation
    137     public void removeViews(int start, int count) {
    138         removeViewsInLayout(start, count);
    139     }
    140 
    141     @Implementation
    142     public void removeViewsInLayout(int start, int count) {
    143         int lastIndex = start + count - 1;
    144         for (int i = lastIndex; i >= start; i--) {
    145             removeViewAt(i);
    146         }
    147     }
    148 
    149     @Override
    150     @Implementation
    151     public boolean hasFocus() {
    152         if (super.hasFocus()) return true;
    153 
    154         for (View child : children) {
    155             if (child.hasFocus()) return true;
    156         }
    157 
    158         return false;
    159     }
    160 
    161     @Implementation
    162     @Override
    163     public void clearFocus() {
    164         if (hasFocus()) {
    165             super.clearFocus();
    166 
    167             for (View child : children) {
    168                 child.clearFocus();
    169             }
    170         }
    171     }
    172 
    173     @Implementation
    174     @Override
    175     public View findFocus() {
    176         if (super.hasFocus()) {
    177             return this.realView;
    178         }
    179 
    180         for (View child : children) {
    181             View focusedView = child.findFocus();
    182             if (focusedView != null) {
    183                 return focusedView;
    184             }
    185         }
    186 
    187         return null;
    188     }
    189 
    190     /**
    191      * Returns a string representation of this {@code ViewGroup} by concatenating all of the strings contained in all
    192      * of the descendants of this {@code ViewGroup}.
    193      * <p/>
    194      * Robolectric extension.
    195      */
    196     @Override
    197     public String innerText() {
    198         String innerText = "";
    199         String delimiter = "";
    200 
    201         for (int i = 0; i < getChildCount(); i++) {
    202             View child = getChildAt(i);
    203             String childText = shadowOf(child).innerText();
    204             if (childText.length() > 0) {
    205                 innerText += delimiter;
    206                 delimiter = " ";
    207             }
    208             innerText += childText;
    209         }
    210         return innerText;
    211     }
    212 
    213     /**
    214      * Non-Android method that dumps the state of this {@code ViewGroup} to {@code System.out}
    215      */
    216     @Override
    217     public void dump(PrintStream out, int indent) {
    218         dumpFirstPart(out, indent);
    219         if (children.size() > 0) {
    220             out.println(">");
    221 
    222             for (View child : children) {
    223                 shadowOf(child).dump(out, indent + 2);
    224             }
    225 
    226             dumpIndent(out, indent);
    227             out.println("</" + realView.getClass().getSimpleName() + ">");
    228         } else {
    229             out.println("/>");
    230         }
    231     }
    232 
    233     @Implementation
    234     public void setLayoutAnimationListener(AnimationListener listener) {
    235         animListener = listener;
    236     }
    237 
    238     @Implementation
    239     public AnimationListener getLayoutAnimationListener() {
    240         return animListener;
    241     }
    242 
    243     @Implementation
    244     public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
    245         disallowInterceptTouchEvent = disallowIntercept;
    246     }
    247 
    248     public boolean getDisallowInterceptTouchEvent() {
    249         return disallowInterceptTouchEvent;
    250     }
    251 }
    252