web-dev-qa-db-ja.com

下部のナビゲーションフラグメント内の複数のタブフラグメント

3つのタブ(ホーム、ダッシュボード、通知)を備えた下部のナビゲーション。下部の各ナビゲーションタブはフラグメントです。最初のタブすなわち。ホームフラグメントには、4つのタブ(タブ1、タブ2、タブ3、タブ4)を持つ別の上部ナビゲーションタブが含まれています。

enter image description here

問題

  1. ホームタブから通知タブに直接移動し、ホームタブ、Tab1 /以前に選択したタブ(上部のナビゲーションタブ)に戻る場合タブのコンテンツはロードされません。

  2. タブ1(ホームフラグメントタブ)から通知タブまでタブをスワイプし、タブ4コンテンツに到達したら、後ろにスワイプします。タブのが読み込まれず、最初のスワイプでタブ4からタブにスワイプしませんタブタブインジケーターが少し動くだけで、2回目のスワイプでタブになります。

アプリにはたくさんのコードが含まれているので、完全なコードを Github にリンクします。

クイックリファレンスはここに私のコードがあります

MainActivity.Java

public class MainActivity extends AppCompatActivity {


    private ViewPager viewPager;

    NavigationView navigationView;

    private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
            = new BottomNavigationView.OnNavigationItemSelectedListener() {

        @Override
        public boolean onNavigationItemSelected(@NonNull MenuItem item) {
            switch (item.getItemId()) {
                case R.id.navigation_home:
                    viewPager.setCurrentItem(0);
                    return true;
                case R.id.navigation_dashboard:
                    viewPager.setCurrentItem(1);
                    return true;
                case R.id.navigation_notifications:
                    viewPager.setCurrentItem(2);
                    return true;
            }
            return false;
        }

    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Hide the activity toolbar
        getSupportActionBar().hide();

        //Initializing viewPager
        viewPager = (ViewPager) findViewById(R.id.viewpager);
        setupViewPager(viewPager);


        final BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
        navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);

        viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
            @Override
            public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            }

            @Override
            public void onPageSelected(int position) {
                switch (position){
                    case 0:
                        navigation.setSelectedItemId(R.id.navigation_home);
                        break;
                    case 1:
                        navigation.setSelectedItemId(R.id.navigation_dashboard);
                        break;
                    case 2:
                        navigation.setSelectedItemId(R.id.navigation_notifications);
                        break;
                }
            }

            @Override
            public void onPageScrollStateChanged(int state) {

            }
        });


    }

    private void setupViewPager(ViewPager viewPager) {
        BottomNavPagerAdapter adapter = new BottomNavPagerAdapter(getSupportFragmentManager());
        adapter.addFragment(new FirstFragment());
        adapter.addFragment(new SecondFragment());
        adapter.addFragment(new ThirdFragment());
        viewPager.setAdapter(adapter);
    }

}

FirstFragment.Java(ホーム)

public class FirstFragment extends Fragment {


    private TabLayout tabLayout;
    private ViewPager firstViewPager;

    public FirstFragment() {
        // Required empty public constructor
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment

        View rootView = inflater.inflate(R.layout.fragment_first, container, false);

        firstViewPager = (ViewPager) rootView.findViewById(R.id.viewpager_content);

        tabLayout = (TabLayout) rootView.findViewById(R.id.tabs);
        tabLayout.setupWithViewPager(firstViewPager);

        setupViewPager(firstViewPager);
        return rootView;
    }

    private void setupViewPager(ViewPager viewPager) {
        TabViewPagerAdapter adapter = new TabViewPagerAdapter(getActivity().getSupportFragmentManager());
        adapter.addFragment(new Tab1Fragment(), "Tab 1");
        adapter.addFragment(new Tab1Fragment(), "Tab 2");
        adapter.addFragment(new Tab1Fragment(), "Tab 3");
        adapter.addFragment(new Tab1Fragment(), "Tab 4");
        viewPager.setAdapter(adapter);
    }
}

質問

  1. コードの何が問題になっていますか?
  2. この問題を解決する方法は? (レイアウトは必須です)またはスクリーンショットからレイアウトを考え出すためのより良いアプローチはありますか?
7
Puni

実際、これはよくある間違いです。フラグメント内でFragmentManagerActivityを使用していますが、このフラグメントには別のchildフラグメントが含まれているため、フラグメント自体のFragmentManagerを使用する必要があります。したがって、修正は簡単です。フラグメント内でgetActivity().getSupportFragmentManager()getChildFragmentManager()に変更するだけで、コードは次のようになります。

private void setupViewPager(ViewPager viewPager) {
    TabViewPagerAdapter adapter = new TabViewPagerAdapter(getChildFragmentManager());
    ...
    ...
    viewPager.setAdapter(adapter);
}

そして、これは期待どおりに機能するはずです。

25
rom4ek