कस्टम सूची दृश्य Android में आइटम पर क्लिक करें समस्या


110

इसलिए मेरे पास एक कस्टम सूची दृश्य ऑब्जेक्ट है। सूची आइटम में दो टेक्स्ट साक्षात्कार एक दूसरे के ऊपर रखे गए हैं, साथ ही एक क्षैतिज प्रगति पट्टी है जिसे मैं छिपाए रखना चाहता हूं जब तक कि मैं वास्तव में कुछ न करूं। अब तक दाईं ओर एक चेकबॉक्स है जिसे मैं केवल तब प्रदर्शित करना चाहता हूं जब उपयोगकर्ता को अपने डेटाबेस (नों) में अपडेट डाउनलोड करने की आवश्यकता होती है। जब मैं दृश्यता को दृश्यता पर सेट करके चेकबॉक्स को अक्षम करता हूं। तब, मैं सूची आइटम पर क्लिक करने में सक्षम हूं। जब चेकबॉक्स दिखाई देता है, तो मैं चेकबॉक्स को छोड़कर सूची में कुछ भी क्लिक करने में असमर्थ हूं। मैंने कुछ खोज की है लेकिन मेरी वर्तमान स्थिति के लिए प्रासंगिक कुछ भी नहीं मिला है। मुझे यह सवाल लगालेकिन जब से मैं डेटाबेस की सूची को आंतरिक रूप से शामिल करने के लिए ArrayLists का उपयोग कर रहा हूं, तब से मैं एक ओवरराइड ArrayAdapter का उपयोग कर रहा हूं। क्या मुझे बस लिनियर लयआउट देखने की जरूरत है और टॉम की तरह ऑनक्लिक्लिंटर को जोड़ना होगा? मुझे यकीन नहीं है।

यहाँ सूची पंक्ति लेआउट XML है:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="?android:attr/listPreferredItemHeight"
    android:padding="6dip">
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="0dip"
        android:layout_weight="1"
        android:layout_height="fill_parent">
        <TextView
            android:id="@+id/UpdateNameText"
            android:layout_width="wrap_content"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:textSize="18sp"
            android:gravity="center_vertical"
            />
        <TextView
            android:layout_width="fill_parent"
            android:layout_height="0dip"
            android:layout_weight="1"
            android:id="@+id/UpdateStatusText"
            android:singleLine="true"
            android:ellipsize="marquee"
            />
        <ProgressBar android:id="@+id/UpdateProgress" 
                     android:layout_width="fill_parent" 
                     android:layout_height="wrap_content"
                     android:indeterminateOnly="false" 
                     android:progressDrawable="@android:drawable/progress_horizontal" 
                     android:indeterminateDrawable="@android:drawable/progress_indeterminate_horizontal" 
                     android:minHeight="10dip" 
                     android:maxHeight="10dip"                    
                     />
    </LinearLayout>
    <CheckBox android:text="" 
              android:id="@+id/UpdateCheckBox" 
              android:layout_width="wrap_content" 
              android:layout_height="wrap_content" 
              />
</LinearLayout>

और यहां वह वर्ग है जो लिस्ट एक्टिविटी का विस्तार करता है। जाहिर है कि यह अभी भी विकास में है, इसलिए उन चीज़ों को माफ़ कर दें जो गायब हैं या जिन्हें आसपास छोड़ा जा सकता है:

public class UpdateActivity extends ListActivity {

    AccountManager lookupDb;
    boolean allSelected;
    UpdateListAdapter list;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        lookupDb = new AccountManager(this);
        lookupDb.loadUpdates();

        setContentView(R.layout.update);
        allSelected = false;

        list = new UpdateListAdapter(this, R.layout.update_row, lookupDb.getUpdateItems());
        setListAdapter(list);

        Button btnEnterRegCode = (Button)findViewById(R.id.btnUpdateRegister);
        btnEnterRegCode.setVisibility(View.GONE);

        Button btnSelectAll = (Button)findViewById(R.id.btnSelectAll);
        btnSelectAll.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
                allSelected = !allSelected;

                for(int i=0; i < lookupDb.getUpdateItems().size(); i++) {
                    lookupDb.getUpdateItem(i).setSelected(!lookupDb.getUpdateItem(i).isSelected());
                }

                list.notifyDataSetChanged();
                // loop through each UpdateItem and set the selected attribute to the inverse 

            } // end onClick
        }); // end setOnClickListener

        Button btnUpdate = (Button)findViewById(R.id.btnUpdate);
        btnUpdate.setOnClickListener(new Button.OnClickListener() {
            @Override
            public void onClick(View v) {
            } // end onClick
        }); // end setOnClickListener

        lookupDb.close();
    } // end onCreate


    @Override
    protected void onDestroy() {
        super.onDestroy();

        for (UpdateItem item : lookupDb.getUpdateItems()) {
            item.getDatabase().close();        
        }
    }

    @Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        super.onListItemClick(l, v, position, id);

        UpdateItem item = lookupDb.getUpdateItem(position);

        if (item != null) {
            item.setSelected(!item.isSelected());
            list.notifyDataSetChanged();
        }
    }

    private class UpdateListAdapter extends ArrayAdapter<UpdateItem> {
        private List<UpdateItem> items;

        public UpdateListAdapter(Context context, int textViewResourceId, List<UpdateItem> items) {
            super(context, textViewResourceId, items);
            this.items = items;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View row = null;

            if (convertView == null) {
                LayoutInflater li = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                row = li.inflate(R.layout.update_row, null);
            } else {
                row = convertView;
            }

            UpdateItem item = items.get(position);

            if (item != null) {
                TextView upper = (TextView)row.findViewById(R.id.UpdateNameText);
                TextView lower = (TextView)row.findViewById(R.id.UpdateStatusText);
                CheckBox cb = (CheckBox)row.findViewById(R.id.UpdateCheckBox);

                upper.setText(item.getName());
                lower.setText(item.getStatusText());

                if (item.getStatusCode() == UpdateItem.UP_TO_DATE) {
                    cb.setVisibility(View.GONE);
                } else {
                    cb.setVisibility(View.VISIBLE);
                    cb.setChecked(item.isSelected());
                }

                ProgressBar pb = (ProgressBar)row.findViewById(R.id.UpdateProgress);
                pb.setVisibility(View.GONE);
            }
            return row;
        }

    } // end inner class UpdateListAdapter
}

संपादित करें: मुझे अभी भी यह समस्या आ रही है। मैं पाठ्यपुस्तकों में ऑनक्लियर हैंडलर को धोखा दे रहा हूं और जोड़ रहा हूं लेकिन यह बहुत ही बेवकूफी भरा लगता है कि जब मैं अपने चेकबॉक्स पर क्लिक नहीं कर रहा हूं तो मेरे ऑनलिस्टस्टेमक्लिक () फ़ंक्शन को बिल्कुल भी नहीं बुलाया जा रहा है।

जवाबों:


243

मुद्दा यह है कि एंड्रॉइड आपको उन सूची आइटमों का चयन करने की अनुमति नहीं देता है, जिनमें उन पर ध्यान देने योग्य तत्व हैं। मैंने सूची आइटम पर चेकबॉक्स को संशोधित किया है ताकि एक विशेषता हो:

android:focusable="false"

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

संपादित करें: अद्यतन के रूप में, एक टिप्पणीकार ने उल्लेख किया "बस एक नोट, बटन की दृश्यता बदलने के बाद मुझे प्रोग्राम को फ़ोकस को फिर से अक्षम करना पड़ा।"


24
यह समाधान प्रकट नहीं होता है जब ImageButton सूची आइटम में उपयोग किया जाता है। :(
जूलियन ए।

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

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

2
महान जवाब धन्यवाद, ImageButtons के साथ भी अच्छा काम करता है। बस एक नोट, बटन की दृश्यता बदलने के बाद मुझे प्रोग्राम को फ़ोकस को फिर से अक्षम करना पड़ा।
Ljdawson

1
आपको एंड्रॉइड सेट करने की भी आवश्यकता हो सकती है: क्लिक करने योग्य = "झूठा"
मीना समी

43

यदि आपके पास सूची आइटम के अंदर ImageButton है तो आपको descendantFocusabilityरूट सूची आइटम तत्व में 'blockDescendants' का मान सेट करना चाहिए ।

android:descendantFocusability="blocksDescendants"

और देखने में focusableInTouchModeझंडा ।trueImageButton

android:focusableInTouchMode="true"

1
यह पूरी तरह से Imagebuttons होने वाले listitem के लिए काम करता है। लेकिन यह ImageButton को छोड़कर काम कर सकता है
raksja

12

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

मैं कहूंगा कि इस दृश्य ऑब्जेक्ट पर भी ध्यान दें, यह चेकबॉक्स से बेहतर काम कर सकता है

चेक किया हुआ पाठ दृश्य


6
मैंने पाया है कि यदि आप सूची में ध्यान देने योग्य वस्तुओं के लिए "फोकस करने योग्य" सेटिंग को गलत पर सेट करते हैं, तो आप फिर से अपने onListItemClick फ़ंक्शन का उपयोग कर सकते हैं।
मैट सिप

2
हालाँकि चेकबॉक्स नारंगी को सूची आइटम की तरह बदल देता है। किसी को भी एक समाधान पता है?
एरोमेडस्टर

8

सूची आइटम के मूल दृश्य में इस लाइन का उपयोग करें

एंड्रॉयड: descendantFocusability = "blocksDescendants"

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.