2013年11月14日木曜日

ActionBarを使ってみる(タブ切り替えでFragmentを表示させる。Android 2.2以上)

今回は、ActionBarのタブを選択したときに、
タブに紐づく内容をFragmentで表示させて、切り替えられるようにしました(ΦωΦ)フフフ…

何となくFragmentTagHostに似てるな~と思った(゚д゚)(。_。)(゚д゚)(。_。) ウンウン

■AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.actionbar2"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="8" />

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.actionbar2.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>
■res/values/styles.xml
<resources>

    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
    -->
    <style name="AppBaseTheme" parent="Theme.AppCompat.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>

</resources>
■activity_main.xml
<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>

■TabOneFragment.java

ActionBarの1つめのタブ用のクラスになります。
FragmentのViewにはTextViewを1つだけ作って中央に寄せています。
package com.example.actionbar2;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TabOneFragment extends Fragment {

 /*
  * フラグメントを作成するためのファクトリメソッド
  */
 public static TabOneFragment newInstance(String title) {
  TabOneFragment fragment = new TabOneFragment();

  Bundle args = new Bundle();
  args.putString("title", title);
  // フラグメントに渡す値をセット
  fragment.setArguments(args);

  return fragment;
 }

 /**
  * 
  * @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater,
  *      android.view.ViewGroup, android.os.Bundle)
  */
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {

  // TextViewを生成する
  TextView textView = new TextView(getActivity());
  // 幅、高さの設定
  LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(
    LinearLayout.LayoutParams.MATCH_PARENT,
    LinearLayout.LayoutParams.MATCH_PARENT);
  textView.setLayoutParams(layout);
  // 文字の位置の設定
  textView.setGravity(Gravity.CENTER);
  // 文字を設定
  textView.setText(getArguments().getString("title"));
  // フォントサイズ変更
  textView.setTextSize(180.0f);

  //
  return textView;
 }
}
■TabSecondFragment.java

ActionBarの2つめのタブ用のクラスになります。
FragmentのViewにはTextViewを1つだけ作って中央に寄せています。
package com.example.actionbar2;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TabSecondFragment extends Fragment {

 /*
  * フラグメントを作成するためのファクトリメソッド
  */
 public static TabSecondFragment newInstance(String title) {
  TabSecondFragment fragment = new TabSecondFragment();

  Bundle args = new Bundle();
  args.putString("title", title);
  // フラグメントに渡す値をセット
  fragment.setArguments(args);

  return fragment;
 }

 /**
  * 
  * @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater,
  *      android.view.ViewGroup, android.os.Bundle)
  */
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {

  // TextViewを生成する
  TextView textView = new TextView(getActivity());
  // 幅、高さの設定
  LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(
    LinearLayout.LayoutParams.MATCH_PARENT,
    LinearLayout.LayoutParams.MATCH_PARENT);
  textView.setLayoutParams(layout);
  // 文字の位置の設定
  textView.setGravity(Gravity.CENTER);
  // 文字を設定
  textView.setText(getArguments().getString("title"));
  // フォントサイズ変更
  textView.setTextSize(180.0f);

  //
  return textView;
 }

}
■TabThirdFragment.java

ActionBarの3つめのタブ用のクラスになります。
FragmentのViewにはTextViewを1つだけ作って中央に寄せています。
package com.example.actionbar2;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;

public class TabThirdFragment extends Fragment {

 /*
  * フラグメントを作成するためのファクトリメソッド
  */
 public static TabThirdFragment newInstance(String title) {
  TabThirdFragment fragment = new TabThirdFragment();

  Bundle args = new Bundle();
  args.putString("title", title);
  // フラグメントに渡す値をセット
  fragment.setArguments(args);

  return fragment;
 }

 /**
  * 
  * @see android.support.v4.app.Fragment#onCreateView(android.view.LayoutInflater,
  *      android.view.ViewGroup, android.os.Bundle)
  */
 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {

  // TextViewを生成する
  TextView textView = new TextView(getActivity());
  // 幅、高さの設定
  LinearLayout.LayoutParams layout = new LinearLayout.LayoutParams(
    LinearLayout.LayoutParams.MATCH_PARENT,
    LinearLayout.LayoutParams.MATCH_PARENT);
  textView.setLayoutParams(layout);
  // 文字の位置の設定
  textView.setGravity(Gravity.CENTER);
  // 文字を設定
  textView.setText(getArguments().getString("title"));
  // フォントサイズ変更
  textView.setTextSize(180.0f);

  //
  return textView;
 }

}
■MainActivity.java

前回はActionBarのタブ用のリスナーをActivityで実装していましたが、
今回は内部クラスを作成して、そこでリスナーを実装しています。

onTabSelectedでタブが選択されたときを検知して、Fragmentを置換しています。

onTabSelectedで選択されたときにreplaceではなくてaddを利用してFragmentを追加した場合には、
onTabUnselectedで、Fragmentをremoveする必要がある。

起動時には、3番目のタブが選択されるように、
setSelectedNavigationItemで指定しています。
package com.example.actionbar2;

import java.util.ArrayList;

import android.app.Activity;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBar.Tab;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;

public class MainActivity extends ActionBarActivity {

 private static ArrayList<Fragment> mTabFragments = new ArrayList<Fragment>();

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

  // action bar を取得する
  ActionBar ab = getSupportActionBar();

  // ActionBarのアイコンを表示しないようにする。 true:表示/false:非表示
  ab.setDisplayShowHomeEnabled(false);
  // ActionBarのタイトル名を表示しないようにする。true:表示/false:非表示
  ab.setDisplayShowTitleEnabled(false);

  // ActionBarのNavigationModeを設定する
  ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);

  // タブに対するフラグメントインスタンスを生成
  mTabFragments.add(TabOneFragment.newInstance("1"));
  mTabFragments.add(TabSecondFragment.newInstance("2"));
  mTabFragments.add(TabThirdFragment.newInstance("3"));

  // リスナー生成
  MainTabListener listener = new MainTabListener(this);

  // タブにリスナーを追加する
  Tab tab1 = ab.newTab().setText("Tab1").setTabListener(listener);
  Tab tab2 = ab.newTab().setText("Tab2").setTabListener(listener);
  Tab tab3 = ab.newTab().setText("Tab3").setTabListener(listener);

  // タブを追加する
  ab.addTab(tab1);
  ab.addTab(tab2);
  ab.addTab(tab3);

  // デフォルトの状態選択を変更する
  ab.setSelectedNavigationItem(2);

 }

 /*
  * ActionBarのタブリスナー
  */
 public static class MainTabListener implements ActionBar.TabListener {

  private final Activity activity;

  public MainTabListener(Activity activity) {
   this.activity = activity;
  }

  /*
   * 選択されているタブが再度選択された場合に実行
   * 
   * @see
   * android.support.v7.app.ActionBar.TabListener#onTabReselected(android.
   * support.v7.app.ActionBar.Tab,
   * android.support.v4.app.FragmentTransaction)
   */
  @Override
  public void onTabReselected(Tab tab, FragmentTransaction ft) {
   // TODO Auto-generated method stub
   Log.d("MainActivity", "onTabReselected " + tab.getText()
     + " : position => " + tab.getPosition());
  }

  /*
   * タブが選択された場合に実行
   * 
   * @see
   * android.support.v7.app.ActionBar.TabListener#onTabSelected(android
   * .support .v7.app.ActionBar.Tab,
   * android.support.v4.app.FragmentTransaction)
   */
  @Override
  public void onTabSelected(Tab tab, FragmentTransaction ft) {
   // TODO Auto-generated method stub
   Log.d("MainActivity", "onTabSelected " + tab.getText()
     + " : position => " + tab.getPosition());
   // Fragmentの置換
   ft.replace(R.id.tab_contents, mTabFragments.get(tab.getPosition()));

  }

  /*
   * タブの選択が外れた場合に実行
   * 
   * @see
   * android.support.v7.app.ActionBar.TabListener#onTabUnselected(android.
   * support.v7.app.ActionBar.Tab,
   * android.support.v4.app.FragmentTransaction)
   */
  @Override
  public void onTabUnselected(Tab tab, FragmentTransaction ft) {
   // TODO Auto-generated method stub
   Log.d("MainActivity", "onTabUnselected " + tab.getText()
     + " : position => " + tab.getPosition());

   // Fragment削除
   // ft.remove(mFragment);

  }
 }

}
実行結果は次のようになります。

以上です(`・ω・´)ゞビシッ!!

参考URL

0 件のコメント:

コメントを投稿