Android: एक ListView से बच्चे के विचारों का उपयोग


108

मुझे एक सूची में एक तत्व की पिक्सेल स्थिति का पता लगाने की आवश्यकता है जो एक का उपयोग करके प्रदर्शित किया गया है ListView। ऐसा लगता है कि मुझे TextView में से एक को प्राप्त करना चाहिए और फिर उपयोग करना चाहिए getTop(), लेकिन मैं यह पता नहीं लगा सकता कि बच्चे को कैसे देखें ListView

अद्यतन: बच्चों के ViewGroupलिए सूची में आइटम के साथ 1-टू -1 के अनुरूप नहीं है, एक के लिए ListView। इसके बजाय, ViewGroupबच्चे केवल उन विचारों के अनुरूप हैं जो अभी दिखाई दे रहे हैं। तो getChildAt()एक ऐसे सूचकांक पर ViewGroupकाम करता है जो आंतरिक है और जरूरी नहीं कि ListViewउपयोग करने वाली सूची में स्थिति के साथ कुछ भी हो ।

जवाबों:


215

देखें: Android ListView: दृश्यमान वस्तु का डेटा इंडेक्स प्राप्त करें और ऊपर दिए गए पैर के उत्तर के हिस्से के साथ संयोजन करें, आपको कुछ ऐसा दे सकता है:

int wantedPosition = 10; // Whatever position you're looking for
int firstPosition = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount(); // This is the same as child #0
int wantedChild = wantedPosition - firstPosition;
// Say, first visible position is 8, you want position 10, wantedChild will now be 2
// So that means your view is child #2 in the ViewGroup:
if (wantedChild < 0 || wantedChild >= listView.getChildCount()) {
  Log.w(TAG, "Unable to get view for desired position, because it's not being displayed on screen.");
  return;
}
// Could also check if wantedPosition is between listView.getFirstVisiblePosition() and listView.getLastVisiblePosition() instead.
View wantedView = listView.getChildAt(wantedChild);

लाभ यह है कि आप ListView के बच्चों पर ध्यान नहीं दे रहे हैं, जो एक प्रदर्शन को प्रभावित कर सकता है।


10
जब आप अपनी सूची में हेडर विचार रखते हैं, तो महान जवाब, लेकिन काफी काम नहीं करता है। इसे ठीक करने के लिए असाइनमेंट firstPositionहोना चाहिए int firstPosition = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount();
पोस्पी

@pospi: धन्यवाद, अच्छी बात! मैंने उसके लिए अपना जवाब अपडेट कर दिया है।
जो

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

2
@VictorDenisov: यह केवल UI थ्रेड पर हो सकता है; इसलिए यह कोड निष्पादित करते समय UI थ्रेड ब्लॉक हो जाएगा, इस प्रकार बच्चे के विचार स्थिर होते हैं और इसे संशोधित नहीं किया जाएगा। ListViewपुराने convertViewएस आदि के पुनर्चक्रण के बाद बच्चे के विचारों को पहले से ही "चलती" संभाल रहा है , इसलिए आपको गारंटी दी जा सकती है कि ListView.getChildAt(0) यह वास्तव में एडेप्टर से जुड़ा हुआ पहला दृश्य है। यह पूरी तरह से दिखाई नहीं दे सकता है (और यह भी दिखाई नहीं दे सकता है, ListViewयह देखने के लिए रीसाइक्लिंग से पहले "दृश्यता" की सीमा पर निर्भर करता है कि यह "दृश्य से बाहर स्क्रॉल" है)
जो

1
@Matheus कि Android ListView कैसे काम करता है। यदि सूची आइटम ऑफ-स्क्रीन है, तो इसका दृश्य पहले से ही पुन: संग्रहित किया गया है और स्क्रीन पर मौजूद अन्य सूची आइटमों में से एक के लिए पुन: उपयोग किया जाता है। आपको फिर से सोचना चाहिए कि यदि आप एक आवश्यकता है तो आप ListView का उपयोग कैसे कर रहे हैं।
जो

17

इस कोड का उपयोग करना आसान है:

 View rowView = listView.getChildAt(viewIndex);//The item number in the List View
    if(rowView != null)
        {
           // Your code here
        }

9
हमेशा काम नहीं करता। getChildAt पहली दिखाई देने वाली पंक्ति से गिना जाता है, डेटा के ऊपर से नहीं।
स्टीलबाइट्स 5

13
ViewID तर्क भ्रमित कर रहा है। यह एक सूचकांक (या स्थिति) है। व्यू आईडी aapt टूल द्वारा उत्पन्न एक पूर्णतः मनमाना पूर्णांक है।
जोहान पेलग्रिम ऑक्ट

6

ListView वर्ग के लिए डॉक्स की एक त्वरित खोज ने GetChildCount () और getChildAt () तरीके देखें हैं जो व्यूग्रुप से विरासत में मिले हैं। क्या आप इनका उपयोग करके इनके माध्यम से पुनरावृति कर सकते हैं? मुझे यकीन नहीं है, लेकिन यह एक कोशिश के काबिल है।

यहां मिला


1
मैंने चयन करने के लिए यह कोशिश की है। यह आमतौर पर काम करता है लेकिन कभी-कभी एक-एक त्रुटियां होती हैं और यह विश्वसनीय नहीं है। मैं इसकी सिफारिश नहीं करूंगा।
टिम्मम

धन्यवाद Timmmm, मैं वास्तव में यह सिर्फ डॉक्स में पाया यह कोशिश नहीं की थी।
पैर

5
listview.setOnItemClickListener(new AdapterView.OnItemClickListener() {
    @Override
    public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {
        View v;
        int count = parent.getChildCount();
        v = parent.getChildAt(position);
        parent.requestChildFocus(v, view);
        v.setBackground(res.getDrawable(R.drawable.transparent_button));
        for (int i = 0; i < count; i++) {
            if (i != position) {
                v = parent.getChildAt(i);
                v.setBackground(res.getDrawable(R.drawable.not_clicked));
            }
        }
    }
});

मूल रूप से, दो ड्राएबल्स बनाएं - एक जो पारदर्शी है, और दूसरा जो वांछित रंग है। क्लिक की गई स्थिति ( int positionजैसा कि परिभाषित किया गया है) पर ध्यान देने का अनुरोध करें और उक्त पंक्ति का रंग बदलें। फिर माता-पिता के माध्यम से चलना ListView, और तदनुसार अन्य सभी पंक्तियों को बदलना। यह तब होता है जब उपयोगकर्ता listviewकई बार क्लिक करता है। यह प्रत्येक पंक्ति में कस्टम लेआउट के साथ किया जाता है ListView। (बहुत सरल, बस एक नई लेआउट फ़ाइल बनाएं TextView- ध्यान केंद्रित या क्लिक करने योग्य सेट न करें!)।

कोई कस्टम एडाप्टर की आवश्यकता नहीं है - उपयोग करें ArrayAdapter


getChildAt वर्तमान स्क्रॉल की गई वस्तुओं के सापेक्ष है। यदि आप अपनी सूची को थोड़ा सा स्क्रॉल करते हैं तो यह काम करना बंद कर देगा।
nurettin

4
int position = 0;
listview.setItemChecked(position, true);
View wantedView = adapter.getView(position, null, listview);

1
थोड़ा विस्तार से
innoSPG

-9

यह मानता है कि आप सूची में तत्व की स्थिति जानते हैं:

  View element = listView.getListAdapter().getView(position, null, null);

फिर आपको स्क्रीन स्थिति पर तत्वों को निर्धारित करने के लिए गेटलिफ्ट () और गेटटॉप () को कॉल करने में सक्षम होना चाहिए।


43
getView()सूची पॉप्युलेट करते समय, सूची दृश्य द्वारा आंतरिक रूप से कहा जाता है। आपको सूची में उस स्थिति पर दृश्य प्राप्त करने के लिए इसका उपयोग नहीं करना चाहिए , क्योंकि एडॉप्टर कारणों के getView()लिए नल के साथ कॉल convertViewकरने से एडेप्टर के लेआउट संसाधन से एक नया दृश्य फुलाया जाता है (वह दृश्य नहीं मिलता है जो पहले से ही प्रदर्शित हो रहा है)।
जो

1
यहां तक ​​कि स्थिति दृश्य स्क्रीन में एक स्थिति होगी, एडाप्टर के डेटा स्रोत की स्थिति में नहीं।
विकास

@ajonhudgins यह वह तरीका है जिसके लिए मैं उपयोग कर रहा हूं मैंने सोचा कि यह सबसे अच्छा है, लेकिन जब मैं बच्चे के दृश्य में एक प्रोग्रेसबार को अदृश्य बनाने की कोशिश करता हूं, लेकिन इसके बजाय यह सभी प्रगति की सूची में अदृश्य हो गया ........ सभी में सभी स्वीकार किए गए उत्तर ने चाल
चली
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.