こんにちわ。ゆんぼうです。
今回は、Androidアプリでタブを作成します。
開発環境は以下の通りです。
・Eclipse v4.2.1
・Android 4.4.2
はじめに、Androidアプリのタブについて記載します。
Android v3.x (Androidコードネーム:Honeycomb)以前は、TabActivity や TabHostのクラスを使用していました。
・android.app.TabActivity
・android.widget.TabHost
しかし、3.x 以降では、非推奨APIとなっています。
代わりに、Fragment や ActionBar を使用してタブを作成します。
・android.app.ActionBar
・android.app.Fragment
■シンプルなタブを作成
タブの名前を表示しただけのシンプルなタブを表示した画面を作成します。
MainActivity.java にタブを表示する処理を実装します。
<pre class="brush: java;" title="MainActivity.java">
package jp.co.pa_rk.test_tab.activity;
import jp.co.pa_rk.test_tab.R;
import jp.co.pa_rk.test_tab.fragment.Tab1Fragment;
import jp.co.pa_rk.test_tab.fragment.Tab2Fragment;
import jp.co.pa_rk.test_tab.fragment.Tab3Fragment;
import jp.co.pa_rk.test_tab.fragment.Tab4Fragment;
import android.app.ActionBar;
import android.app.ActionBar.Tab;
import android.app.Activity;
import android.app.Fragment;
import android.app.FragmentTransaction;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
public class MainActivity extends FragmentActivity { // (1)
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ActionBar actionBar = getActionBar();
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); // (2)
// タブにリスナーを追加する
createTab(actionBar, new MainTabListener<Tab1Fragment>(this, Tab1Fragment.class), "タブ1");
createTab(actionBar, new MainTabListener<Tab2Fragment>(this, Tab2Fragment.class), "タブ2");
createTab(actionBar, new MainTabListener<Tab3Fragment>(this, Tab3Fragment.class), "タブ3");
createTab(actionBar, new MainTabListener<Tab4Fragment>(this, Tab4Fragment.class), "タブ4");
// デフォルトの状態選択を変更する
actionBar.setSelectedNavigationItem(0);
}
/** タブリスナークラス */
public static class MainTabListener<T extends Fragment> implements ActionBar.TabListener {
private Fragment _fragment;
private final Activity _activity;
private final Class<T> _cls;
public MainTabListener(Activity activity, Class<T> cls) {
this._activity = activity;
this._cls = cls;
}
@Override
public void onTabSelected(Tab tab, FragmentTransaction ft) {
_fragment = Fragment.instantiate(_activity, _cls.getName());
ft.replace(android.R.id.content, _fragment); // (4)
}
@Override
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
@Override
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
/**
* タブを作成する
*/
private void createTab(ActionBar actionBar, MainTabListener<?> listener, String title) {
ActionBar.Tab tab = actionBar.newTab();
tab.setTabListener(listener);
tab.setText(title);
actionBar.addTab(tab); // (3)
}
}
</pre>
(1)タブには Fragment を使用するため、FragmentActivity を継承します。
(2)アクションバーでタブ表示を行うモードに設定します。
(3)各タブのFragmentのインスタンスとタブに表示する文字列を設定して、アクションバーに追加します。
(4)タブ切り替え時に、切り替え先のFragmentに置き換えます。
MainActivity の View は下記の通りです。
<pre class="brush: xml;" title="activity_main.xml">
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/tab_contents"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
</pre>
Tab1Fragment にタブの内容を実装します。
<pre class="brush: java;" title="Tab1Fragment.java">
package jp.co.pa_rk.test_tab.fragment;
import jp.co.pa_rk.test_tab.R;
import jp.co.pa_rk.test_tab.R.id;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
/**
* tab 1
*/
public class Tab1Fragment extends Fragment { // (5)
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_tab1, container, false);
TextView textView = (TextView) view.findViewById(id.text);
textView.setText("メッセージ1"); // (6)
return view;
}
}
</pre>
(5)Fragment を継承します。
(6)タブの切り替えが分かりやすいように、テキストを表示します。
※Tab1Fragment と同様に、クラス名及び、テキストの内容を変更して、
Tab2Fragment, Tab3Fragment, Tab4Fragment を作成します。
Tab1Fragment, Tab2Fragment, Tab3Fragment, Tab4Fragment に対する View は下記の通りです。
<pre class="brush: xml;" title="fragment_tab1.xml">
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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" >
<TextView
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
</pre>
ファイル構成は、以下の通りです。
root
├─res
│ └─layout
│ activity_main.xml
│ fragment_tab1.xml
│ fragment_tab2.xml
│ fragment_tab3.xml
│ fragment_tab4.xml
└─src
└─jp
└─co
└─pa_rk
└─test_tab
├─activity
│ MainActivity.java
│
└─fragment
Tab1Fragment.java
Tab2Fragment.java
Tab3Fragment.java
Tab4Fragment.java
アプリを実行したときのスクリーンショットは下記の通りです。
■アイコン付きタブを作成
次に、アイコン付きのタブを作成します。
今回は、Android公式サイトで配布されているアイコンの画像ファイルを使用します。
Action Bar Icon Pack
https://developer.android.com/design/downloads/index.html
取得したアイコンの画像ファイルを下記の構成になるように配置します。
root
└─res
└─drawable-hdpi
icon_tab1.png
icon_tab2.png
icon_tab3.png
icon_tab4.png
MainActivity の createTab()メソッドの処理を変更します。
<pre class="brush: java;" title="MainActivity.java">
private void createTab(ActionBar actionBar, MainTabListener<?> listener, int iconId, String title) {
ActionBar.Tab tab = actionBar.newTab();
tab.setText(title);
tab.setIcon(iconId); // (7)
tab.setTabListener(listener);
actionBar.addTab(tab);
}
</pre>
(7)アイコンをタブに設定して、アクションバーに追加します。
呼び出し側は下記の通りになります。
<pre class="brush: java;" title="MainActivity.java">
createTab(actionBar, new MainTabListener<Tab1Fragment>(this, Tab1Fragment.class), R.drawable.icon_tab1, "タブ1");
createTab(actionBar, new MainTabListener<Tab2Fragment>(this, Tab2Fragment.class), R.drawable.icon_tab2, "タブ2");
createTab(actionBar, new MainTabListener<Tab3Fragment>(this, Tab3Fragment.class), R.drawable.icon_tab3, "タブ3");
createTab(actionBar, new MainTabListener<Tab4Fragment>(this, Tab4Fragment.class), R.drawable.icon_tab4, "タブ4");
</pre>
アプリを実行したときのスクリーンショットは下記の通りです。

■タブのViewをカスタマイズする
次に、タブのViewをカスタマイズします。
カスタマイズ用のViewは、下記の通りです。
※tab2.xml, tab3.xml, tab4.xml もViewIdのみが異なり、その他は同様の内容になっています。
<pre class="brush: xml;" title="tab1.xml">
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="@+id/tab1_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@android:color/transparent" />
<TextView
android:id="@+id/tab1_title"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
</pre>
カスタマイズ用のViewは、下記の構成になるように格納します。
root
└─res
└─layout
tab1.xml
tab2.xml
tab3.xml
tab4.xml
MainActivity の createTab()メソッドの処理を変更します。
<pre class="brush: java;" title="MainActivity.java">
private void createTab(ActionBar actionBar, MainTabListener<?> listener, int tabId, int tabIconId, int tabTitleId, int iconId, String title) {
ActionBar.Tab tab = actionBar.newTab();
tab.setCustomView(tabId); // (8)
tab.setTabListener(listener);
actionBar.addTab(tab);
TextView textView = (TextView) findViewById(tabTitleId); // (9)
textView.setText(title);
ImageView image = (ImageView) findViewById(tabIconId); // (10)
image.setImageResource(iconId);
}
</pre>
(8)カスタマイズ用のViewを設定します。
(9)カスタマイズ用のViewのViewIdからタブのタイトルを設定します。
(10)同様にViewIdからタブのアイコンを設定します。
呼び出し側は下記の通りになります。
<pre class="brush: java;" title="MainActivity.java">
createTab(actionBar, new MainTabListener<Tab1Fragment>(this, Tab1Fragment.class), R.layout.tab1, R.id.tab1_icon, R.id.tab1_title, R.drawable.icon_tab1, "タブ1");
createTab(actionBar, new MainTabListener<Tab2Fragment>(this, Tab2Fragment.class), R.layout.tab2, R.id.tab2_icon, R.id.tab2_title, R.drawable.icon_tab2, "タブ2");
createTab(actionBar, new MainTabListener<Tab3Fragment>(this, Tab3Fragment.class), R.layout.tab3, R.id.tab3_icon, R.id.tab3_title, R.drawable.icon_tab3, "タブ3");
createTab(actionBar, new MainTabListener<Tab4Fragment>(this, Tab4Fragment.class), R.layout.tab4, R.id.tab4_icon, R.id.tab4_title, R.drawable.icon_tab4, "タブ4");
</pre>
アプリを実行したときのスクリーンショットは下記の通りです。
