タブでコンテンツ(Fragment) を切り替える


[Fragmentによるタブ作成 関連記事]

前回はFragmentによるタブのレイアウト作成の処理をメモった。今回はタブで切り替わるコンテンツ(Fragment) を作成する処理をメモる。

コンテンツ(Fragment) の作成


tab_fragment_009
今回はコンテンツ部分を Fragment で作成する。タブの切り替えが3つあるのでFragment も3つ作成する。

tab_fragment_017

フラグメントは、Fragmentクラス ( または既存のそのサブクラス ) のサブクラスを作成する。Fragment クラスのコードは Activity のそれとほとんどそっくりである。これには onCreate()、onStart()、onPause()、および onStop() などのアクティビティと同様のコールバックメソッドがある。
※詳しくは 1.1 フラグメント - ソフトウェア技術ドキュメントを勝手に翻訳 参考

"TAB1"が選択された場合のコンテンツを作成


[Tab1Fragment.java]

  
package localhost.test_tab_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 Tab1Fragment extends Fragment {
    @Override
    public View onCreateView(
    		LayoutInflater inflater,
    		ViewGroup container,
    		Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.tab1_fragment, container, false);
        return v;
    }
}

[tab1_fragment.xml]

 
<LinearLayout 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"
    android:orientation="vertical">
    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TAB1の内容(フラグメント)"/>
</LinearLayout>

FragmentはAndroid SDK 3.0 からでないとサポートされていない。Android1.6以降のSDKでもFragment が使えるようにサポートライブラリ android-support-v4.jar を使うことにする。

※テキストは@string resource を通すの望ましいが、説明上、直接指定している。
※詳しくは Android1.6以上で Fragment 対応 / android-support-v4 を参考に
    
import android.support.v4.app.Fragment;
public class Tab1Fragment extends Fragment
  • サポートライブラリを使うので "Fragmentクラス" は "android.support.v4.app" パッケージからインポートする。
  • フラグメントは、Fragmentクラス ( または既存のそのサブクラス ) のサブクラスとなるので "Fragment" を継承してクラスを作る。

"TAB2"が選択された場合のコンテンツを作成


同様に "TAB2" のコンテンツを作成する。

[Tab2Fragment.java]

package localhost.test_tab_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 Tab2Fragment extends Fragment {
    @Override
    public View onCreateView(
    		LayoutInflater inflater,
    		ViewGroup container,
    		Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.tab2_fragment, container, false);
        return v;
    }
}

[tab2_fragment.xml]

 
<LinearLayout 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"
    android:orientation="vertical">
    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TAB2の内容(フラグメント)"/>
</LinearLayout>

"TAB3"が選択された場合のコンテンツを作成


同様に "TAB3" のコンテンツを作成する。

[Tab3Fragment.java]

package localhost.test_tab_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 Tab3Fragment extends Fragment {
    @Override
    public View onCreateView(
    		LayoutInflater inflater,
    		ViewGroup container,
    		Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.tab3_fragment, container, false);
        return v;
    }
}

[tab3_fragment.xml]

 
<LinearLayout 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"
    android:orientation="vertical">
    <TextView 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="TAB3の内容(フラグメント)"/>
</LinearLayout>

TAB選択時のコンテンツ切り替え


[MainActivity.java]

 
package localhost.test_tab_fragment;

import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.widget.TabHost;
import android.widget.TabHost.TabContentFactory;
import android.widget.TabHost.TabSpec;

public class MainActivity extends FragmentActivity  implements TabHost.OnTabChangeListener {

	// TabHost
    private TabHost mTabHost;
    // Last selected tabId
    private String mLastTabId;    

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tabhost);

        mTabHost = (TabHost) findViewById(android.R.id.tabhost);
        mTabHost.setup();        

        /* Tab1 設定 */
        TabSpec tab1 = mTabHost.newTabSpec("tab1");
        tab1.setIndicator("TAB1");                  
        tab1.setContent(new DummyTabFactory(this)); 
        mTabHost.addTab(tab1); 

        // Tab2 設定
        TabSpec tab2 = mTabHost.newTabSpec("tab2");
        tab2.setIndicator("TAB2");                  
        tab2.setContent(new DummyTabFactory(this)); 
        mTabHost.addTab(tab2);

        // Tab3 設定
        TabSpec tab3 = mTabHost.newTabSpec("tab3");
        tab3.setIndicator("TAB3");                  
        tab3.setContent(new DummyTabFactory(this)); 
        mTabHost.addTab(tab3);   

        // タブ変更時イベントハンドラ
        mTabHost.setOnTabChangedListener(this);

        // 初期タブ選択
        onTabChanged("tab1");        
    }

    /*
     * タブの選択が変わったときに呼び出される
     * @Override
     */
    public void onTabChanged(String tabId) {
    	Log.d("TAB_FRAGMENT_LOG","tabId:" + tabId);
    	if(mLastTabId != tabId){
            FragmentTransaction fragmentTransaction 
                 = getSupportFragmentManager().beginTransaction();
            if("tab1" == tabId){
            	fragmentTransaction
            		.replace(R.id.realtabcontent, new Tab1Fragment());
            }else if("tab2" == tabId){
            	fragmentTransaction
            		.replace(R.id.realtabcontent, new Tab2Fragment());
            }else if("tab3" == tabId){
            	fragmentTransaction
            		.replace(R.id.realtabcontent, new Tab3Fragment());
            }
    		mLastTabId = tabId;
    		fragmentTransaction.commit();
    	}
    }   

    /*
     * android:id/tabcontent のダミーコンテンツ
     */
    private static class DummyTabFactory implements TabContentFactory {

        /* Context */
        private final Context mContext;

        DummyTabFactory(Context context) {
            mContext = context;
        }

        @Override
        public View createTabContent(String tag) {
            View v = new View(mContext);
            return v;
        }
    }  
}
タブとコンテンツを関連づけ、タブが選択されたときに対応するコンテンツに切り替える処理を作る。
 
mTabHost.setOnTabChangedListener(this);
setOnTabChangedListener で、タブが選択された場合に実行されるイベントリスナを登録する。パラメータは、TabHost.OnTabChangeListener インターフェースを実装したインスタンスで、イベント処理は onTabChanged メソッドで行う。
※TabHost | Android Developers

  • タブが変化したときのイベントリスナを setOnTabChangedListener で登録する。
  • タブが変化したときの処理は onTabChanged メソッド で行う。
 
public class MainActivity extends FragmentActivity  implements TabHost.OnTabChangeListener {
上記 setOnTabChangedListener では自分自身のインスタンス this をパラメータとして渡している。setOnTabChangedListener のパラメータは TabHost.OnTabChangeListener インターフェースを実装する必要があるので実装する。このインターフェースを実装したら、onTabChanged メソッドをオーバーライドする必要がある。
※TabHost.OnTabChangeListener | Android Developers
 
/*
 * タブの選択が変わったときに呼び出される
 * @Override
 */
public void onTabChanged(String tabId) {
	Log.d("TAB_FRAGMENT_LOG","tabId:" + tabId);
	if(mLastTabId != tabId){
        FragmentTransaction fragmentTransaction 
             = getSupportFragmentManager().beginTransaction();
        if("tab1" == tabId){
        	fragmentTransaction
        		.replace(R.id.realtabcontent, new Tab1Fragment());
        }else if("tab2" == tabId){
        	fragmentTransaction
        		.replace(R.id.realtabcontent, new Tab2Fragment());
        }else if("tab3" == tabId){
        	fragmentTransaction
        		.replace(R.id.realtabcontent, new Tab3Fragment());
        }
		mLastTabId = tabId;
		fragmentTransaction.commit();
	}
}   

TabHost.OnTabChangeListener インターフェースを実装したのでonTabChanged メソッドをオーバーライドする。タブが選択されるとこのメソッドが呼ばれる。パラメータとして選択されたタブのキーを受ける。レイアウトの "R.id.realtabcontent" 領域を、"選択されたタブと関連するフラグメント"に置き換える。(fragmentTransaction.replace)

サンプルソース


今回までのサンプルソース

 

参考



[Fragmentによるタブ作成 関連記事]

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です