Furudateのブログ

プログラミングやネットワーク系の知識・技術がメインのブログ。技術メモ帳的な感じになるかと。岩手から発信していきます。

【Android】ActionBarにタブを付けてスワイプでも画面を切り替えられるようにする

こんばんは。

今回はActionBarにタブを付けてタブで画面を切り替えられるようにします。
また、スワイプでも切り替えられるようにします。

今回はちょっとしたところですごい詰まってしまいましたが、解決したのでメモしておきます。

また、参考にさせていただいたサイトには色々とやり方がありましたが、今回は参考にしつつ自分でほんの少しだけソースを書き換えました。


以下手順です。


  • メインとなるActivityを作成(ここでは MainActivity とします)
    • BlankActivityでOK
    • Navigation Typeを Tabs + Swipe にする
  • タブに乗せるアクティビティ(Fragment)を作成
    • ここでは2つ(Fragment1, Fragment2)とします。
    • BlankActivityでOK
  • Fragment1, 2のソースを以下のように書き換える
    • 以下のソースはFragment1だけですが、2も同じような感じです。デフォルトで生成されるメニューの作成等のコードは消してOKです
package jp.sakumon.moridai;

import android.os.Bundle;
import android.support.v4.app.Fragment; // ここが大事。[import.android.app.Fragment]にするとエラーになるので、必ず[support.v4.app.Fragment]をインポートする
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class Fragment1 extends Fragment {

	@Override
	 public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
		 // 第3引数のbooleanは"container"にreturnするViewを追加するかどうか  
        //trueにすると最終的なlayoutに再度、同じView groupが表示されてしまうのでfalseでOKらしい  
        return inflater.inflate(R.layout.fragment_answer, container, false);  
	}

}
  • MainActivityのソースコードは以下のようになります。
    • ほとんど自動生成されたものですが、下記では生成されたものに出来るだけ説明を加えています
    • 初期ではDummySectionFragment という関数で各タブのビューを生成していますが、以下では別ファイル(Fragment1, 2)でビューを生成しているので削除しています。
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class MainActivity extends FragmentActivity implements ActionBar.TabListener {

	// アダプターを定義します。
	SectionsPagerAdapter mSectionsPagerAdapter;

	// ViewPagerを定義します。これでスワイプが可能になります。
	ViewPager mViewPager;

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

		// Action barのモードをタブモードに切り替え
		final ActionBar actionBar = getActionBar();
		actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

		// FragmentPagerAdapterを継承したクラスのアダプターを作成
		mSectionsPagerAdapter = new SectionsPagerAdapter(
				getSupportFragmentManager());

		// ViewPagerにSectionPagerAdapterをセット
		mViewPager = (ViewPager) findViewById(R.id.pager);
		mViewPager.setAdapter(mSectionsPagerAdapter);

		/**
		 * スワイプしたときにもActionbarのタブ(NavigationItem)を常に表示させる処理
		 */
		mViewPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() {
			@Override
			public void onPageSelected(int position) {
						actionBar.setSelectedNavigationItem(position);
			}
		});

		// getCountでタブの数を指定。
		for (int i = 0; i < mSectionsPagerAdapter.getCount(); i++) {
			// Actionbarにタブを追加。
			// getPageTitleでタブのタイトルを表示
			actionBar.addTab(actionBar.newTab()
				.setText(mSectionsPagerAdapter.getPageTitle(i))
				.setTabListener(this));
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	/**
	 * タブを選択した時の処理
	 */
	@Override
	public void onTabSelected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
		// ここで表示するフラグメントを決定する
		// setCurrentItem で、下記の SectionPagerAdapter の getItem を呼び出し
		mViewPager.setCurrentItem(tab.getPosition());
	}

	/**
	 * タブの選択が外れた場合の処理
	 */
	@Override
	public void onTabUnselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
	}

	/**
	 * タブが2度目以降に選択された場合の処理
	 */
	@Override
	public void onTabReselected(ActionBar.Tab tab, FragmentTransaction fragmentTransaction) {
	}

	/**
	 * ViewPagerの動作を作成
	 */
	public class SectionsPagerAdapter extends FragmentPagerAdapter {

		public SectionsPagerAdapter(FragmentManager fm) {
			super(fm);
		}

		/**
		 * ここでタブに表示する画面を設定する
		 * positionには0から順のタブの番号が渡される。
		 * なお、値を渡したいときはコメントアウトしてあるBundleを用いる。
		 * また、ここでreturnのFragmentの型についてのエラーが出た場合は、import で[android.app.fragment]にしている可能性あり。support.v4に変えよう
		 */
		@Override
		public Fragment getItem(int position) {
			if (position == 0){
				FragmentAnswer fragment = new FragmentAnswer();
				return fragment;
			} else {
				FragmentTest fragment = new FragmentTest();
				return fragment;
			}
			//Bundle args = new Bundle();
			// 値をBundle(保存)にする
			//args.putInt("testdata", position);
			// FragmentにBundleをセットし、値を渡す
			//fragment.setArguments(args);
		}

		/**
		 * タブの数を決定
		 */
		@Override
		public int getCount() {
			return 2;
		}

		/**
		 * タブのタイトルを決定
		 */
		@Override
		public CharSequence getPageTitle(int position) {
			switch (position) {
			case 0:
				return getString(R.string.title_section1).toUpperCase();
			case 1:
				return getString(R.string.title_section2).toUpperCase();
			}
			return null;
		}
	}
}

以上です。
これで色々と面白いことができそうです。


それでは。