2013年11月27日水曜日

デザイナーチーム用のブログ(゚∀゚)キタコレ!!

同じ部署のデザイナーチーム用のブログが解説された模様です!( ´∀`)bグッ!

そのうちそちらのブログとエンジニアメモも合併する(゚∀゚)ヨカーン

デザイナーブログ

やっぱりデザイナーさんが作ったものは見やすい(・∀・)イイネ!!

2013年11月21日木曜日

Google Maps Android API V2が表示されない

久々にGoogle Mapを使おうかと思ったら、使えなくなってたガ━━(;゚Д゚)━━ン!!

エラーログには次のように出力されていました。
11-21 12:03:42.536: E/Google Maps Android API(16076): Authorization failure.  Please see https://developers.google.com/maps/documentation/android/start for how to correctly set up the map.
11-21 12:03:42.599: E/Google Maps Android API(16076): Ensure that the following correspond to what is in the API Console: Package Name: パッケージ名, API Key: APIキー名, Certificate Fingerprint: フィンガープリント
11-21 12:03:42.677: I/Google Maps Android API(16076): Failed to contact Google servers. Another attempt will be made when connectivity is established.
11-21 12:04:00.755: E/Google Maps Android API(16076): Failed to load map. Error contacting Google servers. This is probably an authentication issue (but could be due to network errors).
APIの認証がうまく出来ていないのかと思い、
APIの設定を何度もやり直したりしましたが、一向に解決せず、半日ほど悩んでました:(;゙゚'ω゚'):
以前に作ったものは正常に動いていて、なおさら謎の現象でした(´;ω;`)ブワッ

半ば諦め状態で、実機にインストールしていたものを削除して、
再度インストールしてみると・・・Google Mapキタ――(゚∀゚)――!!

結局、何が原因だったのか分からなかったですけど・・・orz

この原因を調べる先にいくつか気になった点。

Android SDK Managerの一覧に、
「Google Play services」とは別に、
「Google Play services for Froyo」というものをハヶ━m9( ゚д゚)っ━ン!!

Android 2.2以下対象のアプリの場合には
「Google Play services for Froyo」を使う感じになるのかな?

最新版のAndroid 4.4を利用してGoogle Mapを使う場合には、
次のタグをAndroidManifest.xmlに追記する必要があるみたいです(´・∀・`)ヘー
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
上記のタグがないと次のエラーが出てしまいます。
Caused by: java.lang.IllegalStateException: The meta-data tag in your app's AndroidManifest.xml does not have the right value.  Expected 4030500 but found 0.  You must have the following declaration within the  element:     

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

参考URL

2013年11月19日火曜日

ActionBarを使ってみる(ナビゲーションドロワーとFragment Android 2.2以上)

今回は、前回のナビゲーションドロワーにFragmentを表示させてコンテンツの切り替えを試したと思います。
クリック時の動作に、Fragmentを生成するコードを追加しただけです(ΦωΦ)フフフ…

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

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.actionbar6.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>
■res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">ActionBar6</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="open">開く</string>
    <string name="close">閉じる</string>
</resources>
■activity_main.xml
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <!-- メインコンテンツ -->
    <FrameLayout
        android:id="@+id/frame_contents"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
    <!-- ナビゲーションドロワー用 -->
    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:background="#eee" />
 
</android.support.v4.widget.DrawerLayout>

■TabFirstFragment.php
package com.example.actionbar6;

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 TabFirstFragment extends Fragment {

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

  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.php
package com.example.actionbar6;

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.php
package com.example.actionbar6;

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
package com.example.actionbar6;

import java.util.ArrayList;

import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends ActionBarActivity {

 private DrawerLayout mDrawerLayout;
 private ListView mDrawerList;
 private ActionBarDrawerToggle mDrawerToggle;

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

 // ドロップダウンナビゲーションの項目名
 private static String[] mItem = { "Item 1", "Item 2", "Item 3" };

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  setContentView(R.layout.activity_main);

  ActionBar ab = getSupportActionBar();

  // アプリアイコンのクリックを有効化
  ab.setDisplayHomeAsUpEnabled(true);
  ab.setHomeButtonEnabled(true);

  // DrawerLayout
  mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
  mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
    GravityCompat.START);

  /*
   * ActionBarDrawerToggle 
   * 第1:Drawerを持っている Activity 
   * 第2:DrawerLayout
   * 第3:アイコン(UPアイコンの代わりに表示される)の drawable リソースID
   * 第4:開くというアクションの説明(アクセシビリティ用)の string リソースID
   * 第5:閉じるというアクションの説明(アクセシビリティ用)の string リソースID
   */
  // ナビゲーションドロワーの開く/閉じるトグルボタン
  mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
    R.drawable.ic_drawer, R.string.open, R.string.close) {
   /*
    * ナビゲーションドロワーが閉じた時
    * 
    * @see
    * android.support.v4.app.ActionBarDrawerToggle#onDrawerClosed(android
    * .view.View)
    */
   @Override
   public void onDrawerClosed(View drawerView) {
    Log.d("ActionBarDrawerToggle", "onDrawerClosed");
   }

   /*
    * ナビゲーションドロワーが開いた時
    * 
    * @see
    * android.support.v4.app.ActionBarDrawerToggle#onDrawerOpened(android
    * .view.View)
    */
   @Override
   public void onDrawerOpened(View drawerView) {
    Log.d("ActionBarDrawerToggle", "onDrawerOpened");
   }

   /*
    * ナビゲーションドロワーがスライド中
    * 
    * @see
    * android.support.v4.app.ActionBarDrawerToggle#onDrawerSlide(android
    * .view.View, float)
    */
   @Override
   public void onDrawerSlide(View drawerView, float slideOffset) {
    // ActionBarDrawerToggleクラス内の同メソッドにてアイコンのアニメーションの処理をしている。
    // overrideするときは気を付けること。
    super.onDrawerSlide(drawerView, slideOffset);
    Log.d("ActionBarDrawerToggle", "onDrawerSlide : " + slideOffset);
   }

   /*
    * ナビゲーションドロワーの状態が変化
    * 
    * @see
    * android.support.v4.app.ActionBarDrawerToggle#onDrawerStateChanged
    * (int)
    */
   @Override
   public void onDrawerStateChanged(int newState) {
    // 表示済み、閉じ済みの状態:0
    // ドラッグ中状態:1
    // ドラッグを放した後のアニメーション中:2
    Log.d("ActionBarDrawerToggle", "onDrawerStateChanged state : "
      + newState);
   }
  };
  // ナビゲーションドロワーのリスナー設定
  mDrawerLayout.setDrawerListener(mDrawerToggle);

  // ナビゲーションドロワーを取得する
  mDrawerList = (ListView) findViewById(R.id.left_drawer);
  // アダプターを生成する
  ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
    android.R.layout.simple_list_item_1, mItem);
  // アダプターの設定
  mDrawerList.setAdapter(adapter);
  // クリック時の挙動を設定
  mDrawerList.setOnItemClickListener(mOnItemClickListener);
 }

 /*
  * ナビゲーションドロワーがクリックされた時の挙動
  */
 private AdapterView.OnItemClickListener mOnItemClickListener = new AdapterView.OnItemClickListener() {
  @Override
  public void onItemClick(AdapterView<?> adapterView, View view, int i,
    long l) {
   // DrawerLayoutを閉じる
   mDrawerLayout.closeDrawer(mDrawerList);

   Log.d("AdapterView.OnItemClickListener",
     "closeDrawer : " + String.valueOf(i) + " : "
       + String.valueOf(l));

   createMainContentsFragment(i);
  }
 };

 /*
  * クリックされた項目に合わせて、Fragmentを生成する
  */
 public void createMainContentsFragment(int i) {

  Fragment contents = null;
  String contentsName = String.valueOf(i);
  switch (i) {

  case 0:
   //
   Log.d("createMainContentsFragment", "1");
   contents = TabFirstFragment.newInstance("1");
   break;
  case 1:
   //
   Log.d("createMainContentsFragment", "2");
   contents = TabSecondFragment.newInstance("2");
   break;
  case 2:
   //
   Log.d("createMainContentsFragment", "3");
   contents = TabThirdFragment.newInstance("3");
   break;
  default:
   Log.d("createMainContentsFragment", "default");
   break;

  }

  Log.d("createMainContentsFragment", String.valueOf(contents));
  // Fragmentを管理するFragmentManagerを取得
  FragmentManager mFragmentManager = ((FragmentActivity) this)
    .getSupportFragmentManager();

  // 追加や削除などを1つの処理としてまとめるためのトランザクションクラスを取得
  FragmentTransaction ft = mFragmentManager.beginTransaction();

  // 新規フラグメントでコンテナの内容を置き換える
  // 選択位置の文字列に等しいタグをフラグメントに与える
  ft.replace(R.id.frame_contents, contents, contentsName);

  // バックスタックに登録
  ft.addToBackStack(null);

  // 変更をコミット
  ft.commit();

 }

 @Override
 protected void onPostCreate(Bundle savedInstanceState) {
  // アニメーションを実行させる
  super.onPostCreate(savedInstanceState);
  // DrawerToggleの状態を同期する
  mDrawerToggle.syncState();
 }

 @Override
 public void onConfigurationChanged(Configuration newConfig) {
  // アニメーションを実行させる
  super.onConfigurationChanged(newConfig);
  // DrawerToggleの状態を同期する
  mDrawerToggle.onConfigurationChanged(newConfig);
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  // アプリアイコンのタップ時にナビゲーションドロワーのオープン・クローズの処理
  if (mDrawerToggle.onOptionsItemSelected(item)) {
   return true;
  }
  return super.onOptionsItemSelected(item);
 }

}

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


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

参考URL

2013年11月18日月曜日

ActionBarを使ってみる(ナビゲーションドロワー Android 2.2以上)

今回は、ActionBarのナビゲーションドロワーを試したいと思います( ´∀`)bグッ!

スマートフォンのサイトでも見かける、
横からニョキって出てくるやつですね(゚д゚)(。_。)(゚д゚)(。_。) ウンウン

ナビゲーションドロワーを利用する場合には、
アクションバーのアイコンボタンを三本線にするのがガイドラインとのことです(´・∀・`)ヘー

それようの画像は提供されているのでこちらから落としてきて利用したいと思います( ̄ー ̄)ニヤリ
Android_Navigation_Drawer_Icon_20130516.zip
ダウンロードが完了したら解凍すると、
「holo-dark」、「」のディレクトリがあるので、どちらかの中身の
「drawable-hdpi」、「drawable-mdpi」、「drawable-xhdpi」に
そのまま上書きしますド━━━━m9(゚∀゚)━━━━ン!!

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

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.actionbar5.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>
■res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">ActionBar5</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <string name="open">開く</string>
    <string name="close">閉じる</string>
</resources>
■activity_main.xml

注意点として次の項目があるそうです。
Android : Navigation Drawer を使う
・DrawerLayout をルートビューとし、その中にメインのコンンテンツを表示するビューと、NavigationDrawer として利用するビューを入れる。

DrawerLayout を利用するうえでいくつか注意点がある
・メインのコンテンツ用のビュー(上の例だとFrameLayout)は、DrawerLayout の最初のビューでなければならない
・メインのコンテンツ用のビュー の layout_width と layout_height は match_parent にする
・NavigationDrawer 用のビュー(上の例だとListView)は、layout_gravity で horizontal gravity を指定しなければならない
・RTL言語をサポートするなら left ではなく start を使う
・NavigationDrawer 用のビューは dp 単位で幅を指定し、縦は patch_parent にする
・横幅は 320dp 以上にはしない

結構注意点がある:(;゙゚'ω゚'):
<android.support.v4.widget.DrawerLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
 
    <!-- メインコンテンツ -->
    <FrameLayout
        android:id="@+id/content_frame"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
 
    <!-- ナビゲーションドロワー用 -->
    <ListView
        android:id="@+id/left_drawer"
        android:layout_width="240dp"
        android:layout_height="match_parent"
        android:layout_gravity="start"
        android:choiceMode="singleChoice"
        android:background="#eee" />
 
</android.support.v4.widget.DrawerLayout>

■MainActivity.java

ナビゲーションドロワーのオープンと、クローズの設定は、
「ActionBarDrawerToggle」で行っています。
※ActionBarがあるときのみ有効?ActionBarが無い場合にはリスナーを実装させる

Android : Navigation Drawer を使う
Drawer が開いたり閉じたりしたのを検知するには、
DrawerLayout の setDrawerListener() を使って DrawerLayout.DrawerListener をセットする。
Drawer の開閉時にはそれぞれリスナーの onDrawerOpened() と onDrawerClosed() が呼ばれる。

アプリに ActionBar があるなら、DrawerLayout.DrawerListener よりもそれを implements した ActionBarDrawerToggle が便利。

アプリアイコンでオープン・クローズする

ActionBar のアプリアイコンをタッチして Navigation Drawer を開閉させるには ActionBarDrawerToggle を使えば簡単にできる。

package com.example.actionbar5;

import android.content.res.Configuration;
import android.os.Bundle;
import android.support.v4.app.ActionBarDrawerToggle;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class MainActivity extends ActionBarActivity {

 private DrawerLayout mDrawerLayout;
 private ListView mDrawerList;
 private ActionBarDrawerToggle mDrawerToggle;

 @Override
 protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);

  setContentView(R.layout.activity_main);

  ActionBar ab = getSupportActionBar();

  // アプリアイコンのクリックを有効化
  ab.setDisplayHomeAsUpEnabled(true);
  ab.setHomeButtonEnabled(true);

  // ナビゲーションドロワーの一覧を生成
  String[] list = { "Mercury", "Venus", "Earth", "Mars" };

  // DrawerLayout
  mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
  mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow,
    GravityCompat.START);

  /*
   * ActionBarDrawerToggle 
   * 第1:Drawerを持っている Activity 
   * 第2:DrawerLayout
   * 第3:アイコン(UPアイコンの代わりに表示される)の drawable リソースID
   * 第4:開くというアクションの説明(アクセシビリティ用)の string リソースID
   * 第5:閉じるというアクションの説明(アクセシビリティ用)の string リソースID
   */
  // ナビゲーションドロワーの開く/閉じるトグルボタン
  mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
    R.drawable.ic_drawer, R.string.open, R.string.close) {
   /*
    * ナビゲーションドロワーが閉じた時
    * 
    * @see
    * android.support.v4.app.ActionBarDrawerToggle#onDrawerClosed(android
    * .view.View)
    */
   @Override
   public void onDrawerClosed(View drawerView) {
    Log.d("ActionBarDrawerToggle", "onDrawerClosed");
   }

   /*
    * ナビゲーションドロワーが開いた時
    * 
    * @see
    * android.support.v4.app.ActionBarDrawerToggle#onDrawerOpened(android
    * .view.View)
    */
   @Override
   public void onDrawerOpened(View drawerView) {
    Log.d("ActionBarDrawerToggle", "onDrawerOpened");
   }

   /*
    * ナビゲーションドロワーがスライド中
    * 
    * @see
    * android.support.v4.app.ActionBarDrawerToggle#onDrawerSlide(android
    * .view.View, float)
    */
   @Override
   public void onDrawerSlide(View drawerView, float slideOffset) {
    // ActionBarDrawerToggleクラス内の同メソッドにてアイコンのアニメーションの処理をしている。
    // overrideするときは気を付けること。
    super.onDrawerSlide(drawerView, slideOffset);
    Log.d("ActionBarDrawerToggle", "onDrawerSlide : " + slideOffset);
   }

   /*
    * ナビゲーションドロワーの状態が変化
    * 
    * @see
    * android.support.v4.app.ActionBarDrawerToggle#onDrawerStateChanged
    * (int)
    */
   @Override
   public void onDrawerStateChanged(int newState) {
    // 表示済み、閉じ済みの状態:0
    // ドラッグ中状態:1
    // ドラッグを放した後のアニメーション中:2
    Log.d("ActionBarDrawerToggle", "onDrawerStateChanged state : "
      + newState);
   }
  };
  // ナビゲーションドロワーのリスナー設定
  mDrawerLayout.setDrawerListener(mDrawerToggle);

  // ナビゲーションドロワーを取得する
  mDrawerList = (ListView) findViewById(R.id.left_drawer);
  // アダプターを生成する
  ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
    android.R.layout.simple_list_item_1, list);
  // アダプターの設定
  mDrawerList.setAdapter(adapter);
  // クリック時の挙動を設定
  mDrawerList.setOnItemClickListener(mOnItemClickListener);
 }

 /*
  * ナビゲーションドロワーがクリックされた時の挙動
  */
 private AdapterView.OnItemClickListener mOnItemClickListener = new AdapterView.OnItemClickListener() {
  @Override
  public void onItemClick(AdapterView<?> adapterView, View view, int i,
    long l) {
   // DrawerLayoutを閉じる
   mDrawerLayout.closeDrawer(mDrawerList);

   Log.d("AdapterView.OnItemClickListener",
     "closeDrawer : " + String.valueOf(i) + " : "
       + String.valueOf(l));
  }
 };

 @Override
 protected void onPostCreate(Bundle savedInstanceState) {
  // アニメーションを実行させる
  super.onPostCreate(savedInstanceState);
  // DrawerToggleの状態を同期する
  mDrawerToggle.syncState();
 }

 @Override
 public void onConfigurationChanged(Configuration newConfig) {
  // アニメーションを実行させる
  super.onConfigurationChanged(newConfig);
  // DrawerToggleの状態を同期する
  mDrawerToggle.onConfigurationChanged(newConfig);
 }

 @Override
 public boolean onOptionsItemSelected(MenuItem item) {
  // アプリアイコンのタップ時にナビゲーションドロワーのオープン・クローズの処理
  if (mDrawerToggle.onOptionsItemSelected(item)) {
   return true;
  }
  return super.onOptionsItemSelected(item);
 }

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

 スワイプまたは、アプリアイコンを押すと、ナビゲーションドロワーが表示される。
以上です(`・ω・´)ゞビシッ!!

参考URL

ActionBarを使ってみる(ドロップダウンナビゲーションとFragment Android 2.2以上)

今回は、ActionBarのドロップダウンナビゲーションを選択した際に、
Fragmentを切り替えて表示を試したいと思います(ΦωΦ)フフフ…

基本的には、選択時のonNavigationItemSelectedを検知して、
その中でFragmentを生成する形になります。ワッショイヽ(゚∀゚)メ(゚∀゚)メ(゚∀゚)ノワッショイ

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

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.actionbar4.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/framelayout"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
</FrameLayout>

■TabOneFragment.java
package com.example.actionbar4;

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
package com.example.actionbar4;

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
package com.example.actionbar4;

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
package com.example.actionbar4;

import java.util.ArrayList;

import android.os.Bundle;
import android.app.Activity;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.widget.ArrayAdapter;

public class MainActivity extends ActionBarActivity {

 private static ArrayList<Fragment> mTabFragments = new ArrayList<Fragment>();
 // ドロップダウンナビゲーションの項目
 private static String[] item = { "Item 1", "Item 2", "Item 3" };

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

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

  // ドロップダウンナビゲーションに表示するアダプタを登録
  ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
    android.R.layout.simple_list_item_1, item);

  MainTabListener listener = new MainTabListener(this);

  // ナビゲーションのリストとコールバックを登録する
  ab.setListNavigationCallbacks(adapter, listener);

  // リストモードに設定
  ab.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

  // アプリタイトルを非表示にする
  ab.setDisplayShowTitleEnabled(false);
  
  // タブに対するフラグメントインスタンスを生成
  mTabFragments.add(TabOneFragment.newInstance("1"));
  mTabFragments.add(TabSecondFragment.newInstance("2"));
  mTabFragments.add(TabThirdFragment.newInstance("3"));

 }

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

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

  private final Activity activity;
  private FragmentManager mFragmentManager;

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

   // Fragmentを管理するFragmentManagerを取得
   mFragmentManager = ((FragmentActivity) activity)
     .getSupportFragmentManager();
  }

  @Override
  public boolean onNavigationItemSelected(int itemPosition, long itemId) {
   // TODO Auto-generated method stub
   Log.d("ActionBar",
     "OnNavigationListener " + String.valueOf(itemPosition)
       + " : " + String.valueOf(itemId));

   // 追加や削除などを1つの処理としてまとめるためのトランザクションクラスを取得
   FragmentTransaction ft = mFragmentManager.beginTransaction();

   // 新規フラグメントでコンテナの内容を置き換える
   // 選択位置の文字列に等しいタグをフラグメントに与える
   ft.replace(R.id.framelayout, mTabFragments.get(itemPosition),
     item[itemPosition]);

   // 変更をコミット
   ft.commit();

   return true;

  }
 }

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


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

参考URL

2013年11月14日木曜日

ActionBarを使ってみる(ドロップダウンナビゲーション Android 2.2以上)

今回は、ActionBarのドロップダウンナビゲーションを試したいと思います(ΦωΦ)フフフ…

タブの時とは項目の設定方法が変わっていて、
項目の設定にはAdapterを利用します。

setListNavigationCallbacksでAdapterを渡すと、
そのデータを元にSpinner(スピナー)が生成されるみたいです。
そのSpinnerがActionBarに表示されるっぽい!(´・∀・`)ヘー

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

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

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.actionbar3.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
<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>

■MainActivity.java
package com.example.actionbar3;

import android.os.Bundle;
import android.app.Activity;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.util.Log;
import android.view.Menu;
import android.widget.ArrayAdapter;

public class MainActivity extends ActionBarActivity {

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

  // ドロップダウンナビゲーションの項目
  String[] item = { "Item 1", "Item 2", "Item 3" };

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

  // リストに表示するアダプタを登録
  ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
    android.R.layout.simple_list_item_1, item);

  // Navigationコールバックを登録する
  ab.setListNavigationCallbacks(adapter,
    new ActionBar.OnNavigationListener() {
     @Override
     public boolean onNavigationItemSelected(int itemPosition,
       long itemId) {
      Log.d("ActionBar",
        "OnNavigationListener "
          + String.valueOf(itemPosition) + " : "
          + String.valueOf(itemId));
      return false;
     }
    });

  // NavigationModeをListModeに設定
  ab.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST);

  // アプリタイトルを非表示にする
  ab.setDisplayShowTitleEnabled(false);
 }

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

}

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

アプリのタイトルを消していない状態


アプリのタイトルを消している状態
以上です(`・ω・´)ゞビシッ!!

参考URL

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

2013年11月12日火曜日

ActionBarを使ってみる(タブ表示。Android 2.2以上)

今回は前回からの続きでActionBarについてになります(`・ω・´)シャキーン
ActionBarを使ってみる(Support Library v7の設定)
※設定が終わっていない方は前回の記事を元に設定の方を行ってください。

ActionBarで利用できるものは次の種類があるそうです。
NAVIGATION_MODE_LIST
 リスト構造のNavigationを提供します
NAVIGATION_MODE_STANDARD
 一般的なNavigationです
NAVIGATION_MODE_TABS
 タブのNavigationを提供します
まずはタブの機能を使ってみたいと思います( ̄ー ̄)ニヤリ

■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

ActionBarを利用するためには、
styles.xmlに定義されているAppBaseThemeのparentに
次のうちのテーマを利用する必要があります。

・Theme.AppCompat
・Theme.AppCompat.Light
・Theme.AppCompat.Light.DarkActionBar

今回は、「Theme.AppCompat.Light」を設定しておきます。
<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
<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"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

</RelativeLayout>


■MainActivity.java

エミュレーターでは、ActionBarの中でタブが作成されているのに、
実機のスマートフォンでは、ActionBarの下にタブが表示されてしまっている・・・:(;゙゚'ω゚'):

なんでかな~?と思っていたら、端末の画面サイズによって変わるそうです。(´・∀・`)ヘー
2.05. ActionBarとインタラクション制御
複数のタブから 1 つを選択してコンテンツを切り替えるタイプのナビゲーションモードです。

タブの位置は、画面の大きさによって決定されます。
横幅の狭い画面では、アクションバーの直下に表示されますが、広い画面では、アクションバーのタイトル部分の右横にタブが統合されます。
これは、端末の画面回転時にも判定が行われるため、縦画面と横画面で動的にアクションバーのレイアウトが切り替わることになります。

画面サイズに依存せずに、見た目を似たように感じにするには、
ActionBarを消してあげれば良いかも?
// ActionBarのアイコンを表示しないようにする。 true:表示/false:非表示
ab.setDisplayShowHomeEnabled(false);
// ActionBarのタイトル名を表示しないようにする。true:表示/false:非表示
ab.setDisplayShowTitleEnabled(false);
もしくは、
// ActionBarを非表示にする。(表示にする場合にはshow)
ab.hide();
タブのリスナーはActivityに実装しました。
(そのため、implements ActionBar.TabListenerを行っています)
このonTabSelectedで選択されたタブにあった内容の画面を作成していきます。

onTabSelected
 タブが選択された場合に実行

onTabUnselected
 タブの選択が外れた場合に実行

onTabReselected
 選択されているタブが再度クリックされた場合に実行
package com.example.actionbar1;

import android.os.Bundle;
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;
import android.widget.GridView;
import android.widget.TextView;

public class MainActivity extends ActionBarActivity implements
  ActionBar.TabListener {

 private TextView mText;

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

  //
  mText = (TextView) findViewById(R.id.text);

  // 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);

  // ActionBarにタブを表示する
  ab.addTab(ab.newTab().setText("Tab1").setTabListener(this));
  ab.addTab(ab.newTab().setText("Tab2").setTabListener(this));
  ab.addTab(ab.newTab().setText("Tab3").setTabListener(this));

 }

 /*
  * 選択されているタブが再度選択された場合に実行
  * 
  * @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());
  //
  mText.setText(tab.getText());
 }

 /*
  * タブの選択が外れた場合に実行
  * 
  * @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());
 }

}
実行結果は次のようになります。
・エミュレーター実行時(ActionBarとタブがくっついてる状態)

実機で実行時(画面サイズが小さいため、ActionBarの下にタブが表示されている状態)

実機で実行時(画面サイズが小さいけど、ActionBarを非表示にすることでタブが上に詰まっている状態)
以上です(`・ω・´)ゞビシッ!!

参考URL

2013年11月11日月曜日

ActionBarを使ってみる(Support Library v7の設定。Android 2.2以上)

Android 2系でActionBarを利用するにはSupport Library v7が必要になります(´;ω;`)ウッ…

ActionBarはAndroid3.0以上であれば、次の2つの条件を満たしていれば
自動的にActionBarが追加されるそうです
・android:targetSdkVersion属性に11以上を指定、またはandroid:minSdkVersion属性に11以上を指定
※ActionBarのタブなどを利用するには、minSdkVersionが11以上である必要がある。
・ホログラフィック(もしくはホログラフィックを継承したテーマ)以外のテーマを明示的に指定していない場合

まずは、その準備を行いたいと思います。

■1.Android Support Library v7の場所を確認する

Android SDK ManagerでAndroid Support Libraryがインストールされている場合には、
SDKのインストールした場所に、Support Libraryが配置されているので、
そのディレクトリを開きます。

自分の場合には、SDKを次の場所にインストールをしたので、

C:\app\android-sdk\sdk

C:\app\android-sdk\sdk\extras\android\support

に配置されていました。

このディレクトリの中にv4,v7,v13というディレクトリが、
各API Levelに対応したSupport Libraryになります。

今回はActionBarを利用するためv7を利用します。

v7のディレクトリに「appcompat」というディレクトリがありますので、
これをImportすることになります。

※SDKのインストール先は、Window > Preferences の左側のAndroidを選択して、右側のSDK Locationで確認できる。

■2.利用するプロジェクトから参照させる。

次に、先ほどコピーしたディレクトリをライブラリーとして参照させます。 ここでかなりハマッタヨ(´;ω;`)ブワッ

Importをやってもなぜか次のようなエラーが大量に出てしまい進めなかったです。
android-support-v7-appcompat\res\values-v14\styles_base.xml:24: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.ActionBar'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:28: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.Light.ActionBar'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:32: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.ActionBar.Solid'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:36: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.Light.ActionBar.Solid'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:40: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.Light.ActionBar.Solid.Inverse'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:122: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.ActionButton'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:125: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.Light.ActionButton'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:129: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.ActionButton.CloseMode'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:133: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.Light.ActionButton.CloseMode'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:137: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.ActionButton.Overflow'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:141: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.Light.ActionButton.Overflow'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:44: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.ActionBar.TabBar'.
android-support-v7-appcompat\res\values-v14\styles_base.xml:48: error: Error retrieving parent for item: No resource found that matches the given name 'android:Widget.Holo.Light.ActionBar.TabBar'.
数時間ほど色々悩んだ結果、プロジェクトを作成する時に指定する、
Minimum Required SDK、Target SDK、Compile Withが問題な事に気づきましたハヶ━m9( ゚д゚)っ━ン!!

元々の設定では、次のように設定していました。
Minimum Required SDK API 8: Android 2.2 (Froyo)
Target SDK API 8: Android 2.2 (Froyo)
Compile With API 8: Android 2.2 (Froyo)
これだとうまく行かず、色々調べてみたら各項目の意味は次となっているようなので、
Minimum Required SDK
 動作する最低レベルのSDK
 ここで選択したバージョンより低いレベルのSDKではアプリがインストールできない状態になります
 APIの最低レベルがこのバージョンになる

Target SDK
 メインターゲットとする端末のSDKのバージョンを設定。
 Target SDKのバージョンより古いSDKでもアプリは動作します。

Compile With
 どのSDKのバージョンのコンパイラでビルドするかを指定
 Minimum Required SDK"や"Target SDK"と違い、すべてのバージョンのコンパイラは表示されません。
 コンパイラは新しいものほど改善が進んでいるため通常は最新のコンパイラを指定します。
いまいち、Target SDKが良く分からなかったですけど、
こちらの記事を読んだら多少わかりましたφ(゚Д゚ )フムフム…
Android:SDKバージョンについてなどから抜粋
★ターゲットにすべきバージョン
基本的に最新バージョンのSDKをターゲットにして、
つまり最新バージョンのライブラリを使用して開発すると問題ないはずです。
古いバージョンの端末に対応するにはAndroidManifest.xml中の
minSdkVersionを低く設定し、ソースコード内でそれぞれのバージョンに対応した
処理を記述します。
古いバージョンをターゲットにしてしまうと逆に新しいバージョン用のコードが
コンパイルできなくなってしまうためです。
minSdkVersionとターゲットのAPIレベルが異なると警告がでますが問題ありません。

Target SDKと、Compile Withを最新の形に変更したらうまく行きましたド━━━━m9(゚∀゚)━━━━ン!!

変更後
Minimum Required SDK: API 8: Android 2.2 (Froyo)
Target SDK API 8: API 17: Android 4.2 (Jelly Bean)
Compile With: API 19: Android 4.4
ちなみに次の設定でも問題ありませんでした!
Minimum Required SDK: API 8: Android 2.2 (Froyo)
Target SDK: API 8: Android 2.2 (Froyo)
Compile With: API 19: Android 4.4
ということは、Compile WithのAPI Levelが低いとダメってことですねc⌒っ゚д゚)っφ メモメモ...

上記の設定でプロジェクトを作成した後に下記の手順を行ってください!( ´∀`)bグッ!

Eclipseの「File」>「Import」で次の画面を開きます。

次に、「Android」 > 「Android Project from Existing Code」を選択して、「Next」を押します。

 Import Projects画面が開いたら、
「Browse...」を選択して、手順1で確認したSupport Library v7のappcompatディレクトリを選択し、
「Copy projects into workspace」にチェックしてから「Finish」を押します。

問題なく進むと、Package Explorerに、
「android-support-v7-appcompat」というプロジェクトが追加されます。
「android-support-v7-appcompat」を右クリックして、
「Properties」を選択します。
左の項目からAndroidを選択して、
右下にある「Is Library」が選択されている事を確認する。
■3.appcompatライブラリーの読み込み

このライブラリーを利用したいプロジェクトから参照させます。

参照させたいプロジェクトを右クリックして、
「Properties」を選択します。

開いた画面での左側にあるAndroidをクリックして、
右下にある「Add...」をクリックします。

一覧から「android-support-v7-appcompat」を選択して、「OK」を押します。
画面が戻ったら、正しく追加されている事を確認して「OK」を押します。
別のやり方としては、jarをそのままコピーするやり方があります。

手順1で確認したappcompatディレクトリの中にlibsがあり、
その中に「android-support-v4.jar」、「android-support-v7-appcompat.jar」があります。

このjarファイルを、利用するプロジェクトのlibsディレクトリにコピーします。
※既に「android-support-v4.jar」がある場合には、「android-support-v7-appcompat.jar」のみコピーする。
これだけ利用が可能になるみたいです(゚д゚)(。_。)(゚д゚)(。_。) ウンウン

注意点として、ActionBarを使う場合には、
次の2点を気をつける必要があります。

・ActivityはActionBarActivity を継承する。
※ActionBarActivityはFragmentActivityを継承している

・AppCompat のテーマを設定する
テーマは、styles.xmlのテーマを「Theme.AppCompat」にする必要がある。
それ以外のものが設定されていると次のようなエラーが発生してしまいます。
Caused by: java.lang.IllegalStateException: You need to use a Theme.AppCompat theme (or descendant) with this activity.
↓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>

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

参考URL

PagerTabStripを使ってみる

今回は、PagerTabStripを使ってみたいと思います(`・ω・´)シャキーン

■PagerTabStripとは
・PagerTabStripはViewPagerにタブ機能を追加するためのもの
・Support Package に含まれているので Android 1.6 (APIレベル4) から使用することができる。
・作ったタブが全部表示されているわけではなく、必要な分だけ表示されるので数が多い時に便利かも? ・タブの部分をスクロールさせる事もできる。

Google Playでも使われているそうです(´・∀・`)ヘー
↓このへんかな?

■AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.pagertabstrip1"
    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.pagertabstrip1.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>

■activity_main.xml
<android.support.v4.view.ViewPager xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/pager"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity" >
    <android.support.v4.view.PagerTabStrip
        android:id="@+id/pager_tab_strip"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_gravity="top"
        android:background="#333333"
        android:paddingTop="6dp"
        android:paddingBottom="6dp" />
</android.support.v4.view.ViewPager>

■PagerFragment.java
タブが選択されたときに表示するページの内容を作成しています。
単にテキストビューを1つ動的に作っています( ゚д゚)
package com.example.pagertabstrip1;

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 PageFragment extends Fragment {

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {

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

}
■MyFragmentPagerAdapter.java
ViewPagerに渡すAdapterを生成しています。
内部でタブが選択されたときに表示するFragmentを生成しています。
package com.example.pagertabstrip1;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;

public class MyFragmentPagerAdapter extends FragmentPagerAdapter {

 private String[] pageTitle = { "Page1", "Page2", "Page3" };

 public MyFragmentPagerAdapter(FragmentManager fragmentManager) {
  super(fragmentManager);
 }

 @Override
 public Fragment getItem(int position) {
  
  //選択されたページ内のFragmentを生成する
  Fragment fragment = new PageFragment();
  //Fragmentに渡す引数を生成する
  Bundle arguments = new Bundle();
  arguments.putString("pageIndex", Integer.toString(position + 1));
  fragment.setArguments(arguments);
  
  return fragment;
 }

 @Override
 public int getCount() {
  return pageTitle.length;
 }

 @Override
 public CharSequence getPageTitle(int position) {
  return pageTitle[position];
 }

}
■MainActivity.java
PagerTabStripとViewPagerの設定を行っています。
package com.example.pagertabstrip1;

import android.graphics.Color;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.PagerTabStrip;
import android.support.v4.view.ViewPager;
import android.util.TypedValue;

public class MainActivity extends FragmentActivity {

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

  // PagerTabStrip
  PagerTabStrip pagerTabStrip = (PagerTabStrip) findViewById(R.id.pager_tab_strip);
  // 文字サイズを変更する
  pagerTabStrip.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14);
  // 文字色を変更する
  pagerTabStrip.setTextColor(0xff9acd32);
  // ページタイトルの間隔を変更する
  pagerTabStrip.setTextSpacing(50);
  // 非表示のページタイトルの透過度を変更する
  pagerTabStrip.setNonPrimaryAlpha(0.3f);
  // 下線の表示/非表示を変更する
  pagerTabStrip.setDrawFullUnderline(true);
  // ページタイトルのインジケータの色を変更する
  pagerTabStrip.setTabIndicatorColor(0xff9acd32);
  
  //
  FragmentPagerAdapter fragmentPagerAdapter = new MyFragmentPagerAdapter(
    getSupportFragmentManager());

  //ViewPagerを取得
  ViewPager viewPager = (ViewPager) findViewById(R.id.pager);
  //adapterの設定
  viewPager.setAdapter(fragmentPagerAdapter);

 }

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

タブの部分が多いと、デフォルトで表示される数が決まっているのか、残りの部分は隠れるみたいですね。

2ページ目に行くと、1ページ目、2ページ目、3ページ目のタブが表示されました。
ちなみに、タブの部分をスクロールさせる事もできました。
タブの量が多い時には便利かも(゚д゚)(。_。)(゚д゚)(。_。) ウンウン

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

参考URL

2013年11月6日水曜日

FragmentTabHostを使ってみる

今回は、FragmentTabHostを試したいと思います(`・ω・´)シャキーン

・FragmentTabHostはFragmentをタブで切り替えるためのView。
・Support Packageを利用すればAndroid 1.6から使用することができる。

TabActivity、TabHostはAndroid 3.0 以降は非推奨とのことなので、
今後はFragmentTabHostもしくは、ActionBarを使うようにした方が(・∀・)イイ!!ってことかな?

■AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.fragmenttaghost1"
    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.fragmenttaghost1.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>
■activity_main.xml

FragmentTabHost配下にあるTabWidget(@android:id/tabs)と、
FrameLayout(@android:id/tabcontent)は必須になる。
※名前もこの名前にしないとエラーが出てしまう。
<!-- タブ全体の定義 -->
<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を配置 -->
        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            android:orientation="horizontal" />
        <!-- タブパネルを束ねるためのコンテナーを配置 -->
        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0" />
        <!-- タブが押された時に表示するコンテンツ領域(Fragment) -->
        <FrameLayout
            android:id="@+id/content"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />
    </LinearLayout>
</android.support.v4.app.FragmentTabHost>
■TabFragment.java

タブが選択されたときに表示させるFragmentになります。
package com.example.fragmenttaghost1;

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

/*
 * タブがクリックされた時に表示するFragment
 */
public class TabFragment extends Fragment {

 @Override
 public View onCreateView(LayoutInflater inflater, ViewGroup container,
   Bundle savedInstanceState) {

  String name = getArguments().getString("name");
  Log.d("TabFragment.onCreateView", name);
  
  TextView textView = new TextView(getActivity());
  textView.setGravity(Gravity.CENTER);
  textView.setText(getArguments().getString("name"));

  return textView;
 }

}

■MainActivity.java

setIndicatorで、タブのViewを設定する必要がありますが、
文字列を渡すとことで、デフォルトのViewが使われるそうです。

ここで任意のViewを渡せば任意のタブに変更が行えます。
たとえば次のようにButtonを設定して、バックグラウンドに画像を設定すると、
タブを指定の画像で表示する事ができます。
//Buttonビューを生成
Button button = new Button(this);
//Buttonのバックグラウンドに画像を設定
button.setBackgroundResource(R.drawable.tab_left);
//タブに設定
tabSpec.setIndicator(button);

内部クラスとしてSampleFragmentがありますが、
今回は、TabFragmentを利用しているので利用していません。

もし、クラスファイルを分けるのが嫌っていう方は、
下記のように内部クラスとして定義して、次のように変更すれば同じように動作します。

・変更前
mTabHost.addTab(tabSpec, TabFragment.class, bundle);
・内部クラスを利用するパターン
mTabHost.addTab(tabSpec, SampleFragment.class, bundle);
ファイルを分けたくない人は内部クラスとして記述すると(・∀・)イイネ!!
ただのその際の注意として、内部クラスで記述する場合には
クラスをstaticにしないとエラーが出てしまっていました(´;ω;`)ウッ…
package com.example.fragmenttaghost1;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentTabHost;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TabHost.TabSpec;
import android.widget.TextView;

public class MainActivity extends FragmentActivity implements
  FragmentTabHost.OnTabChangeListener {

 private FragmentTabHost mTabHost;
 //
 private String[] TabTag = { "お気に入りお気に入りお気に入り", "tab2", "tab3", "tab4",
   "tab5" };

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

  // FragmentTabHostを取得する
  mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);

  // Context、FragmentManager、タブ選択時にFragmentを挿入するリソースID
  mTabHost.setup(this, getSupportFragmentManager(), R.id.content);

  for (int i = 0; i < TabTag.length; i++) {

   String name = TabTag[i];

   Log.d("tabSpec", TabTag[i]);

   // Fragmentに渡す値を生成する
   Bundle bundle = new Bundle();
   bundle.putString("name", name);

   // TabSpecの生成。引数にはタブのタグを設定する
   TabSpec tabSpec = mTabHost.newTabSpec(name);
   // タブで利用するViewを生成する(String を渡すとデフォルトのタブボタンの Viewが使われる)
   tabSpec.setIndicator(name);
   /*
    * タブの追加
    * 
    * @param TabSpec
    * 
    * @param タブが選択されたときに表示したい Fragment を Class で渡す
    * 
    * @param Fragmentで読み込みたいデータを Bundle で渡す
    */
   mTabHost.addTab(tabSpec, TabFragment.class, bundle);

  }

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

 }

 /*
  * タブの選択が変わったときに呼び出される
  * 
  * @see
  * android.widget.TabHost.OnTabChangeListener#onTabChanged(java.lang.String)
  */
 @Override
 public void onTabChanged(String arg0) {
  // TODO Auto-generated method stub
  Log.d("onTabChanged", "tabId:" + arg0);
 }

 /*
  * タブがクリックされた時に表示するFragment
  */
 public static class SampleFragment extends Fragment {

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
    Bundle savedInstanceState) {

   String name = getArguments().getString("name");
   Log.d("TabFragment.onCreateView", name);

   TextView textView = new TextView(getActivity());
   textView.setGravity(Gravity.CENTER);
   textView.setText(getArguments().getString("name"));

   return textView;
  }

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

何かタブ内の文字数が多いと、文字がスクロールするらしい:(;゙゚'ω゚'):

今回で言うとお気に入りタブボタンが選択されているとスクロールしていました(´・∀・`)ヘー


別のタブをクリックすると、中身が変わります( ´∀`)bグッ!

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

参考URL

Fragmentを使ってみる(ファクトリメソッドを利用して引数を渡す)

今回は、Fragmentを生成する際に引数を渡したいと思います。

以前の「Fragmentを使ってみる(動的に追加&引数を渡す)」で、
Fragmentに値を渡したい場合にはBandleを利用する必要があると書きましたが、
どうしても生成時に値を渡したい方は、次のようにファクトリメソッドを用意する事で実現が可能になります。

Fragmentを使ってみる(動的に追加&引数を渡す)で利用したコードを、
一部変更してファクトリメソッドに対応したバージョンに書き換えたいと思います。

■AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.fragment9"
    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.fragment9.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>

■fragment_main.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"
    android:gravity="center"
    android:background="#eeeeee"
    >
     
    <TextView
        android:id="@+id/text_view"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginBottom="10dp"
        />
     
    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/ic_launcher"
        />
 
</LinearLayout>

■activity_main.xml
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >
 
    <LinearLayout
        android:id="@+id/layout_fragment_1"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical"
        android:background="#ff0000"
        />
 
    <LinearLayout
        android:id="@+id/layout_fragment_2"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"
        android:orientation="vertical"
        android:background="#00ff00"
         />
 
</LinearLayout>

■MainFragment.java

ファクトリメソッドのnewInstanceを用意します。
インスタンスを生成する場合にはこの関数を経由して必ず生成するようにします:(;゙゚'ω゚'):

ファクトリメソッドの中で、引数で渡された値を保持しておきます。
(保持させないとFragmentの再構成時に引数が引き継がれない)
package com.example.fragment9;

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

public class MainFragment extends Fragment {
 
 /*
  * フラグメントを作成するためのファクトリメソッド
  */
 public static MainFragment newInstance(String title) {
  MainFragment fragment = new MainFragment();
  
  Bundle args = new Bundle();
  args.putString("title", title);
  // フラグメントに渡す値をセット
  fragment.setArguments(args);

  return fragment;
 }

 /**
  * Viewnoの生成
  * 
  * @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) {

  // Bundleで保存されたデータを復元
  String title = getArguments().getString("title");

  //
  Log.d("onCreateView", title);

  // 第1引数:レイアウトXMLファイルのリソースID、
  // 第2引数:
  // 第3引数:trueにするかfalseにするかで戻り値となるルートビュー(View)が変わる。
  // trueの場合には、第2引数で渡したViewGrou、falseの場合には第1引数で渡したリソースIDがルートビューになる
  View view = inflater.inflate(R.layout.fragment_main, container, false);
  //
  TextView text = (TextView) view.findViewById(R.id.text_view);
  text.setText(title);
  //
  return view;
 }

}
■MainActivity.java
Fragmentを生成するところの処理が次のように変更します。

・変更前
        //1つ目のfragmentを生成
        MainFragment fragment1 = new MainFragment();
        Bundle bundle1 = new Bundle();
        bundle1.putString("title", "キタ――(゚∀゚)――!!");
        // フラグメントに渡す値をセット
        fragment1.setArguments(bundle1);
・変更後
        //1つ目のfragmentを生成
        MainFragment fragment1 = MainFragment.newInstance("キタ――(゚∀゚)――!!");
変更後の方は内部でBundleを行っているためスッキリしました( ´∀`)bグッ!
package com.example.fragment9;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
 
public class MainActivity extends FragmentActivity {
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        //Fragmentを管理するFragmentManagerを取得
        FragmentManager manager = getSupportFragmentManager();
        //追加や削除などを1つの処理としてまとめるためのトランザクションクラスを取得
        FragmentTransaction tx = manager.beginTransaction();
        
        //1つ目のfragmentを生成
        MainFragment fragment1 = MainFragment.newInstance("キタ――(゚∀゚)――!!");

        //2つ目のfragmentを生成
        MainFragment fragment2 = MainFragment.newInstance("クル━━━━(゚∀゚)━━━━!!");
        
        //Fragment をスタックに追加する
        //メインレイアウトに対して追加先のビューのID、Fragment、Fragmentのタグ。
        //add() したときに既にバックスタックに同じタグの Fragment が存在する場合、
        //Fragment は新規作成されず、既にインスタンス化してある Fragment が再表示される。
        tx.add(R.id.layout_fragment_1, fragment1, "layout_fragment_1");
        tx.add(R.id.layout_fragment_2, fragment2, "layout_fragment_2");
        // 
        tx.commit();
    }
 
}
実行結果は次のようになります。


Fragment側でBundleした方が呼び出し側のコードがスッキリするし、
FragmentのことはFragment側だけで殆どの流れが把握できるので(・∀・)イイネ!!

今度からこっちを使っていこうかな~(ΦωΦ)フフフ…

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

参考URL