この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
FragmentTabHost とは
FragmentTabHost は Fragment をタブで切り替えるための View です。Android 1.6 から使用することができます。Activity にタブを表示して View を切り替える実装は以前は TabActivity を使っていましたが、現在は非推奨になっています。この機会に最新の実装方法を覚えておきましょう!
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;
}
}
}
まとめ
タブの切り替えはよく使われる UI のひとつだと思いますが Fragment を使うととても管理しやすいです。何より以前良く使われていた TabActivity の実装方法は非推奨になっているので、これからは FragmentTabHost を使うようにしていきましょう。
しかし Support Package で導入されてから Fragment を使う機会がかなり増えてきましたね。Android 開発者にとって Fragment を使いこなすことは必須といえますね!今回は初歩的な解説となりましたが、これからも Fragment を使った実装 Tips をシェアしていきますのでよろしくお願いします!