[Android] Fragment をタブで切り替える FragmentTabHost を使う
タブが実装できる TabHost は、Android 3.0 以降は非推奨となり、FragmentTabHost を使う必要があります。TabHost では、Activity を TabHost に追加していましたが、FragmentTabHost では、Fragment を追加して使います。
この記事では、Android Studio で FragmentTabHost を使う方法を紹介します。
v4 support library の導入
Fragment を使うために、v4 support library を導入する必要があります。
メニュー → Tools → Android → SDK Manager から Android Support Repository をインストールします。
Project Structure(command + ;)→ Module → プロジェクト名 → Dependencies → + → Library dependency から、com.android.support:support-v4:+ を追加する。[Apply] → [OK] で自動的に、gradle の sync が始まり、成功したら OK です。
Fragment
Fragment を用意します。Fragment は、ビューとロジックを持ち、それらをひとつのものとして扱えるものです。単なるカスタムビューとは異なり、フラグメント自身もライフサイクルを持ち、さらにアクティビティのライフサイクルと同期しています。
Project 上で、副クリック → New → Android(Other)から Fragment を簡単に追加出来ます。以下に用意した Fragment のレイアウトとロジックは、標準で準備されるものから必要なものだけを残しました。
・fragment_sample.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.rakuishi.fragment.fragment.SampleFragment">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World!" />
</FrameLayout>
・SampleFragment.java
package com.rakuishi.fragment.fragment;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class SampleFragment extends Fragment {
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_sample, container, false);
}
}
Fragment を扱う Activity
FragmentTabHost に、TabWidget(id/tabs)と FrameLayout(id/tabcontent)が紐付きます。TabWidget と FrameLayout は、id 固定で必須です。FrameLayout(id/container)に Fragment が入ります。
・activity_main.xml
<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:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
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/container"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1" />
</LinearLayout>
</android.support.v4.app.FragmentTabHost>
FragmentTabHost を setup()
し、実際に表示するタブ TabSpec を追加 addTab()
していきます。addTab()
する際には、TabSpec, Fragment, Fragment に渡す値を指定できます。ここでは特に渡す必要がないので null
としています。
・MainActivity.java
package com.rakuishi.fragment.fragment;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
import android.util.Log;
import android.widget.TabHost;
public class MainActivity extends FragmentActivity implements FragmentTabHost.OnTabChangeListener {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// FragmentTabHost を取得する
FragmentTabHost tabHost = (FragmentTabHost)findViewById(android.R.id.tabhost);
tabHost.setup(this, getSupportFragmentManager(), R.id.container);
TabHost.TabSpec tabSpec1, tabSpec2;
// TabSpec を生成する
tabSpec1 = tabHost.newTabSpec("tab1");
tabSpec1.setIndicator("tab1");
// TabHost に追加
tabHost.addTab(tabSpec1, SampleFragment.class, null);
// TabSpec を生成する
tabSpec2 = tabHost.newTabSpec("tab2");
tabSpec2.setIndicator("tab2");
// TabHost に追加
tabHost.addTab(tabSpec2, SampleFragment.class, null);
// リスナー登録
tabHost.setOnTabChangedListener(this);
}
@Override
public void onTabChanged(String tabId) {
Log.d("onTabChanged", "tabId: " + tabId);
}
}