29

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

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

अभ्यास कोड:

package net.solarnz.apps.fragmentsample; 

import android.app.Activity; 
import android.app.Fragment; 
import android.app.FragmentManager; 
import android.os.Bundle; 
import android.support.v13.app.FragmentStatePagerAdapter; 
import android.support.v4.view.ViewPager; 

public class FragmentSampleActivity extends Activity { 
    private ViewPagerAdapter mViewPagerAdapter; 
    private ViewPager mViewPager; 

    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.main); 

     if (mViewPagerAdapter == null) { 
      mViewPagerAdapter = new ViewPagerAdapter(getFragmentManager()); 
     } 

     mViewPager = (ViewPager) findViewById(R.id.log_pager); 
     mViewPager.setAdapter(mViewPagerAdapter); 
     mViewPager.setCurrentItem(0); 
    } 


    private class ViewPagerAdapter extends FragmentStatePagerAdapter { 
     public ViewPagerAdapter(FragmentManager fm) { 
      super(fm); 
     } 

     @Override 
     public int getCount() { 
      return 8; 
     } 

     @Override 
     public Fragment getItem(int position) { 
      Fragment f = Fragment1.newInstance(position); 
      // f.setRetainInstance(true); 
      f.setHasOptionsMenu(true); 
      return f; 
     } 
    } 
} 

टुकड़ा कोड:

package net.solarnz.apps.fragmentsample; 

import android.app.Fragment; 
import android.os.Bundle; 
import android.view.Menu; 
import android.view.MenuInflater; 

public class Fragment1 extends Fragment { 
    int mNum; 

    static Fragment newInstance(int num) { 
     Fragment1 f = new Fragment1(); 

     // Supply num input as an argument. 
     Bundle args = new Bundle(); 
     args.putInt("num", num); 
     f.setArguments(args); 

     return f; 
    } 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setHasOptionsMenu(true); 
     mNum = getArguments() != null ? getArguments().getInt("num") : 0; 
    } 

    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     inflater.inflate(R.menu.menu_list, menu); 
    } 

} 

लेआउट:

<?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="fill_parent" > 

      <android.support.v4.view.ViewPager 
       android:id="@+id/log_pager" 
       android:layout_width="match_parent" 
       android:layout_height="match_parent" /> 
</LinearLayout> 

मेनू:

<?xml version="1.0" encoding="utf-8"?> 
<menu xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item android:id="@+id/menu_refresh" 
      android:title="Refresh" 
      android:icon="@android:drawable/ic_delete" 
      android:showAsAction="ifRoom|withText" /> 
</menu> 

कार्रवाई मेनू डाला जा रहा: http://i.stack.imgur.com/QFMDd.png

कार्रवाई मेनू आबादी वाले नहीं किया जा रहा: http://i.stack.imgur.com/sH5Pp.png

+0

Solarnz साथ सहमत ऐसा लगता है कि कोई स्पष्ट कामकाज नहीं है। मैंने एक [प्रदर्शनकर्ता ऐप] बनाया है (https://github.com/snodnipper/page-flipper-race-condition/) जो किसी को विश्वसनीय रूप से समस्या को पुन: पेश करने की अनुमति देता है। एक ही समस्या [एक्शनबारशेलॉक में रिपोर्ट की गई है] (https://github.com/JakeWharton/ActionBarSherlock/issues/351) और मैंने इसे [मुद्दा] उठाया है (http://code.google.com/p/android एंड्रॉइड इश्यू ट्रैकर में/मुद्दों/विवरण? आईडी = 2 9 472)। – snodnipper

उत्तर

21

आप इस पढ़ना चाहिए (xcolw से ...)

प्रयोग के माध्यम से यह मूल कारण की तरह लगता है invalidateOptionsMenu मुख्य थ्रेड पर एक ब्रेक अप पंक्तिबद्ध नौकरियों पर कार्रवाई करने के बिना एक से अधिक कहा जाता हो रही है। एक अनुमान - इससे कोई फर्क नहीं पड़ता कि मेन्यू सृजन का कुछ महत्वपूर्ण हिस्सा एक पोस्ट के माध्यम से स्थगित कर दिया गया था, जब तक कि यह खराब स्थिति में एक्शन बार को तब तक नहीं चला जाता जब तक वह चलता न हो।

  1. एक ही आइटम

  2. गतिविधि के onCreate में viewPager.setCurrentItem फोन करने के लिए viewPager.setCurrentItem कई बार बुला:

    में कुछ धब्बे से ऐसा हो सकता है कि स्पष्ट नहीं हैं कर रहे हैं। setCurrentItem एक विकल्प मेनू अमान्य है, जो तुरंत गतिविधि के विकल्प मेनू द्वारा पीछा किया जाता अमान्य

समाधान मैं हर

  1. गार्ड viewPager करने के लिए कॉल के लिए मिल गया है कारण बनता है।onCreate

    में
    public void onCreate(...) { 
        ... 
        view.post(new Runnable() { 
         public void run() { 
          // guarded viewPager.setCurrentItem 
         } 
        } 
    } 
    

setCurrentItem

if (viewPager.getCurrentItem() != position) 
    viewPager.setCurrentItem(position); 
  • आस्थगित करें viewPager.setCurrentItem करने के लिए कॉल दृश्य पेजर के अंदर इन परिवर्तनों विकल्प मेनू अपेक्षा के अनुरूप काम करने लगता है के बाद। मुझे आशा है कि कोई इस में अधिक प्रकाश डाल सकता है।

    स्रोतhttp://code.google.com/p/android/issues/detail?id=29472

  • +0

    उत्कृष्ट। धन्यवाद। –

    +0

    Pls, पूरा स्निपेट प्रदान करें कि बिना टैब के व्यूपैज़र के साथ इसका उपयोग कैसे करें, मेरे लिए स्पष्ट नहीं है। धन्यवाद। –

    +0

    यह मेरे लिए काम नहीं किया है। mViewPager.post (नई Runnable() { @Override सार्वजनिक शून्य रन() { mViewPager.setAdapter (नई FragPagerAdapter (getSupportFragmentManager(), MainActivity.this));! अगर (mViewPager.getCurrentItem() = 1) { mViewPager.setCurrentItem (1); } } }); –

    8

    सरल उत्तर ViewPager में टुकड़े भीतर मेनू का उपयोग नहीं करने के लिए है। यदि आपको टुकड़ों के भीतर मेनू का उपयोग करने की आवश्यकता है, तो मैं जो सुझाव देता हूं वह मेनू गतिविधि को पेरेंट गतिविधि में ऑनरेटऑप्शनमेनू विधि के माध्यम से लोड कर रहा है। जाहिर है आपको यह निर्धारित करने में सक्षम होना होगा कि कौन सा मेनू दिखाना है।

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

    +0

    क्या आप इसके लिए कोड साझा कर सकते हैं? –

    0

    पहले FragmentPagerAdapter के उप कक्षा में एक विधि बनाने के वर्तमान टुकड़ा

    public SherlockFragment getFragment() { 
        return currentFragment; 
    } 
    
         @Override 
    public void onTabSelected(final Tab tab, FragmentTransaction ft) { 
    
        ((SherlockFragmentActivity) mContext).invalidateOptionsMenu(); 
        Fragment f = ((SherlockFragmentActivity) mContext) 
          .getSupportFragmentManager().findFragmentByTag(
            makeFragmentName(tab.getPosition())); 
    
        currentFragment=(SherlockFragment) f; 
    } 
    

    अब मुख्य Actvity में विधियों के नीचे ओवरराइड

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
        if (mTabsAdapter.getPositionOfTabSelected() != 0) { 
         menu.add("Read").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); 
         menu.add("Write").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); 
         menu.add("Clear").setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM); 
         menu.add("Factory data reset").setShowAsAction(
           MenuItem.SHOW_AS_ACTION_IF_ROOM); 
        } 
    
        return super.onCreateOptionsMenu(menu); 
    } 
    

    अब फोन प्राप्त करने के लिए onOptionItem गतिविधि से खंड में चयनित

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
        mTabsAdapter.getFragment().onOptionsItemSelected(item); 
        return super.onOptionsItemSelected(item); 
    } 
    
    3

    मुझे भी एक ही समस्या थी। मेरे मामले में मेरे पास व्यूपार्जर के साथ एक गतिविधि है जिसमें दो टुकड़े होते हैं, प्रत्येक खंड अपने स्वयं के एक्शन मेनू को बढ़ाता है लेकिन खंड क्रिया मेनू नहीं दिखाया जाता है।

    देखें पेजर एडाप्टर कोड

    public class ScreensAdapter extends FragmentPagerAdapter { 
    
        public TrackerScreensAdapter(Context context, FragmentManager fm) { 
         super(fm); 
        } 
    
        @Override 
        public int getCount() { 
         return 2; 
        } 
    
        public Fragment getItem(int position) { 
         Fragment fragment = null; 
         switch (position){ 
          case 0: 
           fragment = new Fragment1(); 
           break; 
          case 1: 
           fragment = new Fragment2(); 
           break; 
         } 
         return fragment; 
        } 
    
    } 
    

    गतिविधि को बनाने,

    screensAdapter = new ScreensAdapter(this, getFragmentManager()); 
        viewPager.setAdapter(screensAdapter); 
    

    इस तरह मेरी viewPager दो टुकड़े है, हर टुकड़ा onActivityCreated में अपने स्वयं के कार्य आग डेटा प्राप्त और उसके लेआउट के आधार पर आकर्षित प्राप्त डेटा इसके अलावा हर टुकड़ा इस समस्या का समाधान और क्यों टुकड़ा नहीं मेनू से पता चलता है यह पता लगाने की

    @Override 
    public void onActivityCreated(Bundle savedInstanceState) { 
        super.onActivityCreated(savedInstanceState); 
        setHasOptionsMenu(true); 
        MyTask task = new MyTask(); 
        task.setTaskListener(this); 
        task.execute(); 
    
    
    } 
    
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
        inflater.inflate(R.menu.fragment_menu, menu); 
    } 
    

    कई बार बिताया onCreateOptionsMenu है। सभी है कि मैं जरूरत थी

    screenAdapter = new ScreenAdapter(this, getFragmentManager()); 
        viewPager.post(new Runnable() { 
         public void run() { 
          viewPager.setAdapter(screenAdapter); 
         } 
        }); 
    
    +0

    धन्यवाद! रननेबल के अंदर एडाप्टर को मेरे लिए हल किया गया –

    0

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

    @Override 
    public void onResume() { 
        mPagerAdapter.notifyDataSetChanged(); 
    } 
    
    0

    जबकि मैं HorizontalScrollView उपयोग कर रहा था टैब दिखाने के लिए, लेकिन मैं PagerTitleStrip को बदल दिया है और समस्या हल हो गया था मैं कार्यवाही बार आइटम के साथ इस समस्या हो रही थी।

    शायद यह जानकारी किसी और की मदद कर सकती है।

    0

    मेरे मामले में मैंने इस मुद्दे के मूल कारण का पता लगाया है जो मुझे लगता है कि FragmentStatePagerAdapter में एक बग है जो Fragment#setMenuVisibility को झूठी करने के लिए बुला रहा है और इसे सही स्थिति में सही ढंग से सेट करने में असफल रहा है जब यह स्थिति को पुनर्स्थापित करता है।

    समाधान:

    1. उपयोग FragmentPagerAdapter बजाय FragmentStatePagerAdapter

    2. तुम इतनी तरह अपने अनुकूलक उपवर्ग ओवरराइड setPrimaryItem में FragmentStatePagerAdapter, उपयोग करना आवश्यक है:

      @Override 
      public void setPrimaryItem(ViewGroup container, int position, Object object) { 
          super.setPrimaryItem(container, position, object); 
      
          //This is a workaround for a bug in FragmentStatePagerAdapter 
          Fragment currentItem = getItem(position); 
          if (currentItem != null) { 
           currentItem.setMenuVisibility(true); 
           currentItem.setUserVisibleHint(true); 
          } 
      } 
      
    +0

    उनमें से कोई भी काम काम नहीं करता है। – Proverbio

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