2012-03-17 7 views
22

मेरे पास एक ऐप है जो ViewPager में कुछ टुकड़े (उसी प्रकार का) दिखाता है और मुझे संदर्भ मेनू आइटमों में कुछ परेशानी हो रही है। (मैं समर्थन पुस्तकालय का उपयोग कर रहा हूँ)।व्यूपेजर में गलत खंड को कॉन्टेक्स्ट इटैम चयन प्राप्त करता है

जब किसी खंड में संदर्भ मेनू में संदर्भ मेनू आइटम चुना जाता है, तो गलत खंड onContextItemSelected ईवेंट कॉल प्राप्त कर रहा है।

उदाहरण के लिए, यदि मैं पेजर में खंड # 3 पर हूं, तो स्थिति # 2 पर खंड इसके बजाय प्राप्त करता है। अगर मैं वापस खंड # 2 पर स्वाइप करता हूं, तो खंड # 3 को इसके बजाय कॉल प्राप्त होता है।

मुझे नमूना here मिला है।

(मैं वर्तमान में प्रत्येक खंड में mHandleContext चर करके अपने पृष्ठ में इस पर काम कर रहा हूं और पेज बदलते समय इसे सक्षम/अक्षम कर रहा हूं। इस तरह onContextItemSelected कॉल दाएं तक सभी टुकड़ों तक जायेगा एक कहा जाता है।)

क्या मैं कुछ गलत कर रहा हूं या यह समर्थन पुस्तकालय के साथ एक बग है? एक साइड नोट के रूप में, ऐसा तब नहीं हुआ जब मैं एक्शनबैरशॉक 3.5.1 का उपयोग कर रहा था, जिसका समर्थन पुस्तकालय का अपना कांटा था।

+1

संभव डुप्लिकेट [एक बहु टुकड़ा गतिविधि में onContextItemSelected को संभालने के लिए कैसे] (http://stackoverflow.com/questions/5297842/how-to-handle-oncontextitemselected-in-a-multi-fragment-activity) –

उत्तर

33

तो यह गूगल द्वारा मूर्खतापूर्ण डिज़ाइन निर्णय या कुछ है कि बस पूरी तरह से उपेक्षित हो गया है किसी प्रकार का है। इससे बचने के लिए सबसे आसान तरीका है इस तरह की एक अगर बयान के साथ onContextItemSelected कॉल रैप करने के लिए है: ActionBarSherlock 3.5 में

if (getUserVisibleHint()) { 
    // Handle menu events and return true 
} else 
    return false; // Pass the event to the next fragment 

संगतता पुस्तकालय इस तरह एक हैक किया था।

+1

@ सेराफ का जवाब अधिक सही लगता है, जैसे ही इस व्यवहार की व्याख्या है। मेरे पास एक ही समस्या थी और विभिन्न टुकड़ों के संदर्भ मेनू के लिए अलग-अलग समूह आईडी (उनके समाधान में) का उपयोग कर हल किया गया – marwinXXII

+0

Arnt 'hint' गैर-विश्वसनीय माना जाता है? –

+0

सैद्धांतिक रूप से, शायद, लेकिन ViewPager के लिए दोनों खंड एडाप्टर संकेत सेट करते हैं। – Veeti

14

यह इस वजह से होता है:

public boolean dispatchContextItemSelected(MenuItem item) { 
    if (mActive != null) { 
     for (int i=0; i<mAdded.size(); i++) { 
      Fragment f = mAdded.get(i); 
      if (f != null && !f.mHidden) { 
       if (f.onContextItemSelected(item)) { 
        return true; 
       } 
      } 
     } 
    } 
    return false; 
} 

आप देख सकते हैं, FragmentManager जब तक यह सच रिटर्न अपने ही टुकड़े के सभी के लिए Fragment.onContextItemSelected कहता है। अपने उदाहरण में मैं इस तरह के ठीक पेशकश कर सकते हैं:

public static class TestListFragment extends ListFragment { 

    private int mNumber = 0; 
    private ArrayList<String> mItems; 

    public static TestListFragment newInstance(int number) { 
     Bundle args = new Bundle(); 
     args.putInt("number", number + 1); 

     TestListFragment fragment = new TestListFragment(); 
     fragment.setArguments(args); 

     return fragment; 
    } 

    public TestListFragment() {} 

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

     mNumber = getArguments().getInt("number"); 
     mItems = new ArrayList<String>(); 
     mItems.add("I am list #" + mNumber); 
    } 

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
     super.onActivityCreated(savedInstanceState); 
     setListAdapter(new ArrayAdapter<String>(getActivity(), android.R.layout.simple_list_item_1, mItems)); 
     registerForContextMenu(getListView()); 
    } 

    @Override 
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { 
     super.onCreateContextMenu(menu, v, menuInfo); 
     menu.add(mNumber, 0, 0, "Hello, World!"); 
    } 

    @Override 
    public boolean onContextItemSelected(MenuItem item) { 
     if(item.getGroupId() == mNumber){ 
      Log.d("ViewPagerContextMenuBug", "onContextItemSelected called for number " + mNumber); 
      Toast.makeText(getActivity(), "onContextItemSelected called for number " + mNumber, Toast.LENGTH_SHORT).show(); 
      return true; 
     } 
     return false; 
    } 

} 
+0

मैंने कोशिश की और यह काम नहीं लग रहा है। item.getGroupId() 0 देता है इससे कोई फर्क नहीं पड़ता कि किस टुकड़े को लंबे समय से क्लिक किया जा रहा है। –

+0

इस उद्देश्य के लिए समूह आईडी का उपयोग करना एक अच्छा विचार है। यह निश्चित रूप से सबसे अच्छा जवाब है। – YBrush

0

ओह Google, मेरा मतलब डब्ल्यूटीएफ है?

समस्या यह है कि ऑन कॉन्टेक्स्ट इटैम चयनित बहुत सामान्य है, और इसे प्रत्येक खंड के प्रत्येक मेनू आइटम के लिए बुलाया जाता है।

आप का उपयोग नहीं करने के लिए सभीonContextItemSelected है, लेकिन केवल एक ही इस टुकड़ा के समारोह टुकड़ा मेनू के लिए मजबूर करने MenuItem.OnMenuItemClickListener उपयोग कर सकते हैं।

उपयोग अगले कार्यान्वयन:

@Override 
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) { 
    super.onCreateContextMenu(menu, v, menuInfo); 
    MenuInflater inflater = getActivity().getMenuInflater(); 
    if (v == btnShare) { 
     inflater.inflate(R.menu.share_menu, menu); 
     for (int i = 0; i < menu.size(); ++i) { 
      MenuItem item = menu.getItem(i); 
      item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { 
       @Override 
       public boolean onMenuItemClick(MenuItem item) { 
        onContextItemSelected(item); 
        return true; 
       } 
      }); 
     } 
    } 
} 

@Override 
public boolean onContextItemSelected(MenuItem item) { 
    AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); 
    switch (item.getItemId()) { 
     case R.id.print: 
     // ... 
    } 
} 
0

मेनू वस्तुओं में से प्रत्येक के लिए आशय का उपयोग करना मेरे लिए अच्छी तरह से काम किया।

@Override 
    public void onCreateContextMenu(ContextMenu menu, View v, ContextmenuInfo menuInfo) { 
     super.onCreateContextMenu(menu, v, menuInfo); 

     MenuInflater inflater = super.getActivity.getMenuInflater(); 

     inflater.infalte(R.menu.list_item, menu); 

     for(int i = 0; i < menu.size(); i++) { 
      MenuItem item = menu.getItem(i); 
      Intent intent = new Intent(); 
      intent.putExtra(KEY_EXTRA_FRAGMENT_ID, this.fragmentId); 
      if (item != null) { 
       item.setIntent(intent); 
      } 
     } 
    } 

    @Override 
    public boolean onContextItemSelected(MeniItem item) { 

     Intent intent = item.getIntent(); 

     if (intent != null) { 
      if (intent.getIntExtra(KEY_EXTRA_FRAGMENT_ID, -1) == this.fragmentId) { 

       // Implement code according the item function. 

       return true; 
      } 
     } 

     return super.onContextItemSelected(item); 
    } 
की
संबंधित मुद्दे