2

Я создаю приложение для Android (минимальный SDK Level 10, Gingerbread 2.3.3) с некоторыми фрагментами в ViewPager. Я использую ActionBarSherlock, чтобы создать ActionBar и android-viewpagertabs, чтобы добавить вкладки в ViewPager, как в клиенте Market.Дублирование пунктов меню с помощью ViewPager и фрагментов

У меня есть один глобальный пункт меню, который я хочу показать на каждой вкладке/фрагменте. На первой из трех вкладок я хочу иметь два дополнительных пункта меню.

Но теперь две странные вещи:

Во-первых, если я запустить приложение, кажется, что все будет хорошо, я могу видеть все три пункта меню на первой странице, и только один пункт, если я красть на второй и третья вкладка. Но если я вернусь ко второй вкладке из третьей, я снова смогу увидеть все три элемента, которые не должны произойти. Если я вернусь к первому, а затем снова к второй вкладке, все будет хорошо.

Другое странное, что каждый раз, когда я поворачиваю устройство, элементы меню из фрагмента добавляются снова, даже если они уже находятся в меню.

Код FragmentActivity, который отображает ViewPager и его закладку:

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

} 

код фрагмент, который должен иметь свои собственные пункты меню:

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 из-сайта/# андроида -dev: «protip: Посмотрите, что на самом деле делает actionфрагментатор перед переопределением объекта instantiateItem»

Удаление этого метода решает всю проблему.

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

Была такая же проблема.

Моя ошибка была в том, что я создал новый ViewPager в OnCreate и установить в качестве идентификатора

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

Но это была большая ошибка, обусловленно после изменения ориентации изображения FragmentPagerAdapter пытается повторно использовать старые фрагменты. Он выглядит в FragmentManager для фрагмента с идентификатором, генерируемым из идентификатора viewpagers и положения фрагментов.

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

 Смежные вопросы

  • Нет связанных вопросов^_^