Как установить шрифт для меню "Параметры"?
Когда я создаю меню параметров, элементы по умолчанию по умолчанию имеют собственный шрифт "sans". Когда я смотрю коммерческие приложения, они, похоже, делают то же самое. Можно ли установить размер шрифта, цвет или шрифт для пунктов меню Option?
Спасибо заранее.
Ответы
Ответ 1
Вы можете настроить меню параметров, в том числе:
-
Добавить пользовательский шрифт
-
Изменить размер шрифта
-
Изменить цвет шрифта
-
Установите фон для ресурса, пригодного для рисования (например, изображение, граница, градиент)
Чтобы изменить фон на границу или градиент, вам нужно создать папку ресурса в res
, называемую drawable
, и внутри нее создать XML или градиент XML границы.
Все это можно сделать программно, как показано ниже:
public class CustomMenu extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public boolean onCreateOptionsMenu(android.view.Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.cool_menu, menu);
getLayoutInflater().setFactory(new Factory() {
public View onCreateView(String name, Context context,
AttributeSet attrs) {
if (name.equalsIgnoreCase(
"com.android.internal.view.menu.IconMenuItemView")) {
try {
LayoutInflater li = LayoutInflater.from(context);
final View view = li.createView(name, null, attrs);
new Handler().post(new Runnable() {
public void run() {
// set the background drawable if you want that
//or keep it default -- either an image, border
//gradient, drawable, etc.
view.setBackgroundResource(R.drawable.myimage);
((TextView) view).setTextSize(20);
// set the text color
Typeface face = Typeface.createFromAsset(
getAssets(),"OldeEnglish.ttf");
((TextView) view).setTypeface(face);
((TextView) view).setTextColor(Color.RED);
}
});
return view;
} catch (InflateException e) {
//Handle any inflation exception here
} catch (ClassNotFoundException e) {
//Handle any ClassNotFoundException here
}
}
return null;
}
});
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.AboutUs:
Intent i = new Intent("com.test.demo.ABOUT");
startActivity(i);
break;
case R.id.preferences:
Intent p = new Intent("com.test.demo.PREFS");
startActivity(p);
break;
case R.id.exit:
finish();
break;
}
return false;
}
}
Не забудьте создать папку с именем menu
в папке res
, а внутри папки menu
создайте XML для своего меню (например, cool_menu.xml), например:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:title="about"android:id="@+id/AboutUs" />
<item android:title="Prefs" android:id="@+id/preferences" />
<item android:title="Exit" android:id="@+id/exit" />
</menu>
Тогда вывод будет примерно таким:
![enter image description here]()
Ответ 2
@Android Stack, когда я прочитал ваш ответ, я начал паниковать, думая, что мне придется использовать "factory".
Я немного искал, и я узнал, что вы можете использовать пользовательские представления для элементов меню. Просто назовите setActionView в пункте меню.
@Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.my_menu, menu);
// Get the root inflator.
LayoutInflater baseInflater = (LayoutInflater)getBaseContext()
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
// Inflate your custom view.
View myCustomView = baseInflater.inflate(R.layout.my_custom_view, null);
menu.findItem(R.id.my_custom_menu_icon).setActionView(myCustomView);
// If myCustomView has additional children, you might have to inflate them separately here.
// In my case, I used buttons in my custom view, and registered onClick listeners at this point.
}
Ваша реализация my_custom_view
может быть любым желаемым видом (хотя, возможно, в качестве корневого элемента должна быть LinearLayout
). Например, вы можете использовать макет TextView + ImageView, который предлагает @R4j в своем ответе.
В моем примере использования я просто помещал в него объекты Button
, а затем полагался на обработчик onButtonClick
кнопок для реагирования на события - эффективно перешагивая необходимость обрабатывать их в активности, содержащей меню.
(Большой вопрос, кстати. Спасибо!!)
Ответ 3
Вместо использования XML-ресурса для меню раздуйте его из кода с помощью menu.add и используйте новый SpannableString() для назначения пользовательского шрифта.
Вот пример работы с Android 4.x:
@Override
public void onCreateContextMenu(ContextMenu menu, View v,
ContextMenu.ContextMenuInfo menuInfo) {
...
menu.add(Menu.NONE,1234,1,wrapInSpan(getResources().getString(R.string.item_title)))
.setTitleCondensed(getResources().getString(R.string.item_title));
...
}
private CharSequence wrapInSpan(CharSequence value) {
SpannableStringBuilder sb = new SpannableStringBuilder(value);
sb.setSpan(MY_TYPEFACE, 0, value.length(), 0);
return sb;
}
Требуется setTitleCondensed(...)
для обхода ошибки в API android: при выборе пункта меню регистрируется событие и используется titleCondensed
для записи журнала. Если titleCondensed
не определен, он использует title
и EventLog.writeEvent
сбой при форматировании строки в журнал.
Итак, передаем неформованную CharSequence в обходной ошибке consendedTitle
.
Ответ 4
Протестировано и работает как шарм:)
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu_feedback_filter, menu);
for (int i = 0; i < menu.size(); i++) {
MenuItem mi = menu.getItem(i);
//for aapplying a font to subMenu ...
SubMenu subMenu = mi.getSubMenu();
if (subMenu != null && subMenu.size() > 0) {
for (int j = 0; j < subMenu.size(); j++) {
MenuItem subMenuItem = subMenu.getItem(j);
applyFontToMenuItem(subMenuItem, typeface);
}
}
//the method we have create in activity
applyFontToMenuItem(mi, typeface);
}
return super.onCreateOptionsMenu(menu);
}
private void applyFontToMenuItem(MenuItem mi, Typeface font) {
SpannableString mNewTitle = new SpannableString(mi.getTitle());
mNewTitle.setSpan(new CustomTypefaceSpan("", font), 0, mNewTitle.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
mi.setTitle(mNewTitle);
}
Пользовательский класс span
import android.graphics.Paint;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.text.style.TypefaceSpan;
public class CustomTypefaceSpan extends TypefaceSpan {
private final Typeface newType;
public CustomTypefaceSpan(String family, Typeface type) {
super(family);
newType = type;
}
@Override
public void updateDrawState(TextPaint ds) {
applyCustomTypeFace(ds, newType);
}
@Override
public void updateMeasureState(TextPaint paint) {
applyCustomTypeFace(paint, newType);
}
private static void applyCustomTypeFace(Paint paint, Typeface tf) {
int oldStyle;
Typeface old = paint.getTypeface();
if (old == null) {
oldStyle = 0;
} else {
oldStyle = old.getStyle();
}
int fake = oldStyle & ~tf.getStyle();
if ((fake & Typeface.BOLD) != 0) {
paint.setFakeBoldText(true);
}
if ((fake & Typeface.ITALIC) != 0) {
paint.setTextSkewX(-0.25f);
}
paint.setTypeface(tf);
}
}
Ответ 5
Я думаю, что Android не поддерживает настройку для меню опций. Но вы можете попробовать другой способ: http://www.codeproject.com/Articles/173121/Android-Menus-My-Way
Таким образом, на самом деле элемент меню представляет собой текстовое изображение и изображение, поэтому вы можете легко изменить шрифт, цвет...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:layout_gravity="center"
android:padding="4dip"
android:clickable="true"
android:background="@drawable/custom_menu_selector">
<ImageView
android:id="@+id/custom_menu_item_icon"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:paddingBottom="2dip"
android:paddingTop="2dip"/>
<TextView
android:id="@+id/custom_menu_item_caption"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="#ffffff"
android:textSize="12sp"
android:gravity="center"/>
Ответ 6
Ни один из ответов выше не работал у меня.
Я достиг этого, выполнив следующее решение:
public boolean onPrepareOptionsMenu(Menu menu)
{
MenuItem item = menu.findItem(R.id.menu_name);
item.setTitle(someTextToDisplayOnMenu);
SpannableString spanString = new SpannableString(item.getTitle().toString());
spanString.setSpan(new TextAppearanceSpan(context,android.R.style.TextAppearance_Medium), 0,spanString.length(), 0);
spanString.setSpan(new ForegroundColorSpan(Color.WHITE), 0, spanString.length(), 0); //fix the color to white
item.setTitle(spanString);
return true;
}
Ответ 7
Единственное решение, которое я нашел, это создать настраиваемый диалог, который появляется при нажатии кнопки меню.
Макет будет таким:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Mi cuenta"
android:id="@+id/buttonMyAccount" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Ayuda"
android:id="@+id/buttonHelp" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Contacto"
android:id="@+id/buttonContact" />
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Acerca de"
android:id="@+id/buttonAbout" />
</LinearLayout>
После этого из класса Activity в методе OnOptionsItemSelected я напишу следующий код:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Dialog dialog = new Dialog(this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(R.layout.options_menu);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.show();
Button buttonMyAccount = (Button) dialog.findViewById(R.id.buttonMyAccount);
Typeface font = Typeface.createFromAsset(this.getAssets(), "SamsungIF_Rg.ttf");
buttonMyAccount.setTypeface(font);
buttonMyAccount.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent itMyAccount = new Intent(getBaseContext(), AccountActivity.class);
startActivity(itMyAccount);
}
});
Button buttonHelp = (Button) dialog.findViewById(R.id.buttonHelp);
buttonHelp.setTypeface(font);
buttonHelp.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent itAssistant = new Intent(getBaseContext(), AssistantPagerActivity.class);
startActivity(itAssistant);
}
});
Button buttonContact = (Button) dialog.findViewById(R.id.buttonContact);
buttonContact.setTypeface(font);
buttonContact.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent itContact = new Intent(getBaseContext(), ContactActivity.class);
startActivity(itContact);
}
});
Button buttonAbout = (Button) dialog.findViewById(R.id.buttonAbout);
buttonAbout.setTypeface(font);
buttonAbout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent itAbout = new Intent(getBaseContext(), AboutActivity.class);
startActivity(itAbout);
}
});
Window window = dialog.getWindow();
WindowManager.LayoutParams wlp = window.getAttributes();
wlp.gravity = Gravity.RIGHT | Gravity.TOP;
wlp.y = getSupportActionBar().getHeight();
wlp.width = 300;
wlp.flags &= ~WindowManager.LayoutParams.FLAG_DIM_BEHIND;
window.setAttributes(wlp);
return true;
default:
return super.onOptionsItemSelected(item);
}
}