Ini jelas merupakan masalah yang dihadapi banyak pemrogram dan Google belum memberikan solusi yang didukung dan memuaskan.
Ada banyak niat silang dan kesalahpahaman yang beredar di sekitar postingan tentang topik ini, jadi harap baca seluruh jawaban ini sebelum menanggapi.
Di bawah ini saya menyertakan versi peretasan yang lebih "halus" dan dikomentari dengan baik dari jawaban lain di laman ini, juga menggabungkan gagasan dari pertanyaan yang sangat terkait ini:
Ubah warna latar belakang menu android
Bagaimana cara mengubah warna latar belakang dari menu opsi?
Android: sesuaikan menu aplikasi (mis. Warna latar belakang)
http://www.macadamian.com/blog/post/android_-_theming_the_unthemable/
Tombol Toggle Item Menu Android
Apakah mungkin membuat latar belakang menu opsi Android tidak tembus cahaya?
http://www.codeproject.com/KB/android/AndroidMenusMyWay.aspx
Menyetel latar belakang menu menjadi buram
Saya menguji peretasan ini pada 2.1 (simulator), 2.2 (2 perangkat nyata), dan 2.3 (2 perangkat nyata). Saya belum memiliki tablet 3.X untuk diuji, tetapi akan memposting perubahan yang diperlukan di sini jika / jika saya melakukannya. Mengingat bahwa tablet 3.X menggunakan Bilah Tindakan alih-alih Menu Opsi, seperti yang dijelaskan di sini:
http://developer.android.com/guide/topics/ui/menus.html#options-menu
Peretasan ini hampir pasti tidak akan melakukan apa pun (tidak merugikan dan tidak berguna) pada tablet 3.X.
PERNYATAAN MASALAH (baca ini sebelum membalas pemicu dengan komentar negatif):
Menu Opsi memiliki gaya yang sangat berbeda pada perangkat yang berbeda. Hitam murni dengan teks putih di beberapa, putih bersih dengan teks hitam di beberapa. Saya dan banyak pengembang lain ingin mengontrol warna latar belakang sel menu Opsi serta warna teks menu Opsi .
Pengembang aplikasi tertentu hanya perlu menyetel warna latar belakang sel (bukan warna teks), dan mereka dapat melakukannya dengan cara yang lebih rapi menggunakan gaya android: panelFullBackground yang dijelaskan dalam jawaban lain. Namun, saat ini tidak ada cara untuk mengontrol warna teks menu Opsi dengan gaya, sehingga seseorang hanya dapat menggunakan metode ini untuk mengubah latar belakang ke warna lain yang tidak akan membuat teks "menghilang".
Kami akan senang melakukan ini dengan solusi terdokumentasi, bukti masa depan, tetapi satu tidak tersedia pada Android <= 2.3. Jadi kita harus menggunakan solusi yang berfungsi di versi saat ini dan dirancang untuk meminimalkan kemungkinan rusak / rusak di versi mendatang. Kami menginginkan solusi yang gagal dengan anggun kembali ke perilaku default jika harus gagal.
Ada banyak alasan yang sah mengapa seseorang mungkin perlu mengontrol tampilan menu Opsi (biasanya agar sesuai dengan gaya visual untuk sisa aplikasi) jadi saya tidak akan memikirkannya.
Ada bug Google Android yang diposting tentang ini: harap tambahkan dukungan Anda dengan memberi bintang pada bug ini (catatan Google melarang komentar "saya juga": cukup bintang saja):
http://code.google.com/p/android/issues/detail?id=4441
RINGKASAN SOLUSI JAUH:
Beberapa poster menyarankan peretasan yang melibatkan LayoutInflater.Factory. Peretasan yang disarankan berfungsi untuk Android <= 2.2 dan gagal untuk Android 2.3 karena peretasan tersebut membuat asumsi yang tidak terdokumentasi: bahwa seseorang dapat memanggil LayoutInflater.getView () secara langsung tanpa saat ini berada di dalam panggilan ke LayoutInflater.inflate () pada instance LayoutInflater yang sama. Kode baru di Android 2.3 mematahkan asumsi ini dan menyebabkan NullPointerException.
Peretasan saya yang sedikit halus di bawah ini tidak bergantung pada asumsi ini.
Selain itu, peretasan juga mengandalkan penggunaan nama kelas internal yang tidak terdokumentasi "com.android.internal.view.menu.IconMenuItemView" sebagai string (bukan sebagai tipe Java). Saya tidak melihat cara untuk menghindari ini dan masih mencapai tujuan yang dinyatakan. Namun, Anda dapat melakukan peretasan dengan hati-hati yang akan mundur jika "com.android.internal.view.menu.IconMenuItemView" tidak muncul di sistem saat ini.
Sekali lagi, pahami bahwa ini adalah peretasan dan saya tidak mengklaim ini akan berfungsi di semua platform. Tapi kami para pengembang tidak hidup dalam dunia akademis fantasi di mana segala sesuatu harus sesuai dengan buku: kami memiliki masalah yang harus diselesaikan dan kami harus menyelesaikannya sebaik mungkin. Misalnya, "com.android.internal.view.menu.IconMenuItemView" tampaknya tidak mungkin ada di tablet 3.X karena mereka menggunakan Bilah Tindakan dan bukan Menu Opsi.
Akhirnya, beberapa pengembang telah memecahkan masalah ini dengan sepenuhnya menekan Menu Opsi Android dan menulis kelas menu mereka sendiri (lihat beberapa tautan di atas). Saya belum mencoba ini, tetapi jika Anda punya waktu untuk menulis Tampilan Anda sendiri dan mencari cara untuk mengganti tampilan Android (saya yakin iblis ada dalam detail di sini) maka itu mungkin solusi yang bagus yang tidak memerlukan peretasan tidak berdokumen.
HACK:
Ini kodenya.
Untuk menggunakan kode ini, panggil addOptionsMenuHackerInflaterFactory () ONCE dari aktivitas Anda onCreate () atau aktivitas Anda onCreateOptionsMenu (). Ini menetapkan pabrik default yang akan mempengaruhi pembuatan Menu Opsi selanjutnya. Ini tidak memengaruhi Menu Opsi yang telah dibuat (peretasan sebelumnya menggunakan nama fungsi setMenuBackground (), yang sangat menyesatkan karena fungsi tersebut tidak menyetel properti menu apa pun sebelum dikembalikan).
@SuppressWarnings("rawtypes")
static Class IconMenuItemView_class = null;
@SuppressWarnings("rawtypes")
static Constructor IconMenuItemView_constructor = null;
// standard signature of constructor expected by inflater of all View classes
@SuppressWarnings("rawtypes")
private static final Class[] standard_inflater_constructor_signature =
new Class[] { Context.class, AttributeSet.class };
protected void addOptionsMenuHackerInflaterFactory()
{
final LayoutInflater infl = getLayoutInflater();
infl.setFactory(new Factory()
{
public View onCreateView(final String name,
final Context context,
final AttributeSet attrs)
{
if (!name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView"))
return null; // use normal inflater
View view = null;
// "com.android.internal.view.menu.IconMenuItemView"
// - is the name of an internal Java class
// - that exists in Android <= 3.2 and possibly beyond
// - that may or may not exist in other Android revs
// - is the class whose instance we want to modify to set background etc.
// - is the class we want to instantiate with the standard constructor:
// IconMenuItemView(context, attrs)
// - this is what the LayoutInflater does if we return null
// - unfortunately we cannot just call:
// infl.createView(name, null, attrs);
// here because on Android 3.2 (and possibly later):
// 1. createView() can only be called inside inflate(),
// because inflate() sets the context parameter ultimately
// passed to the IconMenuItemView constructor's first arg,
// storing it in a LayoutInflater instance variable.
// 2. we are inside inflate(),
// 3. BUT from a different instance of LayoutInflater (not infl)
// 4. there is no way to get access to the actual instance being used
// - so we must do what createView() would have done for us
//
if (IconMenuItemView_class == null)
{
try
{
IconMenuItemView_class = getClassLoader().loadClass(name);
}
catch (ClassNotFoundException e)
{
// this OS does not have IconMenuItemView - fail gracefully
return null; // hack failed: use normal inflater
}
}
if (IconMenuItemView_class == null)
return null; // hack failed: use normal inflater
if (IconMenuItemView_constructor == null)
{
try
{
IconMenuItemView_constructor =
IconMenuItemView_class.getConstructor(standard_inflater_constructor_signature);
}
catch (SecurityException e)
{
return null; // hack failed: use normal inflater
}
catch (NoSuchMethodException e)
{
return null; // hack failed: use normal inflater
}
}
if (IconMenuItemView_constructor == null)
return null; // hack failed: use normal inflater
try
{
Object[] args = new Object[] { context, attrs };
view = (View)(IconMenuItemView_constructor.newInstance(args));
}
catch (IllegalArgumentException e)
{
return null; // hack failed: use normal inflater
}
catch (InstantiationException e)
{
return null; // hack failed: use normal inflater
}
catch (IllegalAccessException e)
{
return null; // hack failed: use normal inflater
}
catch (InvocationTargetException e)
{
return null; // hack failed: use normal inflater
}
if (null == view) // in theory handled above, but be safe...
return null; // hack failed: use normal inflater
// apply our own View settings after we get back to runloop
// - android will overwrite almost any setting we make now
final View v = view;
new Handler().post(new Runnable()
{
public void run()
{
v.setBackgroundColor(Color.BLACK);
try
{
// in Android <= 3.2, IconMenuItemView implemented with TextView
// guard against possible future change in implementation
TextView tv = (TextView)v;
tv.setTextColor(Color.WHITE);
}
catch (ClassCastException e)
{
// hack failed: do not set TextView attributes
}
}
});
return view;
}
});
}
Terimakasih telah membaca dan semoga bisa menikmati!