Как изменить пользовательский шрифт элемента меню Android?
У меня есть следующий код Java и XML для Android. Я хочу изменить шрифт пунктов меню моего приложения. Я знаю только, что мы можем изменить шрифт TextView с помощью setTypeface, но не можем найти в любом случае пункт меню.
Код JAVA -:
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_refresh1:
Toast.makeText(this, "Item1 Selected", Toast.LENGTH_SHORT)
.show();
break;
case R.id.action_refresh2:
Toast.makeText(this, "Item2 Selected", Toast.LENGTH_SHORT)
.show();
break;
default:
break;
}
}
Код XML -:
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:id="@+id/action_refresh1"
android:orderInCategory="100"
android:showAsAction="always"
android:title="Item1"/>
<item
android:id="@+id/action_refresh2"
android:orderInCategory="100"
android:showAsAction="always"
android:title="Item2"/>
</menu>
Я хочу изменить шрифт двух элементов меню, но не знаю, как интегрировать settypface для пункта меню.
Ответы
Ответ 1
вам нужно предоставить пользовательский макет для пункта меню.
Во-первых, в вашем меню XML установлен один из следующих
CASE 1, если вы используете библиотеку поддержки:
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_save"
android:title="@string/action_save"
android:icon="@drawable/ic_action_save"
android:orderInCategory="100"
app:showAsAction="always"
app:actionLayout="@layout/layout_menu_save"/>
</menu>
CASE 2, если вы не используете библиотеку поддержки:
<menu
xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/action_save"
android:title="@string/action_save"
android:icon="@drawable/ic_action_save"
android:orderInCategory="100"
android:showAsAction="always"
android:actionLayout="@layout/layout_menu_save"/>
</menu>
Затем в actionLayout (layout_menu_save.xml в моем примере) напишите следующее:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="@drawable/background_transparent_stateful">
<com.example.YourCustomTypefaceTextView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginStart="8dp"
android:layout_marginLeft="8dp"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:gravity="center_vertical"
android:text="@string/action_save"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_marginEnd="8dp"
android:layout_marginRight="8dp"
android:gravity="center_vertical"
android:src="@drawable/ic_action_save"
android:contentDescription="@string/action_save"/>
</LinearLayout>
Фоновое выделение (background_transparent_stateful) полезно для сенсорной обратной связи на вашем пользовательском макете:
<selector xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:state_pressed="true"
android:drawable="#20FFFFFF">
</item>
<item
android:drawable="@android:color/transparent">
</item>
</selector>
Таким образом, у вас будет текст с настраиваемым шрифтом слева в виде метки со значком справа.
Очевидно, вы можете настроить макет по своему усмотрению!
ИЗМЕНИТЬ:
Если вы используете библиотеку поддержки и свою активность. Тема расширяет AppCompatTheme, вы можете получить типичный эффект " пульсации" для более удобной сенсорной обратной связи.
Просто замените пользовательский фон:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:background="?attr/selectableItemBackgroundBorderless">
...
</LinearLayout>
Ответ 2
XML
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item
android:id="@+id/action_edit"
android:title="@string/edit"
android:visible="true"
app:showAsAction="always" />
</menu>
В ДЕЯТЕЛЬНОСТИ ИЛИ В ФРАГМЕНТЕ
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
Typeface face = Typeface.createFromAsset(getActivity().getAssets(),"fonts/OpenSans-Regular.ttf"); // THIS
TypefaceSpan face = new TypefaceSpan("<REPLACE_WITH_FONT_NAME>"); // OR THIS
SpannableStringBuilder title = new SpannableStringBuilder(getContext().getString(R.string.edit));
title.setSpan(face, 0, title.length(), 0);
menu.add(Menu.NONE, R.id.action_edit, 0, title); // THIS
MenuItem menuItem = menu.findItem(R.id.action_edit); // OR THIS
menuItem.setTitle(title);
super.onCreateOptionsMenu(menu, inflater);
}
Ответ 3
Вы также можете использовать SpannableStringBuilder
, когда вы добавляете элемент меню с помощью TypefaceSpan
. Для каждого пункта меню сделайте что-то вроде
TypefaceSpan span = new TypefaceSpan("<REPLACE_WITH_FONT_NAME>");
SpannableStringBuilder title = new SpannableStringBuilder("My Menu Item Title");
title.setSpan(span, 0, title.length(), 0);
menu.add(Menu.NONE, id, index, title);
Ответ 4
Я нашел, что это решение полезно для меня. Надеюсь, это поможет совершенно новым серферам.
ваше меню main.xml
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<item android:id="@+id/item1"
android:title="User"
android:orderInCategory="100"
android:visible="true"
app:showAsAction="always"
app:actionViewClass="android.widget.Button"
/>
</menu>
После того, как вы наполнили пользовательское меню, вы можете сделать ссылку на элемент меню. Когда вы получите ссылку на пункт меню, вы сможете настроить элемент для отображения значка и текста Юникода. Файл образа значка должен быть сохранен в
папка res/drawable.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
//reference to the item of the menu
MenuItem i=menu.findItem(R.id.item1);
Button button_menu =(Button) i.getActionView();
if(itemuser!=null){
// Create Typeface object to use unicode font in assets folder
Typeface font= Typeface.createFromAsset(getApplicationContext().getAssets(),"fonts/arial.ttf");
// Set unicode font to menu item
button_menu .setTypeface(font);
// Set item text and color
button_menu .setText(getResources().getString(R.string._text));
button_menu .setTextColor(Color.WHITE);
// Make item background transparent
button_menu .setBackgroundColor(Color.TRANSPARENT);
// Show icon next to the text
Drawable icon=getApplicationContext().getResources().getDrawable( R.drawable.user);
button_menu .setCompoundDrawablesWithIntrinsicBounds( icon, null, null, null );
}
return true;
}
Ответ 5
Ответ от @brahmyadigopula работает хорошо.
Вот только более полная версия для упрощения:
Меню
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<item
android:id="@+id/update"
android:showAsAction="always"
android:title="@string/menu_update"
tools:ignore="UnusedAttribute"
android:actionViewClass="android.widget.Button"/>
</menu>
В вашей деятельности или фрагменте:
// Inflater the menu based on the layout above
inflater.inflate(menuRes, menu);
// Set font type face
if (setCustomFontType){
final MenuItem menuItem = menu.findItem(R.id.update);
String title = menuItem.getTitle().toString();
Button button_menu = (Button) menuItem.getActionView();
button_menu.setTypeface("<REPLACE_WITH_FONT_NAME>");
button_menu.setText(title);
button_menu.setTextColor(Color.WHITE);
button_menu.setBackgroundColor(_getResources().getColor(R.color.transparent_color));
button_menu.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onOptionsItemSelected(menuItem);
}
});
}
super.onCreateOptionsMenu(menu, inflater);