Toast のビューを変更する


20130318toast6

Toast#setView により、任意のレイアウトに変更することができます。

Toast の文字を大きくする では、標準のレイアウトを使って、文字を大きさだけを変更しました。
今度は、ドロイド君が付いた Toast を作成します。

ソースコードは google code にて公開しています。

参考
カスタムトーストビューの作成 − ソフトウェア技術ドキュメントを勝手に翻訳


Toast の表示位置を変更する


20130314toast5_normal 20130314toast5_center

Toast は、下3分の1くらいの位置に表示されます。
ソフトキーボードがあると、Toast と重なってしまい、見えにくいです。。

Toast#setGravity により、表示する位置を変更することができます。

ソースコードは google code にて公開しています。

参考
トーストの位置決め − ソフトウェア技術ドキュメントを勝手に翻訳


Toast の表示時間を変更する


結論からいうと、まじめに対応するのは断念しました。
代わりに Toast もどきのクラスを作って対応しました。

Toast のソースを読むと。
show() の中で INotificationManager#enqueueToast() を呼んでいます。
INotificationManager の実体は、 NotificationManagerService です。
この中で、Handler#sendMessageDelayed() を使って、表示時間を制御しています。
LENGTH_LONG ならば、3.5秒で、それ以外なら 2秒です。

表示時間を変更するには、NotificationManagerService を改造する必要があります。
NotificationManagerService は、システムに常駐しているサービスなので、いろいろ面倒です。
ということで、まじめに対応するのは断念しました。

代わりに Toast もどきのクラスを作って対応しました。
NotificationManagerService で行っている処理は、Toast のキュー管理と表示時間の制御です。
キュー管理は諦めて、表示時間の制御を行うクラスを作成しました。
Toast の表示と消去は、TN クラスで行っていますが、private になっているため、この部分も作成しました。

ソースコードは code.google にあります。

関連記事
Toast の移植
Toast が固まるのを回避する
Toast の文字を大きくする
・Toast の表示時間を変更する


Toast の文字を大きくする


20130311toast
上は標準の Toast (14sp)、下は今回のカスタマイズ (32sp)。

Toast の文字を大きくするには、
Toast#makeText に相当するクラスを作ることで対応できます。
ソースコードは code.google にあります。

Toast.java のソースを読むと。
文字の大きさは、makeText() の中で読み込まれるレイアウトファイル transient_notification で設定されている。
レイアウトファイルは さらに スタイル TextAppearance.Small を参照している。
文字の大きさは 14sp 固定です。

Toast の文字を大きくするのは、下記のようなコードにする。

使い方

// 32sp で表示する
MyToast.makeText( this, "abc", Toast.LENGTH_LONG, 32f ).show();

MyToast.java

public static Toast makeText( Context context, CharSequence text, int duration, float size ) {
	Toast result = new Toast( context );
	LayoutInflater inflate = (LayoutInflater)
		context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
	View v = inflate.inflate( R.layout.toast, null );
	TextView tv = (TextView) v.findViewById( R.id.message );
	tv.setText( text );       
	tv.setTextSize( size ); 
	result.setView( v );
	result.setDuration( duration );
	return result;
}

toast.xml

<TextView
	android:id="@+id/message"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"
	android:layout_weight="1"
	android:textColor="#ffffffff"			                                        
	android:textSize="14sp" // デフォルトの文字の大きさ
	android:shadowColor="#BB000000"
	android:shadowRadius="2.75" />

関連記事
Toast の移植
Toast が固まるのを回避する
・Toast の文字を大きくする
Toast の表示時間を変更する


Toast が固まるのを回避する


Toast は、キューに積まれています。
Toast を複数回実行すると、順番に表示されます。
ところが、連続する回数が多いと、Toast が消えなくなる (固まる) 現象を起こします。

これを回避するには、新しい Toast を実行する際には、前の Toast をキャンセルする必要があります。
AlarmClockToastMaster.java で実装されています。

Toast#cancel() の処理ですが、Android 1.6 (Donut) では、
表示を消すだけで、キューは残っています。
ということで、気休め程度の効果しかない感じです。

public void cancel() {
	mTN.hide();
	// TODO this still needs to cancel the inflight notification if any
}

Android 4.1 (Jelly Bean) から、キューを消す処理が入りました。
エミュレータで試すと、期待した動きをします。

public void cancel() {
	mTN.hide();
	try {
		getService().cancelToast(mContext.getPackageName(), mTN);
	} catch (RemoteException e) {
            // Empty
	}
}

サンプルコードは google code に置いています。

参考
Android Toastが固まるのを回避する方法 – Taosoftware

関連記事
Toast の移植
・Toast が固まるのを回避する
Toast の文字を大きくする
Toast の表示時間を変更する


Toast の移植


20130310toast

Android の標準UIに Toast がある。
donut(v1.6) の android/widget/Toast.java を移植した。
そのままコピーして、ユーザアプリとしてコンパイルを通るように、若干修正したものです。

移植のポイントを挙げておく。
(1) 追加したシステムファイルを2つです。
android/app/INotificationManager.aidl
android/app/ITransientNotification.aidl
(2) com.android.internal.R は res ディレクトリにコピーした
(3) WindowManagerImpl を使っていたところは、 WindowManager で置き換えた。
(4) ServiceManager を使っていたところは、 esmasui さんの ServiceLocator で置き換えた。

ソースコードは Google code に置いています。

参考
ServiceLocator システムサービスのローカルインターフェイスを取得する

関連記事
・Toast の移植
Toast が固まるのを回避する
Toast の文字を大きくする
Toast の表示時間を変更する