2010-05-28 14 views
9

एंड्रॉइड में, onContextItemSelected में एक MenuItem तर्क है और इसलिए यह स्पष्ट नहीं है कि चयनित दृश्य की पहचान कैसे करें। MenuItem.getMenuInfoContextmenu.ContextMenuInfo तक पहुंच प्रदान करता है, लेकिन दोनों ज्ञात उप-वर्ग लक्षित दृश्य तक पहुंच प्रदान करते हैं, तो इंटरफ़ेस पर कोई एक्सेसर नहीं दिखता है।कॉन्टेक्स्टमेनू (एंड्रॉइड) में चयनित दृश्य की पहचान

एक वैकल्पिक एक निजी वर्ग चर जो onContextItemSelected से पहले गतिविधियों में फिर से onCreateContextMenu नहीं बुलाया जा रहा है पर निर्भर करता है में बचाने के लिए onCreateContextMenu में View प्रदान की है। itemIdContextMenu.add के तर्क के लिए View की आईडी का उपयोग करना है। यदि हम ऐसा करते हैं, तो हमें इसके (संभावित रूप से अंतर्राष्ट्रीयकृत) शीर्षक का उपयोग करके संदर्भ मेनू से चुने गए विकल्प की पहचान करने की आवश्यकता होगी।

onContextSelected में चयनित View की पहचान करने के लिए सबसे अच्छी विधि क्या है?

+0

यह भी देखें: http://stackoverflow.com/questions/2321332/detecting-which-selected-item-in-a-listview-spawned-the-contextmenu-android –

उत्तर

9

एंड्रॉइड में विकल्प मेनू या संदर्भ मेनू के लिए "चयनित दृश्य की पहचान" जैसी कोई अवधारणा नहीं है। इसलिए, आपके प्रश्न का उत्तर देना मुश्किल है। तो, मैं कुछ अनुमान ले जाऊंगा।

तुम्हारा मतलब जो मेनू विकल्प का चयन किया गया "चयनित दृश्य की पहचान" द्वारा, तो उस getItemId()MenuItem कि onOptionsItemSelected() या onContextItemSelected() में भेजा जाता है पर है।

तुम्हारा मतलब द्वारा "चयनित दृश्य की पहचान" अगर में जो पंक्ति एक ListView था एक लंबे समय से उपयोग किया पर संदर्भ मेनू ऊपर लाने के लिए, कच्चा getMenuInfo(), AdapterView.AdapterContextMenuInfo को (MenuItem पर कहा जाता है) तो या तो id या आपके एडाप्टर के आधार पर उपयुक्त position मान। See here for a sample project जो इस तकनीक का उपयोग करता है।

यदि "चयनित दृश्य की पहचान" करके आपका मतलब है कि आपके पास एक गतिविधि में एक से अधिक गैर-ListView संदर्भ मेनू है, तो मैं उस UI तकनीक का उपयोग नहीं करूंगा।

+0

मेरा मतलब तीसरा विकल्प था, सामान्य रूप से वहां स्क्रीन पर कई विचार हो सकते हैं और उनमें से कुछ एक ही संदर्भ मेनू चाहते हैं। आप उस यूआई तकनीक का उपयोग क्यों नहीं करेंगे? – Casebash

+1

सरल: संदर्भ मेनू के लिए कोई दृश्य संकेत नहीं हैं। एंड्रॉइड उपयोगकर्ताओं का एक छोटा प्रतिशत संदर्भ मेनू के लिए सूचियों पर लंबे समय तक टैप करना जानता है। संदर्भ मेनू के लिए किसी और चीज पर लंबे समय तक टैप करने की कोशिश करने से कोई भी परेशान नहीं होगा। संदर्भ मेनू के माध्यम से जो कुछ भी आप ऑफ़र करते हैं, उसे कम से कम एक अन्य तंत्र द्वारा पेश किया जाना चाहिए, केवल बेहतर खोज योग्यता के लिए। पावर उपयोगकर्ताओं को 'ListView' संदर्भ मेनू मिल सकता है, और इसलिए नेविगेशन को तेज़ करने के लिए उन लोगों की पेशकश ठीक है। 'ListViews' के अलावा अन्य चीज़ों पर संदर्भ मेनू? मैं बस परेशान नहीं होगा। – CommonsWare

+0

अच्छे अंक, लेकिन आप @reply मुझे भूल गए। मान लीजिए कि आपको एकाधिक संदर्भ मेनू का उपयोग करना था। आप किस विधि का उपयोग करेंगे? – Casebash

6

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

अन्य पदों की सिफारिश के रूप में है, कुछ संदर्भों के लिए:

AdapterView.AdapterContextMenuInfo menuInfo = 
(AdapterView.AdapterContextMenuInfo)item.getMenuInfo(); 

उचित है और targetView एक उपयोगी संदर्भ बिंदु है।

दृश्य संदर्भ प्रदान करने के लिए दृश्य को उपclass और 'getContextMenuInfo' ओवरराइड करना एक और तरीका है। उदाहरण के लिए, एक साधारण TextView:

 
package ...; 

public class TextViewWithContext extends TextView { 
    TextViewContextMenuInfo _contextMenuInfo = null; 

    public TextViewWithContext(Context context) { 
     super(context); 
     _contextMenuInfo = new TextViewContextMenuInfo(this); 
    } 

    public TextViewWithContext(Context context, AttributeSet attrs) { 
     super(context, attrs); 
     _contextMenuInfo = new TextViewContextMenuInfo(this); 
    } 

    protected ContextMenuInfo getContextMenuInfo() { 
     return _contextMenuInfo; 
    } 

    public boolean isContextView(ContextMenuInfo menuInfo) { 
     return menuInfo == (ContextMenuInfo)_contextMenuInfo; 
    } 

    protected class TextViewContextMenuInfo implements ContextMenuInfo { 
     protected TextView _textView = null; 

     protected TextViewContextMenuInfo(TextView textView) { 
      _textView = textView; 
     } 
    } 
} 

... 
    @Override 
    public boolean onContextItemSelected(MenuItem item) { 

     ContextMenuInfo menuInfo = item.getMenuInfo(); 

     if (textViewWithContext.isContextView(menuInfo) { 
      ... 
     } 
    } 

अंत में, यह अधिक उपयोगी हो गया होता अगर आधार देखें वर्ग को देखने के लिए एक रिवर्स संदर्भ के साथ एक ContextInfo वस्तु सौंपा था, बल्कि वर्तमान में के रूप में अशक्त से।

+0

मैंने इस दृष्टिकोण का उपयोग करके नमूना ऐप तैयार किया है: http://ogrelab.ikratko.com/identifying-the-view-selected-in-a-contextmenu-in-oncontextitemselected-method/ – Ognyan

2

वर्ग परीक्षण गतिविधि गतिविधि {

// create temp item here 

private ImageView tmpImageView = null; 

फैली ...

public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo){ 
    super.onCreateContextMenu(menu, v, menuInfo); 
    // initialize temp item 
    mCurrentStatusImage = (ImageView) v.findViewById(R.id.rule_status); 
} 

public boolean onContextItemSelected(MenuItem item) { 
    switch (item.getItemId()) { 
     case ENABLE_ID: 
      // use temp item 
      tmpImageView.setImageResource(android.R.drawable.presence_online); 
      return super.onContextItemSelected(item); 
     case DISABLE_ID: 
      // use temp item 
      tmpImageView.setImageResource(android.R.drawable.presence_invisible); 
      return super.onContextItemSelected(item); 
     default:  
      return super.onContextItemSelected(item); 
} 
1

मैं जो आइटम पर आधारित MenuItem के लिए एक ग्रुप की स्थापना करके एक ऐसी ही समस्या तय इसे भेजा जैसे:

textview.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() { 
     @Override 
     public void onCreateContextMenu(ContextMenu menu, View view, ContextMenu.ContextMenuInfo contextMenuInfo) { 
       menu.setHeaderTitle("Context Menu"); 
       menu.add(R.id.whateverviewclicked, RENAME_MENU_ITEM, 0, "Rename"); 
       menu.add(R.id.whateverviewclicked, DELETE_MENU_ITEM, 1, "Delete"); 
      } 
     }); 

यह आपको onContextItemSelected में ग्रुप प्राप्त करने की अनुमति होगी:

public boolean onContextItemSelected(MenuItem aItem) { 
     int selectedViewID = aItem.getGroupId(); 
     int selectedItem = aItem.getItemId(); 
}; 

आपको संसाधन आईडी का उपयोग करने की आवश्यकता नहीं है - आप जो भी int चाहते हैं उसका उपयोग कर सकते हैं। मेरे लिये कार्य करता है!

1

यदि आप ContextMenus को कई दृश्यों में संलग्न कर रहे हैं जो सूची दृश्य में नहीं हैं (जो दृश्यों के अंतर्गत कोई एडाप्टर नहीं है) और आप यह निर्धारित करना चाहते हैं कि ContextMenu को "हैक" तक पहुंचने के लिए कौन सा दृश्य लंबे समय से दबाया गया था लागू किया जा सकता है। (यह बेहतर होगा अगर एंड्रॉइड ने एक श्रोता प्रदान किया जो प्रत्येक आइटम से जुड़ा हो)।

private View.OnTouchListener onTouchListener = new View.OnTouchListener() { 
    @Override 
    public boolean onTouch(View view, MotionEvent motionEvent) 
    { 
     mLastViewTouched = view;  // Store a handle on the last view touched. This will be used to identify the view on which the Context Menu was launched 

     return false;  // We return false since this indicates that the touch was not handled and so it is passed down the stack to be handled appropriately 
    } 
}; 

तो जब भी एक दृश्य को छुआ है mLastViewTouched है:

"हैक" एक कक्षा में एक निजी देखें सदस्य mLastViewTouched बनाता है और फिर सब दृश्य है कि एक ContextMenu उत्पन्न कर सकते हैं के लिए निम्न onTouchListener देते हैं वह यह है कि अपडेट किया गया। अब onContextItemSelected में आपको उस दृश्य तक पहुंच होगी जिसने ContextMenu की शुरुआत की थी।

0

जब OnCreateContextMenuListener या public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) कार्यान्वयन में अपने मेनू का निर्माण, आप प्रत्येक आइटम के लिए एक कस्टम MenuItem.OnMenuItemClickListener सेट कर सकते हैं:

addPhotosBtn.setOnCreateContextMenuListener((menu, v, menuInfo) -> { 
     getMenuInflater().inflate(R.menu.upload_image_menu, menu); 
     int itemCount = menu.size(); 
     for(int i = 0; i < itemCount; i++) { 
      menu.getItem(i).setOnMenuItemClickListener(addPhotosBtnMenuItemClickListener); 
     } 
    }); 

इस समय आप दृश्य है जिसके लिए आप संदर्भ मेनू पैदा कर रहे की पहुंच है पर बाद से, आप उस दृश्य के साथ श्रोता को कसकर जोड़ सकते हैं।

संबंधित मुद्दे