2013/06/22

カスタム属性作成時の注意点

先日、自分のプロジェクトにdeclare-styleableを追加したらビルドが出来なくなったのでメモ的な。

環境:
IntelliJ 12.1.4、Android Studio 0.1.6
SDK 22.0.1、Build-tools 17

結論:
idリソースと重複する名前のdeclare-styleable > attr > enum (flag)を定義することは出来ない

具体的には、以下のように定義したidと同じ名前を持つenum、flagが定義できない。レイアウトXML等で『android:id="@+id/sample"』と設定している分には問題無いのだけれど。。。

↓コンパイルエラー

↓OK

2013/06/01

レイアウトxmlにViewの追加情報を仕込む

レイアウトxmlからViewを取得する時に、その取得対象が固定的な内容だったらFragmentに固定で書いても良いけれど、パースするxmlがコロコロ変わる場合はどのViewにどの情報を表示して良いか分からないよね!

→ xmlに仕込みを入れておけばいいじゃない!!(楽観視)


サンプル:TextViewに曜日情報を仕込んで、Activityから取得する。


こんなカスタム属性を用意しておけば、ViewのIDと日付を同時に取れます。


レイアウトxmlにこんな感じでカスタム属性を仕込みます。3行目は自分のアプリ名。namespaceのnxは「noxi」の略なので自分に合ったものに変えることをお勧めします。


android.view.LayoutInfleter$Factoryを実装したクラスを作ります。これを実装することで、xmlパースの処理をフックすることが出来ます。


LayoutInflater#fromでLayoutInflaterを取得し、setFactoryで今回作成したクラスをセットします。ちなみにLayoutInflater$Factory2とかあるらしいけど、違いは親のViewGroupが引数に入るかどうかとAPI11なこと。

2012/12/09

通知のカスタムレイアウトでつぼる

通知のカスタムレイアウトに使用するViewの最初の要素をリソースで指定すると死ぬらしい。。。


#OKな例
#NGな例

そんなん知らんがな。。。(´・ω・`)

※※※
そもそも通知の高さをdpで指定している時点でNGな気がするけれど、match_parentだと表示がおかしくなる端末、OSがあったりして、やむを得ず。

2012/02/28

SparseArrayメモ

ADT17が間もなくリリースされるそうですが、Lint先生にパフォーマンスに関する項目が追加になるそう。
Floatでjava.lang.Mathの各メソッド使うのは無駄だからandroid.util.FloatMath使えとか、Map<Integer, E>は無駄だからSparseArray使えとか。

私自身FloatMathは知っていたけれどSparseArrayはListViewのマルチチョイスモードで選択位置の取得の返り値がSparseBooleanArrayってことくらいしか知らなかったので、SparseArrayについてのメモ。
注)大分適当です


Q. SparseArrayって何?
A. キーがintでListっぽくもMapっぽくも使える何か。

Q. どう使うの?
A. Map<Integer, E>をそのままSparseArrayに書き換えればおk。

Q. キー一覧や値一覧ってどうやって取得するの?
A. forループやwhileで回して頑張れ。


値がBooleanやIntegerの場合にはSparseBooleanArrayやSparseIntegerArrayが実装されているのでそっちを使おう。
あんまりJavaの内部のことを知らないのでintとIntegerがどれくらい違うのかが分からないのだけれど、Androidで利用する分にはパフォーマンスが上がるのでしょう。


SparseArrayは内部で
private int[] mKeys;
private Object[] mValues;
private int mSize;
を管理していて、SparseArray#putで中身を突っ込むとキーと値がそれぞれに格納される。Parcelに突っ込むときはParcel#writeSparseArrayってメソッドがあるのでそれを使うか、sizeとkey、valueをループ回して突っ込もう(Parcel#writeSpaseArrayの中身はループ回してるだけなので)。逆もしかり。


###
SparseArrayは日本語に訳すと疎な配列。それぞれの値に関連性が薄いんでしょう。

2012/01/28

PreferenceActivityで一個だけPreferenceFragmentを表示する

PreferenceFragmentに対してHeader等を利用せずに一個だけPreferenceFragmentを表示したいと思ったが、中々実現できなかったのでメモ的に。(見た目とか気にしなければ、普通のActivityにトランザクションしても表示できてしまうのかもしれないけど、やってないので分からない)


PreferenceActivityのメソッドを見てみるとstartPreferenceFragment(Fragment, boolean)なんてものがあるのでこれを利用すれば出来るのかなと思ったけれど、トランザクションするView見つかんねーぞ(゚Д゚)ゴルァって怒られる。

これの原因は
全てこいつが悪い。先のメソッドは
この通りただのトランザクションなのに
こんな互換性用のレイアウトを設定してしまうためにR.id.prefsというフラグメントトランザクション用のViewが消失。PreferenceActivityで自分でトランザクションを管理するにはこのViewへの切り替えを抑制する必要がある。



長々と理由を説明しつつ、PreferenceActivityはonCreateで最初に
を読み込むため、 これで1PreferenceActivity-1PreferenceFragmentが出来る。onIsMultiPaneかonIsHidingHeadersのどちらかを上書きしないとタブレット表示時にマルチペインになってしまうかも知れないので、予防的上書き。
ちなみにinitialTitleは画面タイトル(Phoneはタイトル部、TabletはFragment上部のタイトル部分の左)、initialShortTitleはTabletでFragment上部のタイトル部分の右に表示される用のStringリソースIDだとかなんとか。

2011/12/20

AndroidでPhoneとTabletを見分ける方法

Android4.0が出て、4.0.3が出て、対応端末もリリースされ、その端末がPhoneなのかTabletなのかを見分けるって結構重要ですよね。Androidのソースコードを元にPhoneとTabletを見分ける方法の紹介です。


・~Android 3.1
Build.SDK_INT見る。ハニカム以上ならタブレット


・Android 3.1~
この様にリソースにBooleanを定義しておいて、 こんな感じ。PhoneでもWXGAの端末が出てきたりして画面ピクセル数による見分けも出来なくなった今日この頃、PhoneとTabletの最大の違いはPhoneはhdpi(1:1.5)~xhdpi(1:2)なのに対してTabletは総じてmdpi(1:1)で画面に表示出来る内容が多いこと。同じ720pxでもPhoneは360dpなのに対してTabletは720dpとして利用できます。


結論:

2011/12/17

他パッケージ(APK)のclassファイルを読み込む

ちょっと興味があって調べてみた。


結論としては
  • 他のパッケージのクラスファイルは読み込める
  • セキュリティー的に問題あるんじゃね?

某ブログには
  • SharedUserIdを共有して
  • 共有Contextを作成すればできる
なんて書いてあるけどこれは嘘。以下、その方法

まずAndroidの標準的なリソース共有方法であるContextの共有から調べてみた。 これでClassを作成しようとすると怒られます。
。。。ん?
この部分が怪しい。
と言うわけでdalvik.system.PathClassLoaderをちょっと見てみると、 mDexとかmZipとか、何となくAPKパッケージを探していそう。コンストラクタを見てみると ビンゴですね。「:」で第一引数を区切ってそこからdexファイルを取得しようとしています。
PathClassLoaderを生成するときの第一引数はクラス名ではなくAPKファイル名を指定しなければいけないようです。


つまりこういうこと

実際にやってみて驚いたのが、これを実行するのにSharedUserIdが同一である必要は無いし、電子署名が一致してる必要も無いこと。これで既存アプリの中身に直接アクセス出来ちゃいます。
試してはいませんが、リソースにもこれで直接アクセス出来てしまうのかもしれませんね。

ちなみにAndroid4.0でこのPathClassLoaderの継承元がjava.lang.ClassLoaderからdalvik.system.BaseDexClassLoaderに変わっているため、同じ方法でアクセス出来ないかもしれません。要注意。これから調べる。
どうやらAndroid4.0でもいけるっぽい? ソースコードぱっと見アウトに思えたけど、API14エミュで動いた。

最後に、例に挙げているjp.co.noxi.weathernow.Commonは実際のアプリには存在しないクラスです

2011/12/16

TextViewに適切なサイズを指定する

JavaからTextViewを生成するとき。。。テキストサイズ、なんかおかしくね?、って思ったことありませんか?
特にXMLリソースでDimensionを設定しこれをJavaで取得してTextViewに適応するとき「フォントサイズでかくね?」って思うことありませんか?


TextView#setTextSize(float)がやっていることって実は 内部でSPをちゃんとかけてます。まぁ、ちゃんとJavaDoc読めば

This size is adjusted based on the current density and user font size preference.

って書いてあるんですけどね。。。
ちなみにsetTextSize(int, float)で利用されているTypedValue#applyDimensionは
らしいので、純粋にXMLで設定したDimensionをJavaから設定するには こんな感じで指定すればいいらしい。

ただしsetTextSize(int, float)が利用できない場合は きれいじゃ無いけどしょうが無いよねっ!


ちなみにdpとspの違いは、dpは画面解像度に対してのみで決定されるのに対し、spは更にユーザーが設定に応じて倍率が変更されるらしいです。
IS05にはその倍率設定画面が見当たらないけど。。。

2011/12/06

PreferenceActivityのHeader画面でカテゴリーも表示する

API11(Android3.0)から実装されたPreferenceActivity$Header
HeaderとPreferenceFragmentを利用した設定画面の作成方法はこちらの記事で紹介した感じで簡単に作れます。

ところで。。。このHeader画面にカテゴリー表示ってどうやんの?っていう疑問。Android標準の設定画面はカテゴリー作ってんじゃんブーブー、的な。
Androidのソースコードを読んだ感じでは、標準で用意されているHeader用のListAdapterを上書きする必要があるようです。Android2.xとのCompatも含めて、以下、その方法。
ほとんどAndroidのソースコードコピペっただけですが・ω・


Header部分を構成するPreferenceなXML。
Android3.0~のXMLではカテゴリーで表示したいheaderタグにfragmentまたはintentを属性設定しないこと。

次にAndroid2.x用ヘッダー画面。
PreferenceFragmentとの共用クラス作った時とここまでは同じ。

ここからAPI11以上用のファイル達
Androidの内部リソースにアクセス出来ないため、ヘッダーで利用されているレイアウトXMLを自前で用意する必要があります。

PreferenceHeaderを表示するActivity

2011/12/05

メモ的 DialogPreference

android.preference.DialogPreferenceを利用してちょっと遊んでみた。


WeatherNow 1.6だか2.0だかではAppWidget背景の透過率を従来の10%単位から1%単位での設定に変更します。設定画面でPreferenceクリックしたらダイアログ出して、ダイアログの中でシーク+ボタン+直接入力で透過率設定出来たら便利だよね?!ってことで作ってみた。

DialogPreferenceを継承する上で重要なDialogの表示部分ですが、Androidのソースコード(4.0.1)ではこんな感じになってます。


ダイアログの表示部分自体を変えたければこのshowDialogを、ダイアログで表示する中身を変えたければonPrepareDialogBuilderを、ダイアログが閉じられたときの挙動を変えたければonClickやonDialogClosedをオーバーライドすればいいっぽいです。


そんなわけで、作ってみた。最終的なViewのアウトプットはこんな感じ。




2011/10/15

子Viewのタッチイベントを取得する

子Viewの実装の有無に関わらず、親となるViewGroupでタッチイベントを取得したい時ってありますよね。
そんな時に便利なのがViewGroup#onInterceptTouchEventというメソッド。

これを利用するには下のサンプルのようにViewGroupを継承した独自ViewGroupクラスを作成し、その中のonInterceptTouchEventを上書きする必要があります。
ひとまず流れだけ。


ちなみにこれをXMLから指定する場合は
こんな感じで使います。

2011/10/10

LayoutInflaterでツボにはまる

LayoutInflaterを利用する際は こんな感じで利用していると思いますが、ここで落とし穴。

LayoutInflater#inflate(int resource, ViewGroup root, boolean attachToRoot)
これの第2引数ViewGroupにnullを指定すると、item.xmlのパラメーターが自動でwrap_contentになってしまう。


item.xml
こんな風に指定してあったパラメーターが実際の表示上では こんなことに。。。


面倒臭くてもinflateでmatch_parent(fill_parent)パラメーターが必要なViewをもってくる時は、第2引数の親となるViewGroupをきっちり指定しましょう。

2011/09/25

Windowsでメーカー製USBドライバーを利用せずにADBで接続する

Windowsで利用していると実機を認識させるのにUSBドライバーを毎回インストールするのは面倒臭いです。
実際はメーカーのUSBドライバーを利用せずとも、Android SDKで入手できるGoogle製のドライバーを数行書き換えるだけで利用できるらしいです。


...android-sdk\extras\google\usb_driver
に「android_winusb.inf」というファイルがありますが、これに2行ほど加えるだけ。


まずは端末のハードウェアIDを確認します。
認識させたい端末を接続するとデバイスマネージャー上で不明なデバイスとして登録されているはずです。プロパティー>詳細>ハードウェアIDを確認すると

こんな文字列が得られます。

今回必要なのは
USB\VID_04DD&PID_939A&REV_0100&MI_01
この部分です。


上に記したandroid_winusb.infを開くと こんな文字列が見られるかと思います。,
ここに こんな感じで2行書き加えればOKです。
ちなみにこれは64ビット版Windowsの場合ですので、32ビット版を利用中の場合は[Google.NTx86]下に書き加え。。。た方がいいかもしれません?(未検証)


これを書き加えたらデバイスマネージャーから手動で上記フォルダーを指定してドライバーのインストールをすれば終了です。

2011/07/31

PhoneとTabletで設定メニューを共有する

Paplicoを作成していてふと気付いたことが。

Compatibility PackageにはPreferenceFragmentが無い!


PreferenceFragmentが使えるなら同じ設定画面を使い回すことが出来ると思ったのですが、どうやらPhone向けのPreferenceActivityとTablet向けの2ペインPreferenceActivityを別に作成する必要があるみたいです。
(注:ちゃんと調べてないので、もっと楽な方法があるのかも。知ってたら教えて下さい)



今回作成する設定メニューの構造はこちら


これをTabletで表示するとこんな感じ。


Phoneの方の見た目は省略(というか言わずもがな)。
Phoneでは設定画面のトップメージで「メニュー1」と「メニュー2」だけが表示される形になります。


今回のサンプルAPK及び作成したプロジェクトはこちら


・AndroidManifest.xml


今回利用するActivityは
・Main・・・PhoneかTabletかを判断して起動するメニューを分けるだけのActivity。

Phone用
・PreferenceHeader・・・スマートフォンで表示する設定メニューのトップページ。
・PreferenceActivity1・・・スマートフォンで表示する設定メニューの詳細ページ1
・PreferenceActivity1・・・スマートフォンで表示する設定メニューの詳細ページ2

Tablet用
・MainPreference・・・タブレットで表示する設定メニュー


・利用するXMLについて

まずはタブレットで利用するXMLについて。
タブレットでは2ペインのメニュー構成になっていますが、これを実現するのは非常に単純で、左ペインのヘッダー部分も右ペインの詳細メニューも共にXMLで構成することができます。

今回タブレットで使用する設定画面のXMLは全部で3つです。
・ヘッダー部分(左ペイン)
res/xml-xlarge-v11/preference_header.xml

このheaderというのはAPI11で追加されたPreferenceActivity$Headerのことで、もうちょっと詳しい使用例はこちらに載っています。
今回はheaderタグ内のfragmentに右ペインに表示するPreferenceFragmentのパスを指定しているだけですが、IntentでWebを開くとかヘッダーの左にアイコンを表示するとか、もっと色々出来るらしいです。
ただしこれはCompatibility Packageでも利用できないため、API11以降専用になります。
なおXMLファイルのフォルダから分かる通り、このXMLはXLARGE画面を持ったAPI11以降専用のXMLです。

・詳細1
res/xml/preference1.xml

PreferenceScreenが二つあるだけのいたって普通な設定画面XMLです。このXMLはスマートフォン、タブレット共用になります。
@string等のリソース詳細は割愛します。

・詳細2
res/xml/preference2.xml
詳細1と全く同じなので割愛します。


次にスマートフォンについて。
スマートフォンで利用する設定画面XMLも3つですが、詳細1・2はタブレットと共用です。スマートフォン専用で必要なのはトップページのヘッダー部分だけになります。

・ヘッダー部分
res/xml/preference_header.xml

ヘッダーを構成するPreferenceScreenが二つあり、それぞれクリックすると詳細のActivityを起動します。


・Javaについて

Androidで設定画面を利用する時にはPreferenceActivityのonCreateでaddPreferenceFromResourceを呼んで設定画面を定義したXMLを利用すると思います。今回利用するのもこの流れと全く同じなのですが、タブレットで2ペイン画面を構成するには右ペインにPreferenceFragmentを設置する必要があります。

PreferenceFragmentの利用方法はPreferenceActivityと基本的には同じで、

特に特別な処理する必要の無い設定画面であればこれだけです。
今回の趣旨は従来の、PreferenceFragmentを利用できないAndroid OSで如何に楽をして設定画面を作成するかになります。

どうすれば楽にPreferenceFragmentとPreferenceActivityの中身を融合できるのか。。。

・PreferenceWrapper.java

どちらかしか使えないので、それらから必要なメソッドを取得するクラス作ればいいじゃない!←結論
簡単な設定メニューを作成するだけであればaddPreferencesFromResource、findPreference、getStringさえ利用出来ればいいので、今回はこれらだけを含んだクラスを作成しました。


あとはこれを
・BasePreference.java

こんな感じの抽象クラスを作成して、これを実際のPreferenceActivityやPreferenceFragmentの中身にします。

・BasePhonePreferenceActivity.java

これを本当に作成すべきかは分かりませんが、こんな感じでPreferenceActivity/PreferenceFragment共に継承元のクラスを作成しておくと後でメンテがしやすい様な気がします。BasePreferenceFragmentは割愛します。


次に、タブレットでマルチペイン設定画面を構成する方法ですが、
・MainPreference.java

特に特別なことをしないならばこれだけでマルチペインの設定画面になります。
PreferenceActivity#onBuildHeadersでloadHeadersFromResourceに先程preference-headerをルートで作成したXMLを指定するだけです。各設定の詳細はPreferenceFragment内で行われるため、基本的にベースとなるPreferenceActivityでは何もする必要はありません。


設定画面をクリックしたりした際の挙動をどこかで記述する必要がありますが、それは先程紹介したBasePreferenceを継承したクラスの中で行います。
・Preference1.java

簡単な例となりますが、こんな感じ。普段PreferenceActivity#onCreateで行っている処理がこのクラスのonCreateで行います。まずaddPreferencesFromResourceメソッドを呼びXMLを指定し、その後実際の処理をつらつらと。


あとはこれを
・PreferenceActivity1.java

こんな感じで利用すれば、設定メニューが完成します。PreferenceFragmentを継承した方のクラスも全く同じ方法です。



簡単でしょ!

最後の方が雑?
じゃっかんめんどうくさくなっt

2011/07/26

アプリのSD移動について

Android2.2(API8-)で対応したアプリのSD移動について、

ビルドSDKを8以上にしAndroidManifest.xmlにinstallLocation="internalOnly"を明示しない限り、目の付け所が違う某メーカーの端末にのみ存在する「優先インストール先」設定で「microSD」を指定された場合、アプリをSDに移動できてしまう。端末側の設定に依存してSDカードへのインストールを許す場合がある。


SD移動すべきでないアプリ(ホームウィジェットやサービスを利用するアプリ)はinstallLocation="internalOnly"を明示すべきである。


ちなみにAndroid3.0にはアプリのSD移動機能がありません。
(おそらくmicroSDのサポート自体が3.0リリース当初は無かったための措置)

3.1以降は出来る。。。?
(3.1は未確認ですが、3.2には「SDへ移動」の項目が存在します)


以下、どうでもいい検証
targetAPI=7, installLocation記述なしアプリについて、

1.優先がmicroSDの時にインストールした場合
PackageManagerから取得できるinstallLocationの値は「移動可能」

2.優先がシステム判断の時にインストールした場合
PackageManagerから取得できるinstallLocationの値は「移動不可能」

3.優先がシステム判断の時にインストール >> インストール後に優先をmicroSDに変更
PackageManagerから取得できるinstallLocationの値は「移動不可能」だが
Androidの設定からはアプリをSDに移動できる


ちなみにinstallLocationの値自体はAPI8ではPackageManagerから取得できるPackageInfo、API9-ではApplicationInfoから取得できます。リフレクションで。


優先インストール先の設定はコマンドラインから
pm setInstallLocation -(数字)
で可能です。

The setInstallLocation command changes the default install location
0 [auto]: Let system decide the best location
1 [internal]: Install on internal device storage
2 [external]: Install on external media

だそうな。

adb shell pm setInstallLocation 2
で通ると優先インストール先がmicroSDになりinstallLocationを指定していないアプリはSDへ移動可能に。

2011/07/22

フラグメントのライフサイクルとかメモ 2

トランザクション等イマイチ自身の理解に欠ける部分が多いため、とりあえず色々挙動を見てみた。
(色々と言うほども無いけれど。。。)


FragmentTransactionのaddとreplaceって何が違うんだろうか、的な。


結論:
・addを呼ぶと純粋にFragmentを2枚重ねるイメージ。Activityの状態遷移と同時に二つのFragmentの状態も変わっていく。
・replaceは先にあるFragment1のViewを破棄した後に呼んだFragment2のViewを作成する。Fragment1はAttachしているActivityがonPauseに入るタイミングでFragment2と同時にonSaveInstanceStateが呼ばれ状態が保存されるが、再びFragment1がトップになるまでは呼ばれない。


動き:
1.アプリを開くとActivity1が起動する
2.Activity1がFragment1を自動的にAttachする
3.Fragment1上のボタンを押すとFragment2をActivity1でFragment1がAttachしているViewにadd/replaceする
4.Fragment2上のボタンを押すとActivity2を起動する
5.Activity2はFragment3を自動的にAttachする
6.Fragment3上のボタンを押すとActivity2が終了する
7.戻る連打でアプリを終了させる


*** FragmentTransaction#add ***

Activity2を起動しない場合

07-22 06:48:16.317: DEBUG/TEST(31299): Activity_1 : onCreate
07-22 06:48:16.377: DEBUG/TEST(31299): Activity_1 : onStart
07-22 06:48:16.377: DEBUG/TEST(31299): Fragment_1 : onAttach
07-22 06:48:16.377: DEBUG/TEST(31299): Activity_1 : onAttachFragment
07-22 06:48:16.377: DEBUG/TEST(31299): Fragment_1 : onCreate
07-22 06:48:16.377: DEBUG/TEST(31299): Fragment_1 : onCreateView
07-22 06:48:16.377: DEBUG/TEST(31299): Fragment_1 : onActivityCreated
07-22 06:48:16.387: DEBUG/TEST(31299): Fragment_1 : onStart
07-22 06:48:16.387: DEBUG/TEST(31299): Activity_1 : onPostCreate
07-22 06:48:16.387: DEBUG/TEST(31299): Activity_1 : onResume
07-22 06:48:16.387: DEBUG/TEST(31299): Fragment_1 : onResume

07-22 06:48:19.367: DEBUG/TEST(31299): Fragment_1 : onClick
07-22 06:48:19.407: DEBUG/TEST(31299): Fragment_2 : onAttach
07-22 06:48:19.407: DEBUG/TEST(31299): Activity_1 : onAttachFragment
07-22 06:48:19.407: DEBUG/TEST(31299): Fragment_2 : onCreate
07-22 06:48:19.407: DEBUG/TEST(31299): Fragment_2 : onCreateView
07-22 06:48:19.427: DEBUG/TEST(31299): Fragment_2 : onActivityCreated
07-22 06:48:19.427: DEBUG/TEST(31299): Fragment_2 : onStart
07-22 06:48:19.427: DEBUG/TEST(31299): Fragment_2 : onResume

07-22 06:48:20.387: DEBUG/TEST(31299): Activity_1 : onBackPressed
07-22 06:48:20.387: DEBUG/TEST(31299): Fragment_2 : onPause
07-22 06:48:20.387: DEBUG/TEST(31299): Fragment_2 : onStop
07-22 06:48:20.387: DEBUG/TEST(31299): Fragment_2 : onDestroyView
07-22 06:48:20.387: DEBUG/TEST(31299): Fragment_2 : onDestroy
07-22 06:48:20.387: DEBUG/TEST(31299): Fragment_2 : onDetach

07-22 06:48:20.777: DEBUG/TEST(31299): Activity_1 : onBackPressed
07-22 06:48:20.787: DEBUG/TEST(31299): Activity_1 : onPause
07-22 06:48:20.787: DEBUG/TEST(31299): Fragment_1 : onPause
07-22 06:48:20.887: DEBUG/TEST(31299): Activity_1 : onStop
07-22 06:48:20.887: DEBUG/TEST(31299): Fragment_1 : onStop
07-22 06:48:20.887: DEBUG/TEST(31299): Activity_1 : onDestroy
07-22 06:48:20.887: DEBUG/TEST(31299): Fragment_1 : onDestroyView
07-22 06:48:20.887: DEBUG/TEST(31299): Fragment_1 : onDestroy
07-22 06:48:20.887: DEBUG/TEST(31299): Fragment_1 : onDetach


起動する場合
。。。ここで色塗り力尽きる。

07-22 06:54:46.407: DEBUG/TEST(31299): Activity_1 : onCreate
07-22 06:54:46.457: DEBUG/TEST(31299): Activity_1 : onStart
07-22 06:54:46.457: DEBUG/TEST(31299): Fragment_1 : onAttach
07-22 06:54:46.457: DEBUG/TEST(31299): Activity_1 : onAttachFragment
07-22 06:54:46.457: DEBUG/TEST(31299): Fragment_1 : onCreate
07-22 06:54:46.457: DEBUG/TEST(31299): Fragment_1 : onCreateView
07-22 06:54:46.497: DEBUG/TEST(31299): Fragment_1 : onActivityCreated
07-22 06:54:46.497: DEBUG/TEST(31299): Fragment_1 : onStart
07-22 06:54:46.497: DEBUG/TEST(31299): Activity_1 : onPostCreate
07-22 06:54:46.497: DEBUG/TEST(31299): Activity_1 : onResume
07-22 06:54:46.497: DEBUG/TEST(31299): Fragment_1 : onResume

07-22 06:54:47.747: DEBUG/TEST(31299): Fragment_1 : onClick
07-22 06:54:47.747: DEBUG/TEST(31299): Fragment_2 : onAttach
07-22 06:54:47.747: DEBUG/TEST(31299): Activity_1 : onAttachFragment
07-22 06:54:47.747: DEBUG/TEST(31299): Fragment_2 : onCreate
07-22 06:54:47.747: DEBUG/TEST(31299): Fragment_2 : onCreateView
07-22 06:54:47.747: DEBUG/TEST(31299): Fragment_2 : onActivityCreated
07-22 06:54:47.747: DEBUG/TEST(31299): Fragment_2 : onStart
07-22 06:54:47.747: DEBUG/TEST(31299): Fragment_2 : onResume

07-22 06:54:48.457: DEBUG/TEST(31299): Fragment_2 : onClick
07-22 06:54:48.467: DEBUG/TEST(31299): Activity_1 : onSaveInstanceState
07-22 06:54:48.467: DEBUG/TEST(31299): Fragment_1 : onSaveInstanceState
07-22 06:54:48.467: DEBUG/TEST(31299): Fragment_2 : onSaveInstanceState
07-22 06:54:48.467: DEBUG/TEST(31299): Activity_1 : onPause
07-22 06:54:48.467: DEBUG/TEST(31299): Fragment_1 : onPause
07-22 06:54:48.477: DEBUG/TEST(31299): Fragment_2 : onPause
07-22 06:54:48.487: DEBUG/TEST(31299): Activity_2 : onCreate
07-22 06:54:48.497: DEBUG/TEST(31299): Activity_2 : onStart
07-22 06:54:48.497: DEBUG/TEST(31299): Fragment_3 : onAttach
07-22 06:54:48.497: DEBUG/TEST(31299): Activity_2 : onAttachFragment
07-22 06:54:48.497: DEBUG/TEST(31299): Fragment_3 : onCreate
07-22 06:54:48.497: DEBUG/TEST(31299): Fragment_3 : onCreateView
07-22 06:54:48.497: DEBUG/TEST(31299): Fragment_3 : onActivityCreated
07-22 06:54:48.497: DEBUG/TEST(31299): Fragment_3 : onStart
07-22 06:54:48.497: DEBUG/TEST(31299): Activity_2 : onPostCreate
07-22 06:54:48.497: DEBUG/TEST(31299): Activity_2 : onResume
07-22 06:54:48.497: DEBUG/TEST(31299): Fragment_3 : onResume
07-22 06:54:48.637: DEBUG/TEST(31299): Activity_1 : onStop
07-22 06:54:48.637: DEBUG/TEST(31299): Fragment_1 : onStop
07-22 06:54:48.637: DEBUG/TEST(31299): Fragment_2 : onStop

07-22 06:54:49.257: DEBUG/TEST(31299): Fragment_3 : onClick
07-22 06:54:49.257: DEBUG/TEST(31299): Activity_2 : finish
07-22 06:54:49.277: DEBUG/TEST(31299): Activity_2 : onPause
07-22 06:54:49.277: DEBUG/TEST(31299): Fragment_3 : onPause
07-22 06:54:49.287: DEBUG/TEST(31299): Activity_1 : onActivityResult
07-22 06:54:49.287: DEBUG/TEST(31299): Fragment_2 : onActivityResult
07-22 06:54:49.287: DEBUG/TEST(31299): Activity_1 : onRestart
07-22 06:54:49.287: DEBUG/TEST(31299): Activity_1 : onStart
07-22 06:54:49.287: DEBUG/TEST(31299): Fragment_1 : onStart
07-22 06:54:49.287: DEBUG/TEST(31299): Fragment_2 : onStart
07-22 06:54:49.287: DEBUG/TEST(31299): Activity_1 : onResume
07-22 06:54:49.287: DEBUG/TEST(31299): Fragment_1 : onResume
07-22 06:54:49.287: DEBUG/TEST(31299): Fragment_2 : onResume
07-22 06:54:49.407: DEBUG/TEST(31299): Activity_2 : onStop
07-22 06:54:49.407: DEBUG/TEST(31299): Fragment_3 : onStop
07-22 06:54:49.407: DEBUG/TEST(31299): Activity_2 : onDestroy
07-22 06:54:49.407: DEBUG/TEST(31299): Fragment_3 : onDestroyView
07-22 06:54:49.407: DEBUG/TEST(31299): Fragment_3 : onDestroy
07-22 06:54:49.407: DEBUG/TEST(31299): Fragment_3 : onDetach

07-22 06:54:49.997: DEBUG/TEST(31299): Activity_1 : onBackPressed
07-22 06:54:49.997: DEBUG/TEST(31299): Fragment_2 : onPause
07-22 06:54:49.997: DEBUG/TEST(31299): Fragment_2 : onStop
07-22 06:54:49.997: DEBUG/TEST(31299): Fragment_2 : onDestroyView
07-22 06:54:49.997: DEBUG/TEST(31299): Fragment_2 : onDestroy
07-22 06:54:49.997: DEBUG/TEST(31299): Fragment_2 : onDetach

07-22 06:54:50.997: DEBUG/TEST(31299): Activity_1 : onBackPressed
07-22 06:54:51.007: DEBUG/TEST(31299): Activity_1 : onPause
07-22 06:54:51.007: DEBUG/TEST(31299): Fragment_1 : onPause
07-22 06:54:51.287: DEBUG/TEST(31299): Activity_1 : onStop
07-22 06:54:51.287: DEBUG/TEST(31299): Fragment_1 : onStop
07-22 06:54:51.287: DEBUG/TEST(31299): Activity_1 : onDestroy
07-22 06:54:51.287: DEBUG/TEST(31299): Fragment_1 : onDestroyView
07-22 06:54:51.287: DEBUG/TEST(31299): Fragment_1 : onDestroy
07-22 06:54:51.287: DEBUG/TEST(31299): Fragment_1 : onDetach


*** FragmentTransaction#replace ***

Activity2を起動しない場合

07-22 07:08:44.957: DEBUG/TEST(32444): Activity_1 : onCreate
07-22 07:08:44.987: DEBUG/TEST(32444): Activity_1 : onStart
07-22 07:08:45.017: DEBUG/TEST(32444): Fragment_1 : onAttach
07-22 07:08:45.017: DEBUG/TEST(32444): Activity_1 : onAttachFragment
07-22 07:08:45.017: DEBUG/TEST(32444): Fragment_1 : onCreate
07-22 07:08:45.017: DEBUG/TEST(32444): Fragment_1 : onCreateView
07-22 07:08:45.037: DEBUG/TEST(32444): Fragment_1 : onActivityCreated
07-22 07:08:45.037: DEBUG/TEST(32444): Fragment_1 : onStart
07-22 07:08:45.037: DEBUG/TEST(32444): Activity_1 : onPostCreate
07-22 07:08:45.037: DEBUG/TEST(32444): Activity_1 : onResume
07-22 07:08:45.047: DEBUG/TEST(32444): Fragment_1 : onResume

07-22 07:08:48.097: DEBUG/TEST(32444): Fragment_1 : onClick
07-22 07:08:48.117: DEBUG/TEST(32444): Fragment_1 : onPause
07-22 07:08:48.117: DEBUG/TEST(32444): Fragment_1 : onStop
07-22 07:08:48.117: DEBUG/TEST(32444): Fragment_1 : onDestroyView
07-22 07:08:48.137: DEBUG/TEST(32444): Fragment_2 : onAttach
07-22 07:08:48.137: DEBUG/TEST(32444): Activity_1 : onAttachFragment
07-22 07:08:48.137: DEBUG/TEST(32444): Fragment_2 : onCreate
07-22 07:08:48.137: DEBUG/TEST(32444): Fragment_2 : onCreateView
07-22 07:08:48.147: DEBUG/TEST(32444): Fragment_2 : onActivityCreated
07-22 07:08:48.147: DEBUG/TEST(32444): Fragment_2 : onStart
07-22 07:08:48.147: DEBUG/TEST(32444): Fragment_2 : onResume

07-22 07:08:50.337: DEBUG/TEST(32444): Activity_1 : onBackPressed
07-22 07:08:50.337: DEBUG/TEST(32444): Fragment_2 : onPause
07-22 07:08:50.337: DEBUG/TEST(32444): Fragment_2 : onStop
07-22 07:08:50.337: DEBUG/TEST(32444): Fragment_2 : onDestroyView
07-22 07:08:50.337: DEBUG/TEST(32444): Fragment_2 : onDestroy
07-22 07:08:50.337: DEBUG/TEST(32444): Fragment_2 : onDetach
07-22 07:08:50.337: DEBUG/TEST(32444): Fragment_1 : onCreateView
07-22 07:08:50.347: DEBUG/TEST(32444): Fragment_1 : onActivityCreated
07-22 07:08:50.347: DEBUG/TEST(32444): Fragment_1 : onStart
07-22 07:08:50.347: DEBUG/TEST(32444): Fragment_1 : onResume

07-22 07:08:50.827: DEBUG/TEST(32444): Activity_1 : onBackPressed
07-22 07:08:51.207: DEBUG/TEST(32444): Activity_1 : onPause
07-22 07:08:51.207: DEBUG/TEST(32444): Fragment_1 : onPause
07-22 07:08:51.417: DEBUG/TEST(32444): Activity_1 : onStop
07-22 07:08:51.417: DEBUG/TEST(32444): Fragment_1 : onStop
07-22 07:08:51.417: DEBUG/TEST(32444): Activity_1 : onDestroy
07-22 07:08:51.417: DEBUG/TEST(32444): Fragment_1 : onDestroyView
07-22 07:08:51.417: DEBUG/TEST(32444): Fragment_1 : onDestroy
07-22 07:08:51.417: DEBUG/TEST(32444): Fragment_1 : onDetach


Activity2を起動する場合

07-22 07:09:58.637: DEBUG/TEST(32444): Activity_1 : onCreate
07-22 07:09:58.657: DEBUG/TEST(32444): Activity_1 : onStart
07-22 07:09:58.657: DEBUG/TEST(32444): Fragment_1 : onAttach
07-22 07:09:58.657: DEBUG/TEST(32444): Activity_1 : onAttachFragment
07-22 07:09:58.657: DEBUG/TEST(32444): Fragment_1 : onCreate
07-22 07:09:58.657: DEBUG/TEST(32444): Fragment_1 : onCreateView
07-22 07:09:58.667: DEBUG/TEST(32444): Fragment_1 : onActivityCreated
07-22 07:09:58.667: DEBUG/TEST(32444): Fragment_1 : onStart
07-22 07:09:58.667: DEBUG/TEST(32444): Activity_1 : onPostCreate
07-22 07:09:58.667: DEBUG/TEST(32444): Activity_1 : onResume
07-22 07:09:58.667: DEBUG/TEST(32444): Fragment_1 : onResume

07-22 07:09:59.447: DEBUG/TEST(32444): Fragment_1 : onClick
07-22 07:09:59.467: DEBUG/TEST(32444): Fragment_1 : onPause
07-22 07:09:59.467: DEBUG/TEST(32444): Fragment_1 : onStop
07-22 07:09:59.467: DEBUG/TEST(32444): Fragment_1 : onDestroyView
07-22 07:09:59.467: DEBUG/TEST(32444): Fragment_2 : onAttach
07-22 07:09:59.467: DEBUG/TEST(32444): Activity_1 : onAttachFragment
07-22 07:09:59.467: DEBUG/TEST(32444): Fragment_2 : onCreate
07-22 07:09:59.467: DEBUG/TEST(32444): Fragment_2 : onCreateView
07-22 07:09:59.467: DEBUG/TEST(32444): Fragment_2 : onActivityCreated
07-22 07:09:59.467: DEBUG/TEST(32444): Fragment_2 : onStart
07-22 07:09:59.467: DEBUG/TEST(32444): Fragment_2 : onResume

07-22 07:09:59.927: DEBUG/TEST(32444): Fragment_2 : onClick
07-22 07:09:59.957: DEBUG/TEST(32444): Activity_1 : onSaveInstanceState
07-22 07:09:59.957: DEBUG/TEST(32444): Fragment_1 : onSaveInstanceState
07-22 07:09:59.957: DEBUG/TEST(32444): Fragment_2 : onSaveInstanceState
07-22 07:09:59.957: DEBUG/TEST(32444): Activity_1 : onPause
07-22 07:09:59.957: DEBUG/TEST(32444): Fragment_2 : onPause
07-22 07:09:59.967: DEBUG/TEST(32444): Activity_2 : onCreate
07-22 07:09:59.967: DEBUG/TEST(32444): Activity_2 : onStart
07-22 07:09:59.967: DEBUG/TEST(32444): Fragment_3 : onAttach
07-22 07:09:59.967: DEBUG/TEST(32444): Activity_2 : onAttachFragment
07-22 07:09:59.967: DEBUG/TEST(32444): Fragment_3 : onCreate
07-22 07:09:59.967: DEBUG/TEST(32444): Fragment_3 : onCreateView
07-22 07:09:59.977: DEBUG/TEST(32444): Fragment_3 : onActivityCreated
07-22 07:09:59.977: DEBUG/TEST(32444): Fragment_3 : onStart
07-22 07:09:59.977: DEBUG/TEST(32444): Activity_2 : onPostCreate
07-22 07:09:59.977: DEBUG/TEST(32444): Activity_2 : onResume
07-22 07:09:59.977: DEBUG/TEST(32444): Fragment_3 : onResume
07-22 07:10:00.117: DEBUG/TEST(32444): Activity_1 : onStop
07-22 07:10:00.117: DEBUG/TEST(32444): Fragment_2 : onStop

07-22 07:10:00.277: DEBUG/TEST(32444): Fragment_3 : onClick
07-22 07:10:00.277: DEBUG/TEST(32444): Activity_2 : finish
07-22 07:10:00.287: DEBUG/TEST(32444): Activity_2 : onPause
07-22 07:10:00.287: DEBUG/TEST(32444): Fragment_3 : onPause
07-22 07:10:00.297: DEBUG/TEST(32444): Activity_1 : onActivityResult
07-22 07:10:00.297: DEBUG/TEST(32444): Fragment_2 : onActivityResult
07-22 07:10:00.297: DEBUG/TEST(32444): Activity_1 : onRestart
07-22 07:10:00.297: DEBUG/TEST(32444): Activity_1 : onStart
07-22 07:10:00.297: DEBUG/TEST(32444): Fragment_2 : onStart
07-22 07:10:00.297: DEBUG/TEST(32444): Activity_1 : onResume
07-22 07:10:00.297: DEBUG/TEST(32444): Fragment_2 : onResume
07-22 07:10:00.408: DEBUG/TEST(32444): Activity_2 : onStop
07-22 07:10:00.408: DEBUG/TEST(32444): Fragment_3 : onStop
07-22 07:10:00.408: DEBUG/TEST(32444): Activity_2 : onDestroy
07-22 07:10:00.408: DEBUG/TEST(32444): Fragment_3 : onDestroyView
07-22 07:10:00.408: DEBUG/TEST(32444): Fragment_3 : onDestroy
07-22 07:10:00.408: DEBUG/TEST(32444): Fragment_3 : onDetach

07-22 07:10:00.877: DEBUG/TEST(32444): Activity_1 : onBackPressed
07-22 07:10:00.877: DEBUG/TEST(32444): Fragment_2 : onPause
07-22 07:10:00.877: DEBUG/TEST(32444): Fragment_2 : onStop
07-22 07:10:00.877: DEBUG/TEST(32444): Fragment_2 : onDestroyView
07-22 07:10:00.887: DEBUG/TEST(32444): Fragment_2 : onDestroy
07-22 07:10:00.887: DEBUG/TEST(32444): Fragment_2 : onDetach
07-22 07:10:00.887: DEBUG/TEST(32444): Fragment_1 : onCreateView
07-22 07:10:00.897: DEBUG/TEST(32444): Fragment_1 : onActivityCreated
07-22 07:10:00.897: DEBUG/TEST(32444): Fragment_1 : onStart
07-22 07:10:00.897: DEBUG/TEST(32444): Fragment_1 : onResume

07-22 07:10:01.257: DEBUG/TEST(32444): Activity_1 : onBackPressed
07-22 07:10:01.267: DEBUG/TEST(32444): Activity_1 : onPause
07-22 07:10:01.267: DEBUG/TEST(32444): Fragment_1 : onPause
07-22 07:10:01.507: DEBUG/TEST(32444): Activity_1 : onStop
07-22 07:10:01.507: DEBUG/TEST(32444): Fragment_1 : onStop
07-22 07:10:01.507: DEBUG/TEST(32444): Activity_1 : onDestroy
07-22 07:10:01.517: DEBUG/TEST(32444): Fragment_1 : onDestroyView
07-22 07:10:01.517: DEBUG/TEST(32444): Fragment_1 : onDestroy
07-22 07:10:01.517: DEBUG/TEST(32444): Fragment_1 : onDetach




挙動は相当違うらしい。つづく。

2011/07/18

タブレットでFragmentを二つ表示したり消したり

タブレットでFragmentを増やしたり減らしたりする超簡単なサンプル。
画面を左右にわけ、左半分に表示されているFragment上のボタンを押すと右半分に新たなFragmentを表示させる。右Fragmentのボタンを押すと右Fragmentを一つ消す。左Fragmentのボタンを連打すると右Fragmentが多重に積み重なる。


main.xml (親ActivityのView)

・fragment.xml (FragmentのView)

・TestActivity (親Activity)

・Fragment1(画面左に最初から表示されているFragment)

・Fragment2 (画面右に表示するFragment)