2012-05-07 35 views
9

FragmentStatePageAdapter (ViewPager için bağdaştırıcı olarak kullandığım) ve işlem çubuğundaki menü öğeleriyle ilgili bir sorunum var. Uygulamayı başlattığımda her şey yolunda. Görevi arka plana taşıyacak olursam (örneğin, HOME düğmesine basarsanız) ve etkinlik sona erene kadar bir şeyler yapmaya başlarım, sonra uygulamaya (uygulama başlatıcısı veya oluşturduğum bir bildirim) geri döndüğümde her şey yolunda eylem çubuğunda çoğaltılan menü öğeleri.FragmentStatePageAdapter yinelenen ActionBar menü öğeleri

Önemli bir ayrıntı, tek çoğaltılmış öğelerin ViewPager'da kullandığım her parçanın onCreateOptionsMenu() öğesinde oluşturulanlardır.

FragmentStatePageAdapter öğesini FragmentPageAdapter ile değiştirirseniz, öğeler artık çoğaltılamaz, ancak parçaları ViewPager'da gösterilmez (adaptörden getItem() işlevi hiçbir zaman geri dönmez, dolayısıyla hiçbir parça döndürmez).

Herhangi bir fikrin var mı? Menü öğelerini kopyalamak için FragmentStatePageAdapter'den kaçınmanın bir yolu var mı? Belki FragmentPageAdapter kullanın ama parçaları göstermek için bir değişiklik ile? Parçalarımdaki bir değişiklik mi? İşte

... benim uygulamadan bazı kod parçacıkları şunlardır menü öğeleri parçaları içine oluşturulur nasıl

: fragmanları ViewPager adaptörü

örneği nasıl

@Override 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
    /* Create play button */ 
    final MenuItem mPlay = menu.add(R.string.play_all); 

    mPlay.setIcon(R.drawable.ic_play_all); 
    mPlay.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS); 

    mPlay.setOnMenuItemClickListener(new OnMenuItemClickListener() { 
     @Override 
     public boolean onMenuItemClick(MenuItem item) { 
      final List<Song> songs = getSongs(); 

      if (songs.size() == 0) { 
       /* Show message */ 
       Toast.makeText(mContext, R.string.no_song_list, Toast.LENGTH_LONG).show(); 
      } else { 
       /* Play song list */ 
       try { PlayManager.getService().playList(songs); } catch (Exception e) {} 
      } 

      return false; 
     } 
    }); 

    /* Create menu */ 
    super.onCreateOptionsMenu(menu, inflater); 
} 

@Override public Fragment getItem(int position) { final Class<?> cls = mTabs.get(position); /* No tab */ if (cls == null) return null; /* Instantiate fragment */ final Fragment fragment = Fragment.instantiate(mContext, cls.getName(), null); /* Add to list */ mFragments.put(position, fragment); /* Return fragment */ return fragment; } 

Teşekkürler!

PS: Etkinliğin launchMode özelliğini "singleTop" olarak değiştirmeyi denedim ve ayrıca getItem() öğesinde önceden oluşturulmuş parçaya dönmeye çalıştım (ancak getItem() uygulamasına geri döndüğümde hiçbir zaman işe yaramaz , daha önce dediğim gibi).

+0

Merhaba, Miguel! Çözüm buldunuz mu? – HighFlyer

+0

Evet. Az önce kullandığım çözümün altında yayınladım. Bu gerçek bir çözüm değil, bir çözüm. –

cevap

3

Sorunumu gönderdikten birkaç gün sonra sorunuma bir çözüm buldum. Onu bu kadar geciktirdiğin için üzgünüm. Ben örneğini ve parçaları kullanmak aktivitesinde kod parçası yazmak kadar

@Override 
protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 

    outState.remove("android:support:fragments"); 
} 

kadar basit:

Aşağıdaki kod

benim sorun giderildi.

Ben Parçası örneği yinelenen menü öğelerini engellemek için görünür olup olmadığını kontrol bu yardımcı olur :)

+0

Awesome! :) Başka bir çözüm: çağrı cihazındaki parçalarda setRetainInstance (true) çağrısı. – HighFlyer

+0

Bunu da denemeliyim :) –

+0

Bazı deneylerden sonra outState.remove ekran döndürme ile çalışmaz, çünkü FragmentStatePageAdapter durum geri yüklendiğinde bu bilgiyi kullanır. Ayrıca setRetainInstance (true), arka planda uygulama başlatılmasıyla çalışmaz. – HighFlyer

2

Sorun şu ki, her kaydırdığınızda FragmentStatePagerAdapter yeni bir Fragment oluşturuyor. Sonuç olarak, oluşturulan her Fragment için onCreateOptionsMenu() çağrılır.

  1. Fragments dışına işlem çubuğu manipülasyon atın:

    , bence, iki çözümü vardır. Fragmanın içindeki menü öğesi için bir onclick ayarlamak yerine, Etkinlik'ten geçerli Parçacık'a bir mesaj gönderirsiniz.

  2. Menu.findItem() öğesini kullanarak, başka bir Parçanın istediğiniz MenuItem öğesinin eklenip eklenmediğini ve varsa geçerli Parçayı ekleyip eklemediğini (onPrepareOptionsMenu() içinde) görebilirsiniz.

+0

Nedeni bu değil. Uygulamayı ilk başlattığımda ve hızlıca kaydırdığımda mükemmel çalışıyor. Kaydırdığımda, taşıdığım parça tarafından oluşturulan öğeler silinir ve taşıdığım parçadan öğeler eklenir. Sorun, yalnızca etkinlik arka plandayken kapatıldığında olur ve tekrar başlatırım. –

3

ViewPager içerdeki Fragment seçenekler menüsünü şişirme önce umut:

// This should be in your Fragment implementation 
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) 
{ 
    if(isVisible()) 
    { 
     inflater.inflate(R.menu.menu_fragment, menu); 
    } 
    super.onCreateOptionsMenu(menu, inflater); 
} 
+0

Kodunuz, Duplikasyon probleminin üstesinden gelmeme yardımcı oluyor ama parça değiştirmiyor. – Roon13

0

bazı çözüm buldu onCreateOptionsMenu(Menu menu, MenuInflater inflater)

yılında şişirmek menü dosyası önce menu.clear() ekle sizin yinelenen menü parçası çalışmak

olabilir denemek

@Override 
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 
     super.onCreateOptionsMenu(menu, inflater); 
     menu.clear(); 
     inflater.inflate(R.menu.main,menu); 
    } 
İlgili konular