0
動的なタブの追加と削除オプションを使用してアプリケーションを作成したいのですが、問題が1つあります。onCreateViewは常にviewPagerAdapter.addTab()の後に呼び出されるとは限りません
初めてタブを追加するときはすべて問題ありませんが、1つのタブを削除して新しいタブをもう一度追加したい場合、その新しいフラグメントに対してonCreateViewが呼び出されません。
例:onCreateViewが呼び出され
ViewPagerAdapter vpa = (ViewPagerAdapter) mViewPager.getAdapter();
vpa.addTab("TAB 1");
vpa.notifyDataSetChanged();
:
- タブ1を追加します。
私は、新しい3つのタブが追加されます。
some logs: [add tab] mViewPager.getChildCount() = 1 [add tab] vpa.getCount() = 1
- タブ2追加:onCreateViewが呼び出され
vpa.addTab("TAB 2"); vpa.notifyDataSetChanged();
を。
some logs: [add tab] mViewPager.getChildCount() = 2 [add tab] vpa.getCount() = 2
- タブ3追加:onCreateViewが呼び出され
vpa.addTab("TAB 3"); vpa.notifyDataSetChanged();
を。
some logs: [add tab] mViewPager.getChildCount() = 3 [add tab] vpa.getCount() = 3
- は、今私はタブ2削除する:
vpa.removeTab("TAB 2"); vpa.notifyDataSetChanged();
some logs: [add tab] mViewPager.getChildCount() = 2 [add tab] vpa.getCount() = 2
- と私は再びタブ2を追加したい:
vpa.addTab("TAB 2"); vpa.notifyDataSetChanged();
と呼ばれる全くonCreateView :(
some logs: [add tab] mViewPager.getChildCount() = 2 [add tab] vpa.getCount() = 3
誰もがそれを修正する方法を知ることができるがありませんか? onCreateViewが常に呼び出されるのはなぜですか?
アプリケーションコード:
private void initViewpagerAndTabs(){ mViewPager = (ViewPager) findViewById(R.id.viewpager_slave); mViewPager.setOffscreenPageLimit(10); mAdapterViewPager = new ViewPagerAdapter(getSupportFragmentManager()); mViewPager.setAdapter(mAdapterViewPager); mTabLayout = (TabLayout) findViewById(R.id.tabLayout_slave); mTabLayout.setupWithViewPager(mViewPager); }
/** Tabs content fragment */ public static class DummyFragment extends Fragment implements RecyclerAdapter.ViewHolder.ClickListener { private RecyclerView mRecyclerView; private RecyclerAdapter mAdapterRecycler; private RecyclerView.LayoutManager mLayoutManager; private Fab fab; @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { View view = inflater.inflate(R.layout.content_slave, container, false); //setRetainInstance(true); initRecyclerView(view); fab = (Fab) getActivity().findViewById(R.id.fabRemoveItems); return view; } private void initRecyclerView(View view){ mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view_slave); // use this setting to improve performance if you know that changes // in content do not change the layout size of the RecyclerView mRecyclerView.setHasFixedSize(true); mLayoutManager = new LinearLayoutManager(getContext()); mRecyclerView.setLayoutManager(mLayoutManager); RecyclerView.ItemAnimator itemAnimator = mRecyclerView.getItemAnimator(); itemAnimator.setAddDuration(500); itemAnimator.setRemoveDuration(500); mAdapterRecycler = new RecyclerAdapter(this); mRecyclerView.setAdapter(mAdapterRecycler); } }
private class ViewPagerAdapter extends FragmentStatePagerAdapter { private final List<DummyFragment> mFragmentList = new ArrayList<>(); private final List<String> mFragmentTitleList = new ArrayList<>(); public ViewPagerAdapter(FragmentManager fm) { super(fm); } public DummyFragment getItem(int num) throws IndexOutOfBoundsException{ return mFragmentList.get(num); } public void addTab(String title) throws Exception { if(isTabExist(title)){ throw new Exception("Tabs already exist!"); } //Log.d(TAG, "[addTab] mFragmentTitleList before add: " + mFragmentTitleList); //Log.d(TAG, "[addTab] mFragmentList before add: " + mFragmentList); mFragmentList.add(new DummyFragment()); mFragmentTitleList.add(title); //Log.d(TAG, "[addTab] mFragmentTitleList after add: " + mFragmentTitleList); //Log.d(TAG, "[addTab] mFragmentList after add: " + mFragmentList); } public void removeTab(int position){ //Log.d(TAG, "[removeTab] mFragmentTitleList before removed: " + mFragmentTitleList); //Log.d(TAG, "[removeTab] mFragmentList before removed: " + mFragmentList); mFragmentTitleList.remove(position); mFragmentList.remove(position); //Log.d(TAG, "[removeTab] mFragmentTitleList after removed: " + mFragmentTitleList); //Log.d(TAG, "[removeTab] mFragmentList after removed: " + mFragmentList); } private boolean isTabExist(String name){ for(int i = 0; i < mFragmentTitleList.size(); i++) { if (mFragmentTitleList.get(i).equals(name)) { return true; } } return false; } public int getTabPosition(String tabName) throws IndexOutOfBoundsException{ for(int i = 0; i < mFragmentTitleList.size(); i++) { if (mFragmentTitleList.get(i).equals(tabName)) { return i; } } throw new IndexOutOfBoundsException(); } @Override public void destroyItem(ViewGroup container, int position, Object object) { super.destroyItem(container, position, object); getSupportFragmentManager().beginTransaction().remove((Fragment) object) .commit(); } @Override public int getItemPosition(Object object) { if (mFragmentList.contains(object)) return mFragmentList.indexOf(object); else return POSITION_NONE; } @Override public int getCount() { return mFragmentList.size(); } @Override public CharSequence getPageTitle(int position) { return mFragmentTitleList.get(position); } }
2番目のフラグメント(削除/追加後)にスワイプするとどうなりますか? – Yazan
その後、そのフラグメントにスワイプしますが、そのフラグメントで同じアイテムをrecyclerViewに追加したい場合は、アプリケーションクラッシュ(NullPointerException)が発生します。 onCreateViewが呼び出されなかったため、そのフラグメントのオブジェクトは初期化されません。 – NeyroN