2014-07-15 14 views
23

का उपयोग कर इंडेक्स पर बाल दृश्य का चयन करना एस्प्रेसो के साथ बच्चे छवि दृश्यों के साथ एक कस्टम विजेट दृश्य का उपयोग करते समय, मैं किस प्रकार का बच्चा एनएच बच्चे का चयन करने के लिए उपयोग कर सकता हूं? उदाहरण:एस्प्रेसो

+--------->NumberSlider{id=2131296844, res-name=number_slider, visibility=VISIBLE, width=700, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=10.0, y=0.0, child-count=7} 
| 
+---------->NumberView{id=-1, visibility=VISIBLE, width=99, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0} 
| 
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=99.0, y=0.0} 
| 
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=199.0, y=0.0} 
| 
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=299.0, y=0.0} 
| 
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=399.0, y=0.0} 
| 
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=499.0, y=0.0} 
| 
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=599.0, y=0.0} 

उत्तर

40
public static Matcher<View> nthChildOf(final Matcher<View> parentMatcher, final int childPosition) { 
    return new TypeSafeMatcher<View>() { 
     @Override 
     public void describeTo(Description description) { 
     description.appendText("with "+childPosition+" child view of type parentMatcher"); 
     } 

     @Override 
     public boolean matchesSafely(View view) { 
     if (!(view.getParent() instanceof ViewGroup)) { 
      return parentMatcher.matches(view.getParent()); 
     } 

     ViewGroup group = (ViewGroup) view.getParent(); 
     return parentMatcher.matches(view.getParent()) && group.getChildAt(childPosition).equals(view); 
     } 
    }; 
    } 

यह

onView(nthChildOf(withId(R.id.parent_container), 0).check(matches(withText("I am the first child")); 
+3

माता-पिता में पर्याप्त बच्चे के दृश्य नहीं होने पर, NullPointerException से बचने के लिए अंतिम निर्देश में 'वापसी parentMatcher.matches (view.getParent()) && view.equals (group.getChildAt (childPosition)) का उपयोग करना सुरक्षित होगा। – nicopico

8

यदि आप मूल दृश्य प्राप्त कर सकते हैं। this link हो सकता है जो एक दृश्य के पहले बच्चे को प्राप्त करने के लिए एक मैचर परिभाषित करता है जो आपको कुछ सुराग दे सकता है।

 public static Matcher<View> firstChildOf(final Matcher<View> parentMatcher) { 
     return new TypeSafeMatcher<View>() { 
      @Override 
      public void describeTo(Description description) { 
       description.appendText("with first child view of type parentMatcher"); 
      } 

      @Override 
      public boolean matchesSafely(View view) {  

       if (!(view.getParent() instanceof ViewGroup)) { 
        return parentMatcher.matches(view.getParent());     
       } 
       ViewGroup group = (ViewGroup) view.getParent(); 
       return parentMatcher.matches(view.getParent()) && group.getChildAt(0).equals(view); 

      } 
     }; 
    } 
+1

यदि आपको एनटी प्राप्त करने की आवश्यकता है, तो इसे getChildAt (n) का उपयोग करना चाहिए। –

15

कोशिश करते हैं और Maragues के समाधान के एक छोटे से सुधार करने के लिए उपयोग करने के लिए, मैं कुछ परिवर्तन किए हैं।

समाधान एक कस्टम Matcher < देखें > कि माता पिता को देखने के लिए एक और Matcher < देखें > लपेटता, और बच्चे को देखने के सूचकांक लेता मिलान किया जा तैयार करना है।

public static Matcher<View> nthChildOf(final Matcher<View> parentMatcher, final int childPosition) { 
    return new TypeSafeMatcher<View>() { 
     @Override 
     public void describeTo(Description description) { 
      description.appendText("position " + childPosition + " of parent "); 
      parentMatcher.describeTo(description); 
     } 

     @Override 
     public boolean matchesSafely(View view) { 
      if (!(view.getParent() instanceof ViewGroup)) return false; 
      ViewGroup parent = (ViewGroup) view.getParent(); 

      return parentMatcher.matches(parent) 
        && parent.getChildCount() > childPosition 
        && parent.getChildAt(childPosition).equals(view); 
     } 
    }; 
} 

विस्तृत विवरण

आपको एक आसान विवरण तर्क को जोड़कर मिलान के विवरण को समझने के लिए देने के लिए describeTo विधि ओवरराइड कर सकते हैं। आप का वर्णन भी करना चाहते हैं अभिभावक matcher पर कॉल करें ताकि यह विवरण भी जोड़ा जा सके।

@Override 
public void describeTo(Description description) { 
    description.appendText("position " + childPosition + " of parent "); // Add this matcher's description. 
    parentMatcher.describeTo(description); // Add the parentMatcher description. 
} 

इसके बाद, आप matchesSafely जो तय करेंगे जब दृश्य पदानुक्रम में एक मैच पाया गया है ओवरराइड करना चाहिए। जब एक दृश्य के साथ बुलाया जाता है जिसका माता-पिता प्रदान किए गए माता-पिता matcher से मेल खाता है, तो जांचें कि दृश्य प्रदान की गई स्थिति में बच्चे के बराबर है।

माता पिता एक childCount बच्चे स्थिति से अधिक है, getChildAt अशक्त लौट सकते हैं और परीक्षण के क्रैश होने का कारण होगा नहीं है, तो। क्रैश होने से बचने और परीक्षण को असफल होने की अनुमति देना बेहतर है ताकि हमें उचित परीक्षण रिपोर्ट और त्रुटि संदेश मिल सके।

@Override 
public boolean matchesSafely(View view) { 
if (!(view.getParent() instanceof ViewGroup)) return false; // If it's not a ViewGroup we know it doesn't match. 
    ViewGroup parent = (ViewGroup) view.getParent(); 

    return parentMatcher.matches(parent) // Check that the parent matches. 
      && parent.getChildCount() > childPosition // Make sure there's enough children. 
      && parent.getChildAt(childPosition).equals(view); // Check that this is the right child. 
} 
+0

ग्रेट उत्तर, बहुत विस्तृत स्पष्टीकरण के लिए धन्यवाद। – makovkastar

संबंधित मुद्दे