[Java] Create Tab and Fragment in Fragment of BottomNavigationView

2 minute read

I made a BottomNavigationView once, and when I created Tabhost and its fragments, I was addicted to it.
Mainly, I referred to the reference at the bottom, but I am including a correction because some errors occurred. First, it is one of each fragment divided by BottomNavigationView.

parent fragment.java


public class parent fragment extends Fragment {
    public static Record newInstance() {
        return new Record();
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.record, container, false);
        //Get FragmentManager
        FragmentManager mFragmentManager = getChildFragmentManager();
        //Get FragmentTabHost from xml, note that id is android.R.id.tabhost
        FragmentTabHost tabHost = (FragmentTabHost)v.findViewById(android.R.id.tabhost);
        Log.d("tabHost", String.valueOf(tabHost));
        //Set up by passing Context, FragmentManager, and View id that the Fragment hits
        tabHost.setup(getActivity().getApplicationContext(), mFragmentManager, R.id.content);
        // Pass any id to the String type argument
        //This time, to switch two Fragment from FragmentTabHost, prepare two TabSpec
        TabHost.TabSpec mTabSpec1 = tabHost.newTabSpec("tab1");
        TabHost.TabSpec mTabSpec2 = tabHost.newTabSpec("tab2");
        // Pass the character to display on the Tab
        mTabSpec1.setIndicator("This is tab1");
        mTabSpec2.setIndicator("This is tab2");
        Bundle args = new Bundle();
        args.putString("string", "message");
        // Pass the argument to associate class with each TabSpec
        //By passing Bundle as the third argument, a value can be passed to Fragment. Pass null if not needed
        tabHost.addTab(mTabSpec1, child fragment 1.class, args);
        tabHost.addTab(mTabSpec2, child fragment 2.class, null);
        return v;

    }
}

child fragment 1.java


public class child fragment 1 extends Fragment {
    static child fragment 1 newInstance() {return new child fragment 1();}
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        //When passing Bundle in addTab, get the value from Bundle
        //If not passed (null is passed), it need not be implemented. Otherwise an error will occur at getString("string")
        Bundle args = getArguments();
        String str = args.getString("string");
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        return inflater.inflate(R.layout.child fragment layout 1, null);
    }
}

child fragment 2.java


public class child fragment 2 extends Fragment {
    static child fragment 2 newInstance() {return new child fragment 2();}

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        return inflater.inflate(R.layout.child fragment layout 2, null);
    }
}

parent fragment layout.xml


<?xml version="1.0" encoding="utf-8"?>
<!-- FragmentTabHost id must be @android:id/tabhost -->
<android.support.v4.app.FragmentTabHost
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <!-- Same as FragmentTabHost, with id specified. The id should always be @android:id/tabs -->
        <TabWidget
            android:id="@android:id/tabs"
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"/>

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0"/>

        <!-- Fragment is added to content -->
        <FrameLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>

    </LinearLayout>
</android.support.v4.app.FragmentTabHost>

child fragment layout.xml (child fragment layout 1, child fragment layout 2)


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/textView3"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Child Fragment" />
</LinearLayout>

Remarks:
Fragment system has “android.app.Fragment~” and “android.support.v4.app.Fragment~”, but it seems that it’s better to unify them (obviously)
Android standard I’m using v4 with reference to the article [support.v4.app.Fragment should be used instead of Fragment].

Reference:
FragmentTabHost Memorandum of Understanding