Установка фона меню непрозрачным
Я пытаюсь сделать фон панели меню непрозрачным. После долгих поисков и опробований, я могу почти заставить его работать, установив 'panelFullBackground', однако я получаю нежелательный результат потери верхнего края панели меню вместе с его эффектом тени. Я предполагаю, что, просто устанавливая цвет, я теряю дополнительные стили, связанные с 'panelFullBackground'.
Я настроил свое приложение на собственный стиль. Стиль наследует от Theme.Light. В моем стиле я устанавливаю 'panelFullBackground' на свой цвет:
В stylex.xml:
<item name="android:panelFullBackground">@color/custom_theme_color</item>
В colors.xml
<color name="custom_theme_color">#ff00ffff</color>
Я пытался использовать panelColorForeground|Background, но они не достигают того, что я хочу.
It should be mentioned that I tried to use the setMenuBackground approach suggested elsewhere to no avail.
Заранее спасибо.
4 ответа
Как предложено Луи Семприни здесь:
@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;
}
});
}
Чтобы использовать этот код, вызовите addOptionsMenuHackerInflaterFactory() ONCE из вашей активности onCreate() или из вашей активности onCreateOptionsMenu().
Кодекс работает отлично! Надеюсь это поможет!!
Попробуйте этот простой учебник Android-Menus-My-Way, который я нашел на Codeproject
может оказаться полезным для вас
Вы можете оценить от @color
в @drawable
как ниже, который работал для меня:
<style name="MyTheme" parent="@android:style/Theme.Holo.Light">
<!-- Menu Style -->
<item name="android:panelBackground">@drawable/blue_background</item>
</style>
Вы можете изменить фон меню Android. Это будет выглядеть только по умолчанию. Если вы хотите изменить их внешний вид, подумайте о создании собственного представления для меню.