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);