सूची में बटन के साथ सूची में onListItem पर क्लिक करें।


89

मेरे पास एक सरल ListActivity है जो सूची में विचार उत्पन्न करने के लिए एक कस्टम ListAdapter का उपयोग करता है। आम तौर पर लिस्ट एडॉप्टर केवल टेक्स्ट व्यू के साथ विचारों को भर देगा, लेकिन अब मैं वहां भी एक बटन रखना चाहता हूं।

हालाँकि यह मेरी समझ और अनुभव है कि सूची आइटम में फ़ोकस करने योग्य दृश्य डालने से सूची आइटम पर क्लिक करने पर ListActivity में onListItemClick () की फ़ायरिंग रुक जाती है। बटन अभी भी सूची आइटम के भीतर सामान्य रूप से कार्य करता है, लेकिन जब बटन के अलावा कुछ दबाया जाता है, तो मैं चाहता हूं कि onListItem क्लिक करें चालू हो जाए।

मै इसे काम मे कैसे ले सकता हूँ?


5
वंशज के साथ आपका समाधान फोकसबिलिटी वास्तव में सहायक है, आपको इसे एक उत्तर के रूप में जोड़ना चाहिए और इसे स्वीकार करना चाहिए!
मैक्सीम गोंटार

@ मोम कारण मैं नहीं है क्योंकि यह वास्तव में बुरा अभ्यास है, एक समाधान है। अगर मुझे कभी कोई स्थायी स्वस्थ समाधान मिला तो मैं उसे एक उत्तर दूंगा (अगर मुझे याद है कि मैंने यह सवाल एक साल पहले लिखा था :))
CodeFusionMobile

मुझे आपके द्वारा किए गए समाधान को भी देखना है। मैं वंश पर ध्यान केंद्रित करने की कोशिश कर रहा हूं और इसे बटन के साथ काम करने के लिए नहीं मिल सकता। इसके अलावा, मैं सूची पंक्ति में एक GridView (ImageViews के साथ) डालने की कोशिश कर रहा हूं और इसके समान मुद्दे हैं।
MrPurpleStreak

IMHO जवाब मैंने दिया समस्या के लिए और अधिक सुंदर समाधान है तो एक रैमप्स और प्रवीण द्वारा प्रस्तावित। PsNot यहाँ भूल सवाल को पुनर्जीवित करने की कोशिश कर रहा है, लेकिन मैं देख रहा हूँ यू में अभी तक कोई जवाब को स्वीकार नहीं किया, डी
Ewoks

@CodeFusionMobile क्या आप इवोक का जवाब स्वीकार कर सकते हैं? उच्चतम मत वाला उत्तर त्रुटिपूर्ण है क्योंकि यह सूची दृश्य तत्व (जहां यह नीला हो जाता है) के लिए ओनक्लिक एनीमेशन को निष्क्रिय कर देता है। यह अन्य डेवलपर्स को बचाने के लिए कुछ समय खर्च करता है शीर्ष उत्तर की कोशिश कर रहा है, यह पता लगाता है कि यह त्रुटिपूर्ण है, और फिर इवोक्स पर जा रहा है।
1 ''

जवाबों:


99

जैसा कि मैंने पिछले कमेंट सॉल्यूशन में लिखा था, इमेजबटन पर फ़ोकस करने योग्य (झूठा) सेट करना।

सूची तत्व के android:descendantFocusability="blocksDescendants" रूट लेआउट में जोड़ने के लिए और भी अधिक सुंदर समाधान है । यह क्लिक को संभव बनाता है और इसे अलग से बटन या छवि बटन पर क्लिक कर सकता है

आशा करता हूँ की ये काम करेगा ;)

चियर्स


3
android:descendantFocusability="blocksDescendants"उत्तम था।
मैथ्यू मिशेल

1
आप, मेरे दोस्त, मेरे निजी हीरो हैं। आप शीर्ष मतदाता होना चाहिए! यह लगभग किसी भी मामलों के लिए बहुत बेहतर है!
OschtärEi

यह स्वीकृत उत्तर होना चाहिए। इसने मेरे लिए पूरी तरह से काम किया। ऐसा लगता है कि सूची आइटम के सभी दृश्य अपरिवर्तनीय होने की आवश्यकता है और यह प्रत्येक व्यक्ति को अलग-अलग सेट किए बिना बस ऐसा करता है।
भीड़

1
यह मेरे लिए काम नहीं करता है। रूट लेआउट से, क्या आपका मतलब पंक्ति लेआउट या जहां सूची को परिभाषित किया गया है? किसी भी तरह, मैंने सभी संभावित संयोजनों की कोशिश की .. काम नहीं कर रहा है :(
ग्रीनबी

"लिस्ट एलीमेंट का रूट लेआउट" जैसा कि मैंने लिखा है .. तो मान लीजिए कि आपके पास लिस्ट और लेआउट्स से मिलकर बने (लिस्ट एलिमेंट ऑफ रूट एलिमेंट) जिसमें कई बटन, ImageButton, TextVeiw हैं
Ewoks

59

मुझे उम्मीद है कि मैं यहां मदद कर सकता हूं। मैं मानता हूं कि आपके पास listView आइटम के लिए कस्टम लेआउट है, और इस लेआउट में बटन और कुछ अन्य दृश्य शामिल हैं - जैसे TextView, ImageView या जो भी हो। अब आप अलग-अलग ईवेंट को बटन क्लिक पर निकाल देना चाहते हैं और अलग-अलग ईवेंट को क्लिक की गई हर चीज पर निकाल दिया जाता है।

आप अपने ListActivity के onListItemClick () का उपयोग किए बिना इसे प्राप्त कर सकते हैं।
यहाँ आपको क्या करना है:

आप कस्टम लेआउट का उपयोग कर रहे हैं, इसलिए शायद आप अपने कस्टम एडाप्टर से getView () विधि को ओवरराइड कर रहे हैं। चाल आपके बटन के लिए अलग श्रोताओं और पूरे दृश्य (आपकी पंक्ति) के लिए अलग सेट करने के लिए है। उदाहरण पर एक नज़र डालें:

private class MyAdapter extends ArrayAdapter<String> implements OnClickListener {

    public MyAdapter(Context context, int resource, int textViewResourceId,
            List<String> objects) {
        super(context, resource, textViewResourceId, objects);
    }


    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        String text = getItem(position);
        if (null == convertView) {
            convertView = mInflater.inflate(R.layout.custom_row, null);
        }
        //take the Button and set listener. It will be invoked when you click the button.
        Button btn = (Button) convertView.findViewById(R.id.button);
        btn.setOnClickListener(this);
        //set the text... not important     
        TextView tv = (TextView) convertView.findViewById(R.id.text);
        tv.setText(text);
        //!!! and this is the most important part: you are settin listener for the whole row
        convertView.setOnClickListener(new OnItemClickListener(position));
        return convertView;
    }

    @Override
    public void onClick(View v) {
        Log.v(TAG, "Row button clicked");
    }
}

आपका OnItemClickListener वर्ग यहाँ की तरह घोषित किया जा सकता है:

private class OnItemClickListener implements OnClickListener{       
    private int mPosition;
    OnItemClickListener(int position){
        mPosition = position;
    }
    @Override
    public void onClick(View arg0) {
        Log.v(TAG, "onItemClick at position" + mPosition);          
    }       
}

बेशक आप शायद OnItemClickListener कंस्ट्रक्टर में कुछ और पैरामीटर जोड़ देंगे।
और एक महत्वपूर्ण बात - ऊपर दिखाए गए getView का कार्यान्वयन बहुत बदसूरत है, सामान्य रूप से आपको ViewViewById कॉल से बचने के लिए ViewHolder पैटर्न का उपयोग करना चाहिए .. लेकिन आप शायद पहले से ही जानते हैं।
मेरा custom_row.xml फ़ाइल RelativeLayout बटन के साथ "बटन", आईडी का TextView "पाठ" और आईडी का ImageView "छवि" है - बस चीजों को स्पष्ट करने के लिए।
सादर!


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

3
मैंने इस समाधान का उपयोग किया। हालाँकि, एक चेतावनी: यदि आपका ऑनक्लियर हैंडलर सूची की सामग्री को बदलने का कारण बनता है, जिसके परिणामस्वरूप getView कहा जा रहा है और यदि आपका विजेट स्टेटस है (जैसे ToggleButton या चेकबॉक्स), और getView उस स्थिति को सेट करता है, तो आपOnClickListener को सेट करना चाहते हैं (null) इससे पहले कि आप लूप इफ़ेक्ट पाने से बचने के लिए राज्य को onView में बदल दें।
पियरे-ल्यूक पाऊर

3
मेरे समाधान के बारे में क्या? मुझे आभास है कि यह अधिक सुरुचिपूर्ण है और जब भी हमें इसकी आवश्यकता हो, तब इसे आसानी से लागू किया जा सकता है ..
इवोक

पहली टिप्पणी को उत्तर के रूप में स्वीकार किया जाना चाहिए, इसलिए मेरे जैसे लोगों को इसे खोजने के लिए घंटों की आवश्यकता नहीं होगी
कीबी

धन्यवाद! यह उपयोगी था। मैं इसे फ़ोकस के अधिक स्थानीय विकल्प के रूप में पसंद करता हूं: अन्य थ्रेड्स में वर्णित ब्लॉकडेसेंडेंट्स दृष्टिकोण।
योव शपीरा

18

जब एक कस्टम सूची दृश्य में ध्यान देने योग्य तत्व शामिल होते हैं, तो onListItemClick काम नहीं करेगा (मुझे लगता है कि यह अपेक्षित व्यवहार है)। बस कस्टम दृश्य से ध्यान हटा दें, यह चाल करेगा:

उदाहरण के लिए:

public class ExtendedCheckBoxListView extends LinearLayout {

    private TextView mText;
    private CheckBox mCheckBox;

    public ExtendedCheckBoxListView(Context context, ExtendedCheckBox aCheckBoxifiedText) {
         super(context);
         
         mText.setFocusable(false);
         mText.setFocusableInTouchMode(false);

         mCheckBox.setFocusable(false);
         mCheckBox.setFocusableInTouchMode(false);
               
    }
}

3
मुझे आपका समाधान पसंद है: यदि प्रति पंक्ति में केवल एक "क्लिक करने योग्य" विजेट है, तो उन्हें ध्यान केंद्रित करने से इनकार करना एक सुरुचिपूर्ण समाधान है। इसका मतलब यह है कि पंक्ति पर कहीं भी एक टैप मेल खाएगा, लेकिन यह एक उपयोगी व्यवहार है जब विजेट एक रेडियो या चेकबॉक्स है। XML को एंड्रॉइड के उपयोग से प्राप्त किया जा सकता है: फ़ोकस करने योग्य = "झूठा" और Android: focusableInTouchMode = "false"।
पियरे-ल्यूक पाऊर

1
अगर आप दृश्यता को बदलते हैं तो xml तरीका काम नहीं करता है, इसलिए किसी को "दृश्य" को दृश्यमान पर सेट करने के बाद कोड के माध्यम से करना होगा
अधिकतम 4

13

मैं एक ही समस्या है: OnListItem क्लिक करें निकाल नहीं दिया! [SOLVED]
ऐसा वर्ग पर होता है, जो ListActivity का विस्तार करता है,
जिसमें ListActivity के लिए एक लेआउट होता है, जिसमें TextBox और ListView ने रेखीय लयआउट में
और पंक्तियों के लिए एक अन्य लेआउट (एक चेकबॉक्स और LinBoxLayout में नेस्टेड) ​​के रूप में सूचीबद्ध होता है।

यह कोड है:

रेस / लेआउट / configpage.xml (ListActivity के लिए मुख्य)

<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent" > 
    <TextView  
        android:id="@+id/selection"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:text="pippo" /> 
    <ListView  
        android:id="@android:id/list"  
        android:layout_width="fill_parent"  
        android:layout_height="wrap_content"  
        android:drawSelectorOnTop="false"  
        android:background="#aaFFaa" > 
    </ListView> 
<LinearLayout> 

res/layout/row.xml (layout for single row)  
<LinearLayout  
  xmlns:android="http://schemas.android.com/apk/res/android"  
  android:layout_width="fill_parent"  
  android:layout_height="wrap_content"> 
  <CheckBox  
      android:id="@+id/img"  
      android:layout_width="wrap_content"  
      android:layout_height="wrap_content"  
      **android:focusable="false"**  
      **android:focusableInTouchMode="false"** /> 

  <TextView  
      android:id="@+id/testo"  
      android:layout_width="wrap_content"  
      android:layout_height="wrap_content"  
      **android:focusable="false"**  
      **android:focusableInTouchMode="false"** /> 
</LinearLayout> 

src /.../.../ configPage.java

public class ConfigPage extends ListActivity
{
    TextView selection;

    public void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.configpage);  
        // loaded from res/value/strings  
        String[] azioni = getResources().getStringArray(R.array.ACTIONS);  
        setListAdapter(new ArrayAdapter&lt;String&gt;(this, R.layout.row, 
                R.id.testo,   azioni));  
        selection = (TextView) findViewById(R.id.selection);  
    }       

    public void onListItemClick(ListView parent, View view, int position, long id)
    {
        selection.setText(" " + position);
    }
}

जब मैंने row.xml पर जोड़ा तो यह काम करना शुरू कर देता है

  • android:focusable="false"
  • android:focusableInTouchMode="false"

मैं ग्रहण 3.5.2
एंड्रॉइड एसडीके 10.0.1
मिनट एसडीके संस्करण का उपयोग करता हूं : 3

मुझे आशा है कि यह उपयोगी है
... और मेरे अंग्रेजी के लिए खेद है :(


@fellons पता नहीं क्यों, लेकिन यह मेरे लिए काम नहीं किया। मेरे onListItemClick को नहीं बुलाया जा रहा है।
likejudo

क्या आपने गुण कोड android जोड़ा है: focusable = "false" और android: focusableInTouchMode = "false" कोड?
10

2

बस android:focusable="false"अपने बटन की विशेषताओं में से एक के रूप में जोड़ें


1

मुझे ToggleButton के साथ भी यही समस्या है। एक दीवार के खिलाफ मेरे सिर को पीटने के आधे दिन के बाद मैंने आखिरकार इसे हल कर दिया। यह 'एंड्रॉइड: फोकस करने योग्य' का उपयोग करके फ़ोकस करने योग्य दृश्य को अन-फ़ोकस करने योग्य बनाने जितना आसान है। आपको सूची पंक्ति के फ़ोकसबिलिटी और क्लिक करने की क्षमता (मैं सिर्फ शब्दों से बना है) के साथ खेलने से बचना चाहिए, बस उन्हें डिफ़ॉल्ट मान के साथ छोड़ दें।

बेशक, अब जब सूची पंक्ति में आपके ध्यान देने योग्य विचार अन-फ़ोकस हैं, तो कीबोर्ड का उपयोग करने वाले उपयोगकर्ताओं को समस्या हो सकती है, ठीक है, उन्हें ध्यान केंद्रित करना। यह एक समस्या होने की संभावना नहीं है, लेकिन सिर्फ अगर आप 100% निर्दोष ऐप्स लिखना चाहते हैं, तो आप चयनित पंक्ति के तत्वों को ध्यान केंद्रित करने और पहले से चयनित पंक्ति के तत्वों को ध्यान केंद्रित करने के लिए onItemSelected घटना का उपयोग कर सकते हैं।


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

1
 ListView lv = getListView();
lv.setTextFilterEnabled(true);

lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
    int position, long id) {
  // When clicked, show a toast with the TextView text
  Toast.makeText(getApplicationContext(), ((TextView) view).getText(),
      Toast.LENGTH_SHORT).show();
}
});

-1

मैंने getListAdapter ()। GetItem (स्थिति) का उपयोग उस वस्तु को तत्काल करने के लिए किया है जो आइटम के भीतर मेरे मूल्यों को रखती है

MyPojo myPojo = getListAdapter().getItem(position);

तब myPojo से प्राप्त करने वाली विधि का उपयोग किया यह आइटम के भीतर अपने उचित मूल्यों को बुलाएगा।

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