digital matter

‘tips’ タグのついている投稿

OptionsMenuの文字色を変更する

Activityで端末のメニューボタンを押したときに出てくるオプションメニューですが、文字の色が変えられなくて困っていました。

Themeのandroid:panelTextAppearanceで変えられるのかと思っていたのだけど、なぜかうまく行かず。

背景画像はテーマで変更できるのですが。

リフレクションを使ってテキストカラーの変更をしてみました。Android API 8で確認しています。

デフォルト

device-2011-10-22-120919

文字色変更

device-2011-10-22-135742

Activityのコード

public class CustomizedMenuActivity extends Activity {
	public static final int MENU_ID_COFFEE = 1;
	public static final int MENU_ID_LOVE = 2;
	public static final int MENU_ID_RECYCLE = 3;

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

	private TextView getMenuItemView(MenuItem item) {
		try {
			Class<?> c = item.getClass(); // itemはMenuItemImplのインスタンス
			Class<?>[] paramTypesGetItemView = { int.class, ViewGroup.class };
			Method method = c.getDeclaredMethod("getItemView", paramTypesGetItemView);

			// getItemViewはprivateメソッドなのでアクセス可能に変更する
			method.setAccessible(true);

			// IconMenuItemViewを取得できる
			TextView view = (TextView) method.invoke(item, new Object[] { 0, null });

			return view;
		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (NoSuchMethodException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InvocationTargetException e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// メニューアイテムの追加
		MenuItem menuItemCoffee = menu.add(Menu.NONE, MENU_ID_COFFEE,
				Menu.NONE, this.getText(R.string.menu_coffee)).setIcon(
				R.drawable.icon_coffee);
		MenuItem menuItemLove = menu.add(Menu.NONE, MENU_ID_LOVE, Menu.NONE,
				this.getText(R.string.menu_love)).setIcon(R.drawable.icon_love);
		MenuItem menuItemRecycle = menu.add(Menu.NONE, MENU_ID_RECYCLE,
				Menu.NONE, this.getText(R.string.menu_recycle)).setIcon(
				R.drawable.icon_recycle);

		try {
			TextView viewCoffee = getMenuItemView(menuItemCoffee);
			TextView viewLove = getMenuItemView(menuItemLove);
			TextView viewRecycle = getMenuItemView(menuItemRecycle);

			// テキストの色を変える
			viewCoffee.setTextColor(0xFFB5985A);
			viewCoffee.setTextSize(14);
			viewCoffee.setTextScaleX(0.8f);

			viewLove.setTextColor(0xFFCF7D5B);
			viewLove.setTextSize(22);
			viewLove.setTypeface(Typeface.DEFAULT_BOLD);

			viewRecycle.setTextColor(0xFF8A6381);
			viewRecycle.setTextSize(16);
			viewRecycle.setTypeface(Typeface.create(Typeface.SERIF,
					Typeface.BOLD_ITALIC));

		} catch (SecurityException e) {
			e.printStackTrace();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		}

		return super.onCreateOptionsMenu(menu);
	}
}

MenuItemの実体はMenuItemImplクラスで、getItemViewメソッドを使ってIconMenuItemViewクラスを取り出しています。

IconMenuItemViewクラスはTextViewを継承しているので、キャストすればテキストカラーやフォントサイズなどの変更ができます。

ちなみに、このあと、メニューのセパレータ(divider)画像の変更とアイコンと文字の配置の変更もやりました。それは次以降のエントリで。

オプションメニューのアイコンと文字を横並びにしたかった : blog.loadlimit – digital matter -

関連する投稿

複数の入力欄にまたがるValidationのエラーを特定の入力欄に表示させたい場合

sfFormでSymfony 1.4のお話。

PostValidatorのエラーメッセージをどこに出せばいいんだ?という状況で使用できます。

class SomethingInputForm extends BaseForm
{
    public function configure()
    {
        // ...
        $this->validatorSchema->setPostValidator(
            new sfValidatorCallback(array('callback' => array($this, 'myCallbackFunc')))
        );
    }

    public function myCallbackFunc($validator, $values) {
        // 何かバリデーション
        if (!($values['input1'] == $values['input2'] == $values['input3'])) {
            $error = new sfValidatorError($validator, 'error message ...');
            throw new sfValidatorErrorSchema($validator, array('input1' => $error));
        }

        return $values;
    }
}

こんな感じで、input1のエラーとして出力できるので、テンプレートのエラー表示が楽になります。

関連する投稿

iPhoneな人への地図URLの送り方

iPhone/iPod touchでもPCでも共通で見られるGoogleマップのURLを作りたくなったのでメモ。

というか、iPhone上のSafariから、Googleで場所を検索すると出てくるリンクですね。iPhoneの場合、このURLを開くと地図アプリが開きます。

http://maps.google.co.jp/?q=東京都新宿区西新宿2丁目8−1

http://maps.google.co.jp/?q=248-0006

PCのGoogleマップで地図のURL開くとめちゃくちゃ長くなってしまうので、こういう指定の仕方覚えておくと便利かも。

何がやりたかったかって言うと、twitterで○○の場所どこ?って聞かれて、とっさに住所だけ答えてしまったけど、iPhoneで使える地図のURLにしたほうが便利だったな、って思って。

関連する投稿