如何更改 Android 2.3 的选项菜单背景?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10394016/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I change the Options menu background for Android 2.3?
提问by SpicyWeenie
I have the same standard options menu, but I want to change the background of the items from white to black. I've seen many postings about how to do it, but those don't work for 2.3.
我有相同的标准选项菜单,但我想将项目的背景从白色更改为黑色。我看过很多关于如何做的帖子,但那些不适用于 2.3。
Does anyone know of a working menu inflater with a custom-colored background compatible with version 2.3?
有谁知道具有与 2.3 版兼容的自定义颜色背景的工作菜单充气器?
**ATTENTION**NO IMAGE PLACEMENT!!! NO CODE FROM OTHER POSTINGS, BECAUSE IVE TRIED THEM ALL HERE!!!
**注意* *无图片放置!!!没有来自其他帖子的代码,因为我在这里都试过了!!!
采纳答案by Kumar Bibek
In an ideal scenario, you shouldn't be doing that. Various devices would have different colors, as they decide. If you really really have to customize the menu item's backgrounds, then, I would suggest don't use it. Instead, create some kind of context menu, which you can fully customize as per your needs.
在理想情况下,您不应该这样做。根据他们的决定,不同的设备会有不同的颜色。如果您真的必须自定义菜单项的背景,那么我建议不要使用它。相反,创建某种上下文菜单,您可以根据需要对其进行完全自定义。
I know its probably not a solution you are asking for, but whatever workarounds you will be be doing for this, it might work for a few device, and would probably be a disaster for others.
我知道这可能不是您要求的解决方案,但是无论您为此采取什么解决方法,它都可能适用于一些设备,而对其他人来说可能是一场灾难。
回答by dira
See if following solution solves your problem....
看看以下解决方案是否能解决您的问题....
AndroidMenifest.xml
AndroidMenifest.xml
<application android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/CustomTheme">
menu/options.xml
菜单/选项.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/option_1" android:title="Android"/>
<item android:id="@+id/option_2" android:title="iPhone"/>
<item android:id="@+id/option_3" android:title="iPad"/>
</menu>
styles.xml
样式文件
<resources>
<style name="CustomTheme" parent="android:Theme">
<!-- Panel attributes -->
<!-- <item name="android:panelBackground">@drawable/menu_bg</item> -->
<item name="android:panelFullBackground">@drawable/menu_full_bg</item>
<!-- <item name="android:panelColorBackground">#FF0000</item> -->
</style>
<!-- <drawable name="menu_bg">#DDDAAA</drawable> -->
<drawable name="menu_full_bg">#000FFF</drawable>
</resources>
StackoverflowActivity.java
StackoverflowActivity.java
public class StackoverflowActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options, menu);
return true;
}
}
回答by Shankar Agarwal
The below code is working fine 2.3.6(test on device and emulator). It is almost copied & combined from different sites from google search
下面的代码工作正常 2.3.6(在设备和模拟器上测试)。它几乎是从谷歌搜索的不同站点复制和组合的
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
setMenuBackground();
return super.onCreateOptionsMenu(menu);
}
protected void setMenuBackground() {
getLayoutInflater().setFactory(new Factory() {
@Override
public View onCreateView(final String name, final Context context,
final AttributeSet attrs) {
if (name.equalsIgnoreCase("com.android.internal.view.menu.IconMenuItemView")) {
try { // Ask our inflater to create the view
final LayoutInflater f = getLayoutInflater();
final View[] view = new View[1];
try {
view[0] = f.createView(name, null, attrs);
} catch (InflateException e) {
hackAndroid23(name, attrs, f, view);
}
// Kind of apply our own background
new Handler().post(new Runnable() {
public void run() {
view[0].setBackgroundColor(Color.BLUE);
}
});
return view[0];
} catch (InflateException e) {
} catch (ClassNotFoundException e) {
}
}
return null;
}
});
}
static void hackAndroid23(final String name,
final android.util.AttributeSet attrs, final LayoutInflater f,
final View[] view) {
try {
f.inflate(new XmlPullParser() {
@Override
public int next() throws XmlPullParserException, IOException {
try {
view[0] = (TextView) f.createView(name, null, attrs);
} catch (InflateException e) {
} catch (ClassNotFoundException e) {
}
throw new XmlPullParserException("exit");
}
@Override
public void defineEntityReplacementText(String entityName,
String replacementText)
throws XmlPullParserException {
// TODO Auto-generated method stub
}
@Override
public int getAttributeCount() {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getAttributeName(int index) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getAttributeNamespace(int index) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getAttributePrefix(int index) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getAttributeType(int index) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getAttributeValue(int index) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getAttributeValue(String namespace,
String name) {
// TODO Auto-generated method stub
return null;
}
@Override
public int getColumnNumber() {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getDepth() {
// TODO Auto-generated method stub
return 0;
}
@Override
public int getEventType() throws XmlPullParserException {
// TODO Auto-generated method stub
return 0;
}
@Override
public boolean getFeature(String name) {
// TODO Auto-generated method stub
return false;
}
@Override
public String getInputEncoding() {
// TODO Auto-generated method stub
return null;
}
@Override
public int getLineNumber() {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getName() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getNamespace() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getNamespace(String prefix) {
// TODO Auto-generated method stub
return null;
}
@Override
public int getNamespaceCount(int depth)
throws XmlPullParserException {
// TODO Auto-generated method stub
return 0;
}
@Override
public String getNamespacePrefix(int pos)
throws XmlPullParserException {
// TODO Auto-generated method stub
return null;
}
@Override
public String getNamespaceUri(int pos)
throws XmlPullParserException {
// TODO Auto-generated method stub
return null;
}
@Override
public String getPositionDescription() {
// TODO Auto-generated method stub
return null;
}
@Override
public String getPrefix() {
// TODO Auto-generated method stub
return null;
}
@Override
public Object getProperty(String name) {
// TODO Auto-generated method stub
return null;
}
@Override
public String getText() {
// TODO Auto-generated method stub
return null;
}
@Override
public char[] getTextCharacters(
int[] holderForStartAndLength) {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isAttributeDefault(int index) {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isEmptyElementTag()
throws XmlPullParserException {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isWhitespace() throws XmlPullParserException {
// TODO Auto-generated method stub
return false;
}
@Override
public int nextTag() throws XmlPullParserException,
IOException {
// TODO Auto-generated method stub
return 0;
}
@Override
public String nextText() throws XmlPullParserException,
IOException {
// TODO Auto-generated method stub
return null;
}
@Override
public int nextToken() throws XmlPullParserException,
IOException {
// TODO Auto-generated method stub
return 0;
}
@Override
public void require(int type, String namespace, String name)
throws XmlPullParserException, IOException {
// TODO Auto-generated method stub
}
@Override
public void setFeature(String name, boolean state)
throws XmlPullParserException {
// TODO Auto-generated method stub
}
@Override
public void setInput(Reader in)
throws XmlPullParserException {
// TODO Auto-generated method stub
}
@Override
public void setInput(InputStream inputStream,
String inputEncoding) throws XmlPullParserException {
// TODO Auto-generated method stub
}
@Override
public void setProperty(String name, Object value)
throws XmlPullParserException {
// TODO Auto-generated method stub
}
}, null, false);
} catch (InflateException e1) {
// "exit" ignored
}
}
回答by Mehul Joisar
i was searching for the same stuff but when i installed my application in my Samsung galaxy Ywhich is having version 2.3.6. i got black background for optionmenu automatically.although the emulator displays me white background for same menu.i don't know how it is working like that,but i got what i want.so i left it unaltered.
Here is the code:
我正在寻找相同的东西,但是当我在我的三星 Galaxy Y 中安装了我的应用程序时,它的版本是 2.3.6。我自动获得了 optionmenu 的黑色背景。虽然模拟器为我显示了同一个菜单的白色背景。我不知道它是如何工作的,但我得到了我想要的。所以我没有改变它。
这是代码:
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater1 = getMenuInflater();
inflater1.inflate(R.menu.scfmenu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
Intent i = new Intent(getApplicationContext(), prefsActivity.class);
startActivity(i);
break;
case R.id.logout:
Intent j = new Intent(getApplicationContext(), LoginActivity.class);
startActivity(j);
break;
}
return super.onOptionsItemSelected(item);
}
回答by R4j
I found this funny postfrom codeproject. You can custom everything you want: bk color, icon. And you can change the menu style with this:
我从 codeproject 中发现了这篇有趣的帖子。您可以自定义您想要的一切:bk 颜色、图标。您可以通过以下方式更改菜单样式:
mMenu.setItemsPerLineInLandscapeOrientation(8);
mMenu.setItemsPerLineInPortraitOrientation(4);
Note: it is a trick to add view look like option menu. Hope this help!
注意:添加视图看起来像选项菜单是一个技巧。希望这有帮助!
回答by Khan
i have used the code as shown below on 2.3.1 version and it works and just call in onCreat method addOptionsMenuHackerInflaterFactory();
我在 2.3.1 版本上使用了如下所示的代码,它可以工作,只需调用 onCreat 方法 addOptionsMenuHackerInflaterFactory();
private static final int COLOR_MENU_ID = Menu.FIRST;
private static final int EMBOSS_MENU_ID = Menu.FIRST + 1;
private static final int BLUR_MENU_ID = Menu.FIRST + 2;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
menu.add(0, COLOR_MENU_ID, 0, "Color").setShortcut('3', 'c');
menu.add(0, EMBOSS_MENU_ID, 0, "Emboss").setShortcut('4', 's');
menu.add(0, BLUR_MENU_ID, 0, "Blur").setShortcut('5', 'z');
return true;
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
@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.BLUE);
try
{
// in Android <= 3.2, IconMenuItemView implemented with TextView
// guard against possible future change in implementation
TextView tv = (TextView)v;
tv.setTextColor(Color.RED);
}
catch (ClassCastException e)
{
// hack failed: do not set TextView attributes
}
}
});
return view;
}
});
}
the output for backround blue and textcolor red as shown below
背景蓝色和文本颜色红色的输出如下所示