Android - एक दृश्य के अंदर बच्चों को मिलता है?


169

यह देखते हुए कि मैं इसके अंदर बच्चे के विचार कैसे प्राप्त कर सकता हूं?

इसलिए मेरे पास एक कस्टम व्यू और डिबगर शो है, जिसके तहत mChildren7 अन्य दृश्य हैं। मुझे इन विचारों को एक्सेस करने के लिए एक तरीका चाहिए, लेकिन ऐसा लगता नहीं है कि ऐसा करने के लिए कोई सार्वजनिक एपीआई है।

कोई सुझाव?

संपादित करें:

मेरा कस्टम दृश्य इनहेरिट करता है AdapterView

जवाबों:


313
for(int index = 0; index < ((ViewGroup) viewGroup).getChildCount(); index++) {
    View nextChild = ((ViewGroup) viewGroup).getChildAt(index);
}

कर लेंगे?


2
इस पुनरावृत्ति को करने का सबसे अच्छा तरीका क्या है और इस तरह से एक उत्तराधिकार JSON ऑब्जेक्ट उत्पन्न होता है?
जिंबाब

मूल विचार को नाम दिया गया हैviewGroup
Prime624

57

यदि आप न केवल सभी प्रत्यक्ष बच्चों बल्कि सभी बच्चों के बच्चों और इतने पर प्राप्त करना चाहते हैं, तो आपको इसे पुनरावर्ती रूप से करना होगा:

private ArrayList<View> getAllChildren(View v) {

    if (!(v instanceof ViewGroup)) {
        ArrayList<View> viewArrayList = new ArrayList<View>();
        viewArrayList.add(v);
        return viewArrayList;
    }

    ArrayList<View> result = new ArrayList<View>();

    ViewGroup vg = (ViewGroup) v;
    for (int i = 0; i < vg.getChildCount(); i++) {

        View child = vg.getChildAt(i);

        ArrayList<View> viewArrayList = new ArrayList<View>();
        viewArrayList.add(v);
        viewArrayList.addAll(getAllChildren(child));

        result.addAll(viewArrayList);
    }
    return result;
}

परिणाम का उपयोग करने के लिए आप ऐसा कुछ कर सकते हैं:

    // check if a child is set to a specific String
    View myTopView;
    String toSearchFor = "Search me";
    boolean found = false;
    ArrayList<View> allViewsWithinMyTopView = getAllChildren(myTopView);
    for (View child : allViewsWithinMyTopView) {
        if (child instanceof TextView) {
            TextView childTextView = (TextView) child;
            if (TextUtils.equals(childTextView.getText().toString(), toSearchFor)) {
                found = true;
            }
        }
    }
    if (!found) {
        fail("Text '" + toSearchFor + "' not found within TopView");
    }

8
यह कॉल सेव नहीं है, जैसे कि बच्चा टाइप व्यू का हो सकता है और व्यूग्रुप का नहीं, इसलिए getAllChildren की पुनरावर्ती कॉल एक अपवाद का कारण बन सकती है, क्योंकि कास्ट विफल रहता है। इसलिए आपको एक if ((v Instof ViewGroup)) को वापस जोड़ना चाहिए; कलाकारों से पहले
फिल

2
छोटा सुझाव: अपने for (int i = 0, n = vg.getChildCount(); i < n; i++) एंड्रॉइड के साथ लूप के लिए बदलें , एक विधि को कॉल करने के बजाय स्थानीय चर तक पहुंचना अधिक तेज़ हो जाता है। इस तरह, एक विधि को केवल एक बार प्रति दृश्य समूह कहा जाता है और फिर बाद के रन पर एक स्थानीय चर का उपयोग किया जाता है।
आर्टऑफवर्फ

फिल डाईगमैन के सुझाव के कारण मैंने कोड बदल दिया। उम्मीद है की यह मदद करेगा। मेरे लिये कार्य करता है।
IHeartAndroid

1
ठंडा। मैं केवल एक बूलियन को शामिल करने का सुझाव दूंगा, जिसमें केवल 'ViewViewGroups' और केवल अगर यह सत्य है, iewArrayList.add (v); यह एक एडाप्टर में पुनरावृत्ति के लिए उपयोगी है (और मुझे केवल लीफ़्स की आवश्यकता है)। धन्यवाद!
जूं

20

आप हमेशा View.findViewById () http://developer.android.com/reference/android/view/View.html#findViewById(int के माध्यम से बच्चे के विचारों का उपयोग कर सकते हैं ) के ।

उदाहरण के लिए, एक गतिविधि / दृश्य के भीतर:

...
private void init() {
  View child1 = findViewById(R.id.child1);
}
...

या यदि आपके पास एक दृश्य का संदर्भ है:

...
private void init(View root) {
  View child2 = root.findViewById(R.id.child2);
}

मेरे पास आईडी तक पहुंच नहीं है, यूआई कोड के माध्यम से उत्पन्न होता है, मैं रोबोटियम का उपयोग करके स्वचालन लिख रहा हूं, इसलिए मैं जो कुछ कर सकता हूं वह सीमित है
aryaxt

@ जोंसन, सभी बच्चों को प्राप्त करने की आवश्यकता होने पर उपयोगी नहीं है।
पचेरियर

इसके अलावा quora.com/unanswered/...
Pacerier

17

मैं इस उत्तर को केवल एक विकल्प के रूप में प्रदान करने जा रहा हूं @ IHeartAndroid के पुनरावर्ती एल्गोरिदम को सभी बच्चों Viewको एक दृश्य पदानुक्रम में खोजने के लिए । ध्यान दें कि इस लेखन के समय, पुनरावर्ती समाधान में त्रुटिपूर्ण है कि इसके परिणाम में डुप्लिकेट शामिल होंगे।

उन लोगों के लिए जिन्हें अपने सिर को पुनरावृत्ति के चारों ओर लपेटने में परेशानी होती है, यहां एक गैर-पुनरावर्ती विकल्प है। आपको यह महसूस करने के लिए बोनस अंक मिलते हैं कि यह पुनरावर्ती समाधान के गहराई-पहले दृष्टिकोण के लिए एक चौड़ाई-पहला खोज विकल्प भी है ।

private List<View> getAllChildrenBFS(View v) {
    List<View> visited = new ArrayList<View>();
    List<View> unvisited = new ArrayList<View>();
    unvisited.add(v);

    while (!unvisited.isEmpty()) {
        View child = unvisited.remove(0);
        visited.add(child);
        if (!(child instanceof ViewGroup)) continue;
        ViewGroup group = (ViewGroup) child;
        final int childCount = group.getChildCount();
        for (int i=0; i<childCount; i++) unvisited.add(group.getChildAt(i));
    }

    return visited;
}

त्वरित परीक्षणों की एक जोड़ी (औपचारिक कुछ भी नहीं) का सुझाव है कि यह विकल्प भी तेज है, हालांकि नए की संख्या के साथ ऐसा करने की सबसे अधिक संभावना है ArrayList उदाहरणों की जो अन्य उत्तर बनाता है। इसके अलावा, परिणाम कैसे ऊर्ध्वाधर / क्षैतिज दृश्य पदानुक्रम के आधार पर भिन्न हो सकते हैं।

इससे पार से पोस्ट किया गया: Android | एक ViewGroup के सभी बच्चों के तत्व प्राप्त करें


7

यहाँ एक सुझाव दिया गया है: आप इसके IDद्वारा निर्दिष्ट नाम द्वारा (उदाहरण के लिए ) android:id="@+id/..My Str..उत्पन्न किया जा सकता Rहै My StrgetIdentifier()विधि का उपयोग कर एक कोड स्निपेट तब होगा:

public int getIdAssignedByR(Context pContext, String pIdString)
{
    // Get the Context's Resources and Package Name
    Resources resources = pContext.getResources();
    String packageName  = pContext.getPackageName();

    // Determine the result and return it
    int result = resources.getIdentifier(pIdString, "id", packageName);
    return result;
}

के भीतर से Activity, एक उदाहरण के साथ युग्मित उपयोग findViewByIdहोगा:

// Get the View (e.g. a TextView) which has the Layout ID of "UserInput"
int rID = getIdAssignedByR(this, "UserInput")
TextView userTextView = (TextView) findViewById(rID);

3

2018 के बाद इस सवाल पर आने वालों के लिए एक अपडेट के रूप में, यदि आप कोटलिन का उपयोग कर रहे हैं, तो आप बस व्यू के तत्काल बच्चों का एक अनुक्रम प्राप्त करने के लिए एंड्रॉइड केटीएक्स एक्सटेंशन संपत्ति ViewGroup.children का उपयोग कर सकते हैं ।


0

तालिका लेआउट (TableLayout) को रीफ्रेश करने के लिए, मैंने सभी बच्चों के बच्चों को प्राप्त करने के लिए ऊपर वर्णित पुनरावर्ती दृष्टिकोण का उपयोग करने के लिए समाप्त कर दिया।

मेरी स्थिति कुछ हद तक सरल हो गई थी क्योंकि मुझे केवल LinearLayout के साथ काम करने की आवश्यकता थी और उन वर्गों ने जैसे TableLayout से इसे बढ़ाया। और मुझे केवल TextView बच्चों को खोजने में दिलचस्पी थी। लेकिन मुझे लगता है कि यह अभी भी इस सवाल पर लागू है।

अंतिम वर्ग एक अलग धागे के रूप में चलता है, जिसका अर्थ है कि यह बच्चों के लिए पार्स करने से पहले पृष्ठभूमि में अन्य चीजें कर सकता है। कोड छोटा और सरल है और इसे github पर देखा जा सकता है: https://github.com/jkincali/Android-LinearLayout-Parser


0

यह विधि सभी विचारों को एक लेआउट के अंदर ले जाती है, यह अलेक्जेंडर कुलाख्तिन के उत्तर के समान है। अंतर यह है, यह किसी भी प्रकार के मूल लेआउट को स्वीकार करता है और विचारों की एक सरणी सूची देता है।

public List<View> getAllViews(ViewGroup layout){
        List<View> views = new ArrayList<>();
        for(int i =0; i< layout.getChildCount(); i++){
            views.add(layout.getChildAt(i));
        }
        return views;
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.