2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

BottomNavigationViewのFragmentの中に更にTabとFragmentを作る

Last updated at Posted at 2020-08-13

BottomNavigationViewを一回作り、その中にTabhostとそのフラグメントを作った際、ハマったのでメモ。

主に、一番下の参考を参照しましたが、いくつかエラーが発生したため修正を入れています。
まず、BottomNavigationViewで分けた各フラグメントのうち一つです。

親フラグメント.java
public class 親フラグメント 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);
        //FragmentManagerの取得
        FragmentManager mFragmentManager = getChildFragmentManager();
        //xmlからFragmentTabHostを取得、idが android.R.id.tabhost である点に注意
        FragmentTabHost tabHost = (FragmentTabHost)v.findViewById(android.R.id.tabhost);
        Log.d("tabHost", String.valueOf(tabHost));
        //ContextとFragmentManagerと、FragmentがあたるViewのidを渡してセットアップ
        tabHost.setup(getActivity().getApplicationContext(), mFragmentManager, R.id.content);
        //String型の引数には任意のidを渡す
        //今回は2つのFragmentをFragmentTabHostから切り替えるため、2つのTabSpecを用意する
        TabHost.TabSpec mTabSpec1 = tabHost.newTabSpec("tab1");
        TabHost.TabSpec mTabSpec2 = tabHost.newTabSpec("tab2");
        //Tab上に表示する文字を渡す
        mTabSpec1.setIndicator("This is tab1");
        mTabSpec2.setIndicator("This is tab2");
        Bundle args = new Bundle();
        args.putString("string", "message");
        //それぞれのTabSpecにclassを対応付けるように引数を渡す
        //第3引数はBundleを持たせることで、Fragmentに値を渡せる。不要である場合はnullを渡す
        tabHost.addTab(mTabSpec1, 子フラグメント1.class, args);
        tabHost.addTab(mTabSpec2, 子フラグメント2.class, null);
        return v;

    }
}
子フラグメント1.java
public class 子フラグメント1 extends Fragment {
    static 子フラグメント1 newInstance() {return new 子フラグメント1();}
    @Override
    public void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        //addTabの際にBundleを渡す場合は、Bundleから値を取得する
        //渡さない(nullを渡している)場合は、実装しなくてよい。そうでないと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.子フラグメントレイアウト1, null);
    }
}
子フラグメント2.java
public class 子フラグメント2 extends Fragment {
    static 子フラグメント2 newInstance() {return new 子フラグメント2();}

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        return inflater.inflate(R.layout.子フラグメントレイアウト2, null);
    }
}
親フラグメントレイアウト.xml
<?xml version="1.0" encoding="utf-8"?>
<!-- FragmentTabHostのidは必ず @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">

        <!-- FragmentTabHost同様、idの指定あり。idは必ず @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"/>

        <!-- contentにFragmentが追加される-->
        <FrameLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>

    </LinearLayout>
</android.support.v4.app.FragmentTabHost>
子フラグメントレイアウト.xml(子フラグメントレイアウト1,子フラグメントレイアウト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="子フラグメント" />
</LinearLayout>

備考:

Fragment系は"android.app.Fragment~"と"android.support.v4.app.Fragment~"がありますが、どちらかに統一したほうが良いっぽいです(当たり前ですが。)
Android標準のFragmentよりsupport.v4.app.Fragmentを使うべき、という理由を徹底調査という記事を参考にして、わたしはv4を使っています。

参考:

FragmentTabHost覚書

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?