ListView addHeaderView एक के द्वारा स्थिति बढ़ाने का कारण बनता है?


97

नीचे एक सूची दृश्य के साथ एक कोड स्निपेट है। मैंने एक खाली दृश्य और एक शीर्ष लेख जोड़ा। शीर्षलेख दृश्य को जोड़ने से ऑन इटेम में स्थिति एक हो जाती है।

तो शीर्ष लेख के बिना पहली सूची तत्व की स्थिति 0 होगी, शीर्ष लेख के साथ पहली सूची तत्व की स्थिति 1 होगी!

यह मेरे एडाप्टर में त्रुटि का कारण बनता है, उदाहरण के लिए जब getItem () और कुछ अन्य तरीकों का उपयोग करते हुए, नीचे देखें। अजीब बात है: एडेप्टर की getView () विधि में पहली सूची तत्व को स्थिति 0 के साथ अनुरोध किया जाता है, भले ही शीर्ष लेख दृश्य जोड़ा गया हो !!

public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    ListView list = (ListView) viewSwitcher.findViewById(R.id.list);
    View emptyView = viewSwitcher.findViewById(R.id.empty);
    list.setEmptyView(emptyView);

    View sectionHeading = inflater.inflate(R.layout.heading, list, false);
    TextView sectionHeadingTextView = (TextView) sectionHeading.findViewById(R.id.headingText);
    sectionHeadingTextView.setText(headerText);
    list.addHeaderView(sectionHeading);

    list.setAdapter(listAdapter);

    list.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            listAdapter.getItem(position);
            //Do something with it
        }
    });
}

कुछ एडॉप्टर तरीके:

@Override
public int getViewTypeCount() {
    return TYPE_COUNT;
}

@Override
public int getItemViewType(int position) {
    return (position < items.size()) ? ITEM_NORMAL : ITEM_ADVANCED;
}

    @Override
public Product getItem(int position) {
    return items.get(position);
}
@Override
public boolean areAllItemsEnabled() {
    return false;
}

@Override
public boolean isEnabled(int position) {
    return (position < items.size());
}

क्या शीर्ष लेख जोड़ते समय यह सामान्य व्यवहार है ?? और मेरे एडॉप्टर में मुद्दों को कैसे दूर किया जाए?


1
आपके सवाल का मेरे सवाल का जवाब था। +1
शशांक देग्लोर्कर

जवाबों:


113

मैं तो बस सबसे अच्छा तरीका है का उपयोग करने लगता है इस समस्या में आए और ListView.getItemAtPosition(position)के बजाय ListAdapter.getItem(position)के रूप में ListViewसंस्करण हेडर, यानी के लिए खातों: -

इसके बजाय यह करें:

myListView.getItemAtPosition(position)

1
बिल्कुल सही! onItemClickआपको एक parentकारण के लिए देता है । आप उपयोग कर सकते हैंparent.getItemAtPosition(position)
ब्रिस गाबिन

3
यह वास्तव में मेरे लिए काम नहीं करता है, जबकि @whuandroid सजाया / आवरण एडाप्टर समाधान का उपयोग करता है।
डोरी

3
इस मामले में भी आपको आइटम कास्ट करना होगा।
njzk2

मेरे लिए भी काम नहीं करता है, भले ही मैं माता-पिता को ListView में डालूं। मुझे बस पद == 0 ... पर शासन करने की आवश्यकता है
PawelP

मेरे लिए काम नहीं करता है। AdapterViewयह भी सिर्फ सूची ऐडेप्टर के लिए नीचे गुजरता है। return (adapter == null || position < 0) ? null : adapter.getItem(position);
फिलिप

31

यदि आप हेडर के लिए क्लिक की परवाह नहीं करते हैं, तो अपने एडेप्टर के लिए स्थिति प्राप्त करने के लिए स्थिति से हेडर दृश्यों की संख्या घटाएं:

        listView.addHeaderView(inflater.inflate(
                R.layout.my_hdr_layout, null), null, false);
        listView.setAdapter(m_adapter);
        listView.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view,
                int position, long id) {
            position -= listView.getHeaderViewsCount();
            final MyObject object = m_adapter.getItem(position);

        }
    });

यह सबसे अच्छा उत्तर होना चाहिए, मैं हेडर के बारे में परवाह नहीं कर रहा हूं, मैं सुनने वाले की परवाह करता हूं।
निंजा

मुझे लगता है कि इस समाधान के लिए नवीनतम ओएस 7.0 काम नहीं करता है
शा

27

यदि आप एक हेडर जोड़ते हैं ListViewजो सूची में पहला आइटम बन जाता है। आप getCount()एक आइटम को कम वापस करने के लिए ओवरराइड करके इसके लिए क्षतिपूर्ति कर सकते हैं , लेकिन सुनिश्चित करें कि आप हैंडल करें getItem(), getItemId()और इसी तरह हेडर भी आइटम 0 की स्थिति में होगा।


6
GetCount () को किसी आइटम को वापस करने के लिए ओवरराइड करना कम काम नहीं करता है, क्योंकि तब मुझे सूची के अंतिम सूची आइटम की याद आती है। यदि सूची में केवल 1 आइटम है तो getView () को कभी नहीं बुलाया जाता है। इसके अलावा एडॉप्टर को लिस्टव्यू से हटा दिया गया है और यह नहीं पता है कि लिस्ट में हेडर जोड़ा गया था या नहीं।
d1rk

2
ListItemClick सेट स्थिति = स्थिति - 1 में यदि कोई शीर्ष लेख संलग्न है, तो मुझे लगता है कि मैंने जो किया है जब मैंने इस विशेष मुद्दे का सामना किया है, तो यह बहुत साफ नहीं है, लेकिन एकमात्र तरीका जो मैं सोच सकता हूं
akshaydashrath

3
मुझे लगता है कि आपके द्वारा सुझाए गए OnItemClickListener में स्थिति = स्थिति- (जोड़े गए हेडवर्वी की संख्या) सेट करने का सबसे आसान तरीका होगा। मैंने हेडव्यू को स्वयं संभालने के लिए अपना एडेप्टर बदल लिया, इस प्रकार मुझे सूची में addHeaderView को कॉल करने की आवश्यकता नहीं है। हालांकि एडॉप्टर थोड़ा और अधिक जटिल हो गया।
d1rk

22
"जोड़ा गया हेडर्व्यू की संख्या" के साथ प्राप्त किया जा सकता है:ListView.getHeaderViewsCount()
जॉन

2
मैं नहीं देखता कि यह सही उत्तर कैसे है। @ इयान वारविक ने सही पोस्ट किया है, हालांकि मुझे लगता है कि थोड़ी देर हो चुकी है।
सीदोन

14

लागू करते समय AdapterView.OnItemClickListenerहम सिर्फ हेडर को स्थिति से घटाते हैं।

@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
    position -= mListView.getHeaderViewsCount();
    // what ever else follows...
}

13

किसी भी कोड को बदलने की आवश्यकता नहीं है। बस नीचे दिए गए कोड का उपयोग करें।

 list.setOnItemClickListener(new OnItemClickListener() {
     @Override
     public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
      parent.getAdapter().getItem(position);
         //Do something with it
     }
});

1
यह आमतौर पर कास्टिंग की आवश्यकता होगी, क्योंकि वापस किया जा रहा आइटम सिर्फ "ऑब्जेक्ट" है।
Android डेवलपर

9

अपने एडेप्टर का उपयोग न करें, getAdapter से 'सजा हुआ' एडॉप्टर का उपयोग करें।


+1 यह IMO जाने का तरीका है - आपके द्वारा सप्लाई किया जाने वाला एडेप्टर एक अन्य अडैप्टर से लिपटा होता है जो हेडर की आपूर्ति करते समय इंडेक्स ऑफसेट को ध्यान में रखता है। इसके लिए यह कोड इस का उपयोग कर रहा है @Ramesh द्वारा इस पृष्ठ पर कहीं और दिया गया है (+1 आप भी!)
Dori

5

इसका एक हल आईडी को इंडेक्स में मैप करना है। मूल रूप से आईडी को सूची में वापस लौटाएं और क्लिक श्रोता करेंगे:

public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            listAdapter.getItem((int) id);
}

3

नमस्ते, हम इसे इस तरह से हल कर सकते हैं पहले आप अपना हेडर दृश्य बनाएं, अपनी सूची में इंजेक्ट करने के बाद और अंतिम चरण में सेटऑनक्लॉकरटेकर को असमर्थ कर दें। यह मेरे लिए काम करता है। किसी भी प्रतिक्रिया का स्वागत करते हैं

ViewGroup headerView = (ViewGroup) getLayoutInflater().inflate(R.layout.your_header, list,false);
list.addHeaderView(headerView);
headerView.setEnabled(false);
headerView.setOnClickListener(null);

यह उत्तरों की सूची में नीचे है, लेकिन यह वास्तव में उपयोगी है। यदि आप इन परिवर्तनों को नहीं करते हैं, तो आपके शीर्षलेख दृश्य क्लिक करने योग्य रहेंगे, रिपल इफेक्ट्स आदि के साथ ..
स्कॉट फर्ग्यूसन

0

ज्यादा नया जोड़ने के लिए नहीं है कि @Ramesh नहीं जोड़ा लेकिन कुछ अतिरिक्त संदर्भ:

personList.setOnItemClickListener(new OnItemClickListener() {
    @SuppressWarnings("unchecked")
    public void onItemClick( AdapterView<?> parent, View view, int position, long duration) {
        Map<String, Object> person = (Map<String, Object>) parent.getAdapter().getItem(position);
        if (person != null){

            // If the header was clicked on a null  is returned

            OnPersonUiChangeListener listener = (OnPersonUiChangeListener) getActivity();
            listener.onSelectedPersonChanged(person);
        }
    }
});

0

GetSelectedItemPosition का उपयोग करें () एडाप्टर के डेटा सेट के भीतर वर्तमान में चयनित आइटम की स्थिति लौटाएं। इस विधि को हेडर या पाद के आकार के बारे में चिंता करने की आवश्यकता नहीं है।


0

यह किसी को मदद कर सकता है, फरीद_ज़ और फिलिप के जवाब में सुधार करते हुए, हम सही तरीके से सेट इट को लागू कर सकते हैं और कुछ इस तरह से सेट करें।

        FragmentManager fragmentManager = getSupportFragmentManager();
        fragmentManager.beginTransaction().replace(R.id.content_frame, fragment).commit();
        position += 1;
        mDrawerList.setItemChecked(position, true);
        mDrawerList.setSelection(position);
        position -= 1;
        setTitle(mNavigationDrawerItemTitles[position]);
        mDrawerLayout.closeDrawer(mDrawerList);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.