Júl*_*ger 64 android android-design-library navigationview
使用new NavigationView,我们可以通过XML菜单资源设置抽屉的项目.
有了它,我们可以设置每个项目
<item
android:id="@+id/drawer_my_account"
android:icon="@drawable/ic_my_account"
android:title="@string/drawer_my_account" />
Run Code Online (Sandbox Code Playgroud)
但现在,我想为抽屉中的每个项目设置一个自定义字体,我无法通过XML或Java代码找到方法.有办法吗?
Moi*_*han 162
只需将以下类文件添加到项目中即可.
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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后为您的活动创建以下方法
private void applyFontToMenuItem(MenuItem mi) {
Typeface font = Typeface.createFromAsset(getAssets(), "ds_digi_b.TTF");
SpannableString mNewTitle = new SpannableString(mi.getTitle());
mNewTitle.setSpan(new CustomTypefaceSpan("" , font), 0 , mNewTitle.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
mi.setTitle(mNewTitle);
}
Run Code Online (Sandbox Code Playgroud)
并从活动中调用它.
navView = (NavigationView) findViewById(R.id.navView);
Menu m = navView.getMenu();
for (int i=0;i<m.size();i++) {
MenuItem mi = m.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);
}
}
//the method we have create in activity
applyFontToMenuItem(mi);
}
Run Code Online (Sandbox Code Playgroud)
这是我的输出

Pan*_*tel 75
这个适合我
<android.support.design.widget.NavigationView
android:id="@+id/navigation_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#4A4444"
android:clipToPadding="false"
android:paddingBottom="50dp"
app:itemIconTint="@color/white"
app:menu="@menu/drawer_home"
app1:itemTextAppearance="@style/NavigationDrawerStyle" >
</android.support.design.widget.NavigationView>
Run Code Online (Sandbox Code Playgroud)
水库>值 - >风格
<style name="NavigationDrawerStyle">
<item name="android:textSize">18sp</item>
<item name="android:typeface">monospace</item>
</style>
Run Code Online (Sandbox Code Playgroud)
//设置自定义字体MainApplication.java
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//set Custom Typeface
FontsOverride.setDefaultFont(this, "MONOSPACE", "OpenSans-Semibold.ttf");
}
}
Run Code Online (Sandbox Code Playgroud)
// FontsOverride.java
public final class FontsOverride {
public static void setDefaultFont(Context context,
String staticTypefaceFieldName, String fontAssetName) {
final Typeface regular = Typeface.createFromAsset(context.getAssets(),
fontAssetName);
replaceFont(staticTypefaceFieldName, regular);
}
protected static void replaceFont(String staticTypefaceFieldName,
final Typeface newTypeface) {
try {
final Field staticField = Typeface.class
.getDeclaredField(staticTypefaceFieldName);
staticField.setAccessible(true);
staticField.set(null, newTypeface);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
Run Code Online (Sandbox Code Playgroud)
Moo*_*idi 20
使用app:itemTextAppearance =""属性.希望这可以帮助.
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
android:background="@drawable/nav_bg_gradient"
android:theme="@style/NavigationView"
app:itemIconTint="@color/colorWhite"
app:itemTextColor="@color/colorWhite"
app:itemTextAppearance="@style/NavigationText"
app:menu="@menu/main_drawer">
Run Code Online (Sandbox Code Playgroud)
在styles.xml中写
<style name="NavigationText" parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">@color/colorWhite</item>
<item name="android:textSize">12sp</item>
<item name="android:fontFamily">sans-serif-thin</item>
</style>
Run Code Online (Sandbox Code Playgroud)
adn*_*eal 14
有办法吗?
是.在NavigationView不提供处理这种直接的方式,但它可以很容易地使用来实现View.findViewsWithText.
有两件事可以帮助我们解决这个问题.
MenuItem视图都是一个TextView.所以,这使得Typeface更容易应用你.有关TextView实际使用的更多信息NavigationView,请参阅NavigationMenuItemView.NavigationView MenuItem选择a时提供回调.我们将不得不为每个MenuItem提供一个唯一的id,这个回调将帮助尽可能地生成这些id,这意味着稍后会少一些代码.虽然,这与你是否有一个更相关SubMenu.履行
注意每个MenuItemid都很简单menuItem+Position.当我们找到View每一个时,这将会派上用场MenuItem.
<group android:checkableBehavior="single">
<item
android:id="@+id/menuItem1"
android:icon="@drawable/ic_dashboard"
android:title="MenuItem 1" />
<item
android:id="@+id/menuItem2"
android:icon="@drawable/ic_event"
android:title="MenuItem 2" />
<item
android:id="@+id/menuItem3"
android:icon="@drawable/ic_headset"
android:title="MenuItem 3" />
<item
android:id="@+id/menuItem4"
android:icon="@drawable/ic_forum"
android:title="MenuItem 4" />
</group>
<item android:title="Sub items" >
<menu>
<item
android:id="@+id/menuItem5"
android:icon="@drawable/ic_dashboard"
android:title="Sub item 5" />
<item
android:id="@+id/menuItem6"
android:icon="@drawable/ic_forum"
android:title="Sub item 6" />
</menu>
</item>
Run Code Online (Sandbox Code Playgroud)
/** The total number of menu items in the {@link NavigationView} */
private static final int MENU_ITEMS = 6;
/** Contains the {@link MenuItem} views in the {@link NavigationView} */
private final ArrayList<View> mMenuItems = new ArrayList<>(MENU_ITEMS);
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
final NavigationView navView = ...
// Grab the NavigationView Menu
final Menu navMenu = navView.getMenu();
// Install an OnGlobalLayoutListener and wait for the NavigationMenu to fully initialize
navView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// Remember to remove the installed OnGlobalLayoutListener
navView.getViewTreeObserver().removeOnGlobalLayoutListener(this);
// Loop through and find each MenuItem View
for (int i = 0, length = MENU_ITEMS; i < length; i++) {
final String id = "menuItem" + (i + 1);
final MenuItem item = navMenu.findItem(getResources().getIdentifier(id, "id", getPackageName()));
navView.findViewsWithText(mMenuItems, item.getTitle(), View.FIND_VIEWS_WITH_TEXT);
}
// Loop through each MenuItem View and apply your custom Typeface
for (final View menuItem : mMenuItems) {
((TextView) menuItem).setTypeface(yourTypeface, Typeface.BOLD);
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
您可以看到使用通用MenuItemID 如何使用Resources.getIdentifier和保存几行代码.
SubMenu 警告
要记住的事情.您需要显式循环您的N菜单项而不是使用Menu.size.否则,您的SubMenu商品将无法识别.换句话说,如果你没有SubMenu,另一种方法是:
for (int i = 0, length = navMenu.size(); i < length; i++) {
final MenuItem item = navMenu.getItem(i);
navigationView.findViewsWithText(mMenuItems, item.getTitle(), View.FIND_VIEWS_WITH_TEXT);
}
Run Code Online (Sandbox Code Playgroud)
而且您不必担心为每个ID应用唯一ID MenuItem.
结果

我在示例中使用的字体是:Smoothie Shoppe
我用过app:theme
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="@color/colorMenuBackground"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header_main"
app:menu="@menu/activity_main_drawer"
app:theme="@style/NavigationViewTextAppearance"
/>
Run Code Online (Sandbox Code Playgroud)
Styles.xml:
<style name="NavigationViewTextAppearance">
<item name="android:ellipsize">end</item>
<item name="android:fontFamily">@font/badscript_regular</item>
</style>
Run Code Online (Sandbox Code Playgroud)
设置自定义字体的另一种方法:
1.您可以将字体添加到“字体”文件夹中,然后您可以在任何 TextView(或任何您需要的地方)中使用它们
font.xml 的一个例子:
<?xml version="1.0" encoding="utf-8"?>
<font-family xmlns:android="http://schemas.android.com/apk/res/android">
<font
android:font="@font/nunito_bold"
android:fontStyle="normal"
android:fontWeight="400" />
</font-family>
Run Code Online (Sandbox Code Playgroud)
2.在您的styles.xml文件中,您可以在任何需要的地方使用该字体和颜色自定义您的项目文本样式(来自@Moonis Abidi的回答)
<style name="NavigationText" parent="@android:style/TextAppearance.Medium">
<item name="android:textColor">@android:color/white</item>
<item name="android:textSize">12sp</item>
<item name="android:fontFamily">@font/nunito_semibold</item>
</style>
Run Code Online (Sandbox Code Playgroud)
3.现在,您只需在导航视图中使用app:itemTextAppearance指定此项:
<android.support.design.widget.NavigationView
android:id="@+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="@layout/nav_header"
app:menu="@menu/main_menu"
app:itemTextAppearance="@style/NavigationText"/>
Run Code Online (Sandbox Code Playgroud)
// ------------- 另外,如果您需要使用其他 TextViews 中的这种字体,您可以像这样使用它
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/nunito_bold"/>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
55509 次 |
| 最近记录: |