2

我在ViewPager中構建了一些帶有碎片的Android應用程序(最低SDK級別10,薑餅2.3.3)。我正在使用ActionBarSherlock創建一個ActionBar,並使用android-viewpagertabs爲ViewPager添加選項卡,就像在Market客戶端中一樣。使用ViewPager和片段複製菜單項

我有一個全局菜單項,我想要顯示在每個選項卡/片段上。在三個選項卡中的第一個上,我希望有兩個額外的菜單項。

但現在兩個陌生的事情發生了:

首先,如果我啓動應用程序,一切似乎都很正常,我可以看到在第一頁上的所有三個菜單項只有一個項目,如果我刷到第二和第三個標籤。但是如果我滑回第三個選項卡的第二個選項卡,我可以再次看到所有三個不應該發生的項目。如果我滑回第一個,然後又回到第二個標籤,一切都很好。

另一個奇怪的是,我每次旋轉設備時,片段中的菜單項都會再次添加,即使它們已經在菜單中。從位於freenode /#安卓

public class SubscriptionGridFragment extends Fragment { 

    private GridView subscriptionList; 
    private SubscriptionListAdapter adapter; 

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

    // ... 

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

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     // ... 
    } 
} 

回答

0

感謝SimonVT:

public class MainActivity extends FragmentActivity { 

    public static final String TAG = "MainActivity"; 

    private ActionBar actionBar; 
    private Adapter adapter; 
    private ViewPager viewPager; 
    private ViewPagerTabs tabs; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.volksempfaenger); 

     actionBar = getSupportActionBar(); 

     adapter = new Adapter(getSupportFragmentManager()); 
     adapter.addFragment(getString(R.string.title_tab_subscriptions), 
       SubscriptionGridFragment.class); 
     // adding more fragments here 

     viewPager = (ViewPager) findViewById(R.id.viewpager); 
     viewPager.setAdapter(adapter); 

     tabs = (ViewPagerTabs) findViewById(R.id.tabs); 
     tabs.setViewPager(viewPager); 
    } 

    public static class Adapter extends FragmentPagerAdapter implements 
      ViewPagerTabProvider { 

     private FragmentManager fragmentManager; 
     private ArrayList<Class<? extends Fragment>> fragments; 
     private ArrayList<String> titles; 

     public Adapter(FragmentManager fm) { 
      super(fm); 
      fragmentManager = fm; 
      fragments = new ArrayList<Class<? extends Fragment>>(); 
      titles = new ArrayList<String>(); 
     } 

     public void addFragment(String title, Class<? extends Fragment> fragment) { 
      titles.add(title); 
      fragments.add(fragment); 
     } 

     @Override 
     public int getCount() { 
      return fragments.size(); 
     } 

     public String getTitle(int position) { 
      return titles.get(position); 
     } 

     @Override 
     public Fragment getItem(int position) { 
      try { 
       return fragments.get(position).newInstance(); 
      } catch (InstantiationException e) { 
       Log.wtf(TAG, e); 
      } catch (IllegalAccessException e) { 
       Log.wtf(TAG, e); 
      } 
      return null; 
     } 

     @Override 
     public Object instantiateItem(View container, int position) { 
      FragmentTransaction fragmentTransaction = fragmentManager 
        .beginTransaction(); 
      Fragment f = getItem(position); 
      fragmentTransaction.add(container.getId(), f); 
      fragmentTransaction.commit(); 
      return f; 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     BaseActivity.addGlobalMenu(this, menu); 
     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     return BaseActivity.handleGlobalMenu(this, item); 
    } 

} 

片段的代碼,應有自己的菜單項:

,顯示ViewPager及其選項卡的FragmentActivity準則-dev:「protip:在覆蓋instantiateItem之前查看fragmentpageradapter實際執行的操作」

刪除此方法解決了整個問題。

1

在Android示例項目中發現此問題。在片段活動中,的onCreate需要檢查,看看是否savedInstanceState仍然活躍,像這樣:

setContentView(R.layout.custom_detail_fragment); 

    if (savedInstanceState != null) { 
     return; 
    } 

    CDFrag = new CustomDetailFragment(); 
    getSupportFragmentManager().beginTransaction().add(R.id.custom_detail_fragment_container, CDFrag).commit(); 

的關鍵是這一部分:

if (savedInstanceState != null) { 
     return; 
    } 

我也湊了重複的項目我操作欄,當我旋轉,一旦我添加了檢查,複製停止。

0

有同樣的問題。

我的錯誤是我在OnCreate中創建了一個新Viewpager並設置爲ID

viewpager.setId(viewpager.hashcode()); 
setContentView(viewpager); 

但是,這是一個很大的錯誤,東陽的方向改變後的FragmentPagerAdapter嘗試重用舊片段。它在FragmentManager中查找具有從視圖頁面ID和片段位置生成的ID的片段。

public Object instantiateItem(ViewGroup container, int position) { 
     if (mCurTransaction == null) { 
      mCurTransaction = mFragmentManager.beginTransaction(); 
     } 

     final long itemId = getItemId(position); 

     // Do we already have this fragment? 
     String name = makeFragmentName(container.getId(), itemId); 
     Fragment fragment = mFragmentManager.findFragmentByTag(name); 
     if (fragment != null) { 
      if (DEBUG) Log.v(TAG, "Attaching item #" + itemId + ": f=" + fragment); 
      mCurTransaction.attach(fragment); 
     } else { 
      fragment = getItem(position); 

容器是Viewpager。

解決方案:

viewpager.setId(R.id.viewpager); 
setContentView(viewpager);