Android Tips #38 FragmentTabHost を使って Fragment をタブで切り替える

Android Tips #38 FragmentTabHost を使って Fragment をタブで切り替える

Clock Icon2013.01.12

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

FragmentTabHost とは

FragmentTabHost は Fragment をタブで切り替えるための View です。Android 1.6 から使用することができます。Activity にタブを表示して View を切り替える実装は以前は TabActivity を使っていましたが、現在は非推奨になっています。この機会に最新の実装方法を覚えておきましょう!

tab_host01

FragmentTabHost の使いかた

1. レイアウトを作る

まずはレイアウトを作ります。

<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">

        <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"/>
        
        <FrameLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>

    </LinearLayout>

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

まず大原則として大枠は FragmentTabHost にします。その中にタブの View である TabWidget @android:id/tabs という id で配置します。TabWidget は TabActivity のときにも使われていた View なので馴染み深いと思います。また FrameLayout を @android:id/tabcontent という id で配置します。これは実際には表示されない View になりますが、こうすることで FragmentTabHost がそれぞれの View をパーツとして使ってくれます。最後に Fragment を追加するレイアウトに好きな id を入れて完了です。今回は content という名前にしました。

2. FragmentTabHost をセットアップする

次に Activity の実装です。Fragment を取り扱うので FragmentActivity を継承します。onCreate() で FragmentTabHost を findViewById() で参照し FragmentTabHost#setup() メソッドを呼びます。引数には Context と FragmentManager を渡さなければいけないので FragmentActivity#getSupportFragmentManager() で取得した FragmentManager を渡すようにします。

FragmentTabHost host = (FragmentTabHost)findViewById(android.R.id.tabhost);
host.setup(this, getSupportFragmentManager(), R.id.content);

3. TabSpec を追加する

あとはタブの情報である TabSpec で作っていきます。TabSpec のインスタンスは FragmentTabHost#newTabSpec() で生成します。引数には TabSpec のタグを渡します。 必ず設定しておかなければいけないのが TabSpec#setIndicator() です。これはタブの View になります。String を渡すとデフォルトのタブボタンの View が使われます。
最後に FragmentTabHost#addTab() でタブを追加します。第一引数に TabSpec を、第二引数にタブが選択されたときに表示したい Fragment を Class で渡します。第三引数には Fragment で読み込みたいデータを Bundle で渡します。特に必要ない場合は null でOKです。

TabSpec tabSpec1 = host.newTabSpec("tab1").setIndicator("Tab1");
host.addTab(tabSpec1, SampleFragment.class, null);

以下が Activity の全ソースです。Fragment は適当に。

MainActivity.java

package jp.classmethod.android.sample.fragmenttabhost;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.TabHost.TabSpec;
import android.widget.TextView;

public class MainActivity extends FragmentActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_main);
        FragmentTabHost host = (FragmentTabHost) findViewById(android.R.id.tabhost);
        host.setup(this, getSupportFragmentManager(), R.id.content);

        TabSpec tabSpec1 = host.newTabSpec("tab1");
        Button button1 = new Button(this);
        button1.setBackgroundResource(R.drawable.tab_left);
        tabSpec1.setIndicator(button1);
        Bundle bundle1 = new Bundle();
        bundle1.putString("name", "Tab1");
        host.addTab(tabSpec1, SampleFragment.class, bundle1);
        
        TabSpec tabSpec2 = host.newTabSpec("tab2");
        Button button2 = new Button(this);
        button2.setBackgroundResource(R.drawable.tab_center);
        tabSpec2.setIndicator(button2);
        Bundle bundle2 = new Bundle();
        bundle2.putString("name", "Tab2");
        host.addTab(tabSpec2, SampleFragment.class, bundle2);
        
        TabSpec tabSpec3 = host.newTabSpec("tab3");
        Button button3 = new Button(this);
        button3.setBackgroundResource(R.drawable.tab_right);
        tabSpec3.setIndicator(button3);
        Bundle bundle3 = new Bundle();
        bundle3.putString("name", "Tab3");
        host.addTab(tabSpec3, SampleFragment.class, bundle3);
    }
    
    public static class SampleFragment extends Fragment {
        
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            
            TextView textView = new TextView(getActivity());
            textView.setGravity(Gravity.CENTER);
            textView.setText(getArguments().getString("name"));
            
            return textView;
        }
        
    }
}

tab_host01

tab_host02

tab_host03

まとめ

タブの切り替えはよく使われる UI のひとつだと思いますが Fragment を使うととても管理しやすいです。何より以前良く使われていた TabActivity の実装方法は非推奨になっているので、これからは FragmentTabHost を使うようにしていきましょう。
しかし Support Package で導入されてから Fragment を使う機会がかなり増えてきましたね。Android 開発者にとって Fragment を使いこなすことは必須といえますね!今回は初歩的な解説となりましたが、これからも Fragment を使った実装 Tips をシェアしていきますのでよろしくお願いします!

参考

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.