などに書いてありますが、まっとうな方法では、アイコンとタイトルしか
変更できません。
*Menuとはメニューキーを押したときに下から”にゅっ”と出てくる
やつです。

↑これの「使い方」とか「ネイル・ド・ロンジョについて」とかのパネルの部分
システムとの一貫性を保つためにそうなっているんだろうとは
思うのですが、アイコンにすごくカラフルなのとか使ったら
一貫性もなにもないだろぅ。とか思ったりもします。
例えば、ic_menu_**.png はアイコンが灰色ですが、このアイコンの
色を変えた画像を用意して、アイコンに指定すると

となって、メニューパネルの背景色がアプリ全体の色バランスと
合ってない感じになってしまいます。
そこで、メニューパネル部分の背景を変えてみました。

以下やりかたです。
*注! この方法は Reflection で内部クラスを使っているので、SDKのアップデートなどで使えなくなる可能性があります。
- import java.lang.reflect.Constructor;
- import java.lang.reflect.InvocationTargetException;
- import android.app.Activity;
- import android.content.Context;
- import android.content.Intent;
- import android.graphics.Color;
- import android.os.Bundle;
- import android.util.AttributeSet;
- import android.view.LayoutInflater;
- import android.view.Menu;
- import android.view.MenuInflater;
- import android.view.MenuItem;
- import android.view.View;
- import android.view.ViewGroup;
- import android.view.LayoutInflater.Factory;
- public class MenuTest extends Activity {
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- // ここで設定
- ensureInflaterFactory();
- setContentView(R.layout.main);
- }
- void ensureInflaterFactory() {
- LayoutInflater service = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
- final Factory orgFactory = service.getFactory();
- if (orgFactory == null) {
- // View をインスタンス化するための Factory オブジェクトを LayoutInflater に設定する。
- // Factory の onCreateView で View のインスタンスを return すればそれが使われる。
- // null を return すれば LayoutInflater 自身がViewをインスタンス化する。
- final Factory factory = new Factory() {
- public View onCreateView(String name, Context context, AttributeSet attrs) {
- // メニューパネル部分の内部クラスだけ変更
- if(name.equals("com.android.internal.view.menu.IconMenuView")) {
- try {
- ClassLoader cl = getClassLoader();
- Class<!----> clazz;
- clazz = cl.loadClass("com.android.internal.view.menu.IconMenuView");
- Constructor<!----> constructor = clazz.getConstructor(Context.class, AttributeSet.class);
- Object view = constructor.newInstance(context, attrs);
- ViewGroup vg = (ViewGroup) view;
- // ここで色指定
- // vg.setBackgroundColor(R.color.hoge); だとうまくいかなかった
- //vg.setBackgroundColor(Color.CYAN); これはうまくいく
- vg.setBackgroundColor(Color.parseColor("#66ffccff"));
- //vg.setBackgroundResource(R.drawable.hoge); で画像を背景にすることも可能
- return vg;
- }
- catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (NoSuchMethodException e) {
- e.printStackTrace();
- } catch (IllegalArgumentException e) {
- e.printStackTrace();
- } catch (InstantiationException e) {
- e.printStackTrace();
- } catch (IllegalAccessException e) {
- e.printStackTrace();
- } catch (InvocationTargetException e) {
- e.printStackTrace();
- }
- }
- return null;
- }
- };
- service.setFactory(factory);
- }
- }
Reflection を使っているので、通常の方法よりも
呼び出すときにオーバーヘッドが大きくなります。
#メニューボタンが押された一番最初しか呼ばれないし、
#実際そこまで気になるわけではないけど
メニューの中の各アイテムは com.android.internal.view.menu.IconMenuItemView
というクラスで TextView を extends してるので、同じようにして
文字色を変えられないかな、と思ったのですが変わりませんでした。残念。
あ、あと背景に指定する色を透過にしても、透過にはならないで白のパネルになりました。
白のパネルの上に載せる色を指定する、という感じなんですね。
0 件のコメント:
コメントを投稿