NavigationView의 항목에 사용자 지정 서체를 설정하는 방법은 무엇입니까?
새로운을 사용하면 NavigationView
XML의 메뉴 리소스를 통해 서랍의 항목을 설정할 수 있습니다.
이를 통해 각 항목을 다음과 같이 설정할 수 있습니다.
<item
android:id="@+id/drawer_my_account"
android:icon="@drawable/ic_my_account"
android:title="@string/drawer_my_account" />
그러나 지금은 서랍의 각 항목에 사용자 정의 서체를 설정하고 싶습니다. XML이나 Java 코드로 그렇게 할 수있는 방법을 찾을 수 없습니다. 그것을 할 방법이 있습니까?
프로젝트에 다음 클래스 파일을 추가하십시오.
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);
}
}
그런 다음 활동에 다음 방법을 만듭니다.
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);
}
활동에서 호출합니다.
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);
}
그리고 여기에 내 출력이 있습니다.
이건 나를 위해 일해
<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>
res-> values-> styles
<style name="NavigationDrawerStyle">
<item name="android:textSize">18sp</item>
<item name="android:typeface">monospace</item>
</style>
// 사용자 정의 서체 MainApplication.java 설정
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
//set Custom Typeface
FontsOverride.setDefaultFont(this, "MONOSPACE", "OpenSans-Semibold.ttf");
}
}
// 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();
}
}
}
사용 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">
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>
그것을 할 방법이 있습니까?
예. 는 NavigationView
이를 직접 처리하는 방법을 제공하지 않지만 View.findViewsWithText
.
이를 처리하는 데 도움이되는 두 가지가 있습니다.
- 각
MenuItem
보기는TextView
. 따라서 적용Typeface
이 훨씬 쉬워집니다. 에서TextView
실제로 사용하는 에 대한 자세한 내용은을NavigationView
참조하십시오NavigationMenuItemView
. NavigationView
MenuItem
가 선택 되면 콜백을 제공합니다 . 우리는 각각MenuItem
고유 한 ID를 제공해야하며이 콜백은 가능한 한 이러한 ID를 생성하는 데 도움이 될 것입니다. 이는 나중에 코드가 조금 줄어든다는 것을 의미합니다. 그러나 이것은SubMenu
.
이행
각 MenuItem
ID는 간단 menuItem+Position
합니다. 이것은 나중에 View
for each를 찾을 때 유용 합니다 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>
/** 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);
}
}
});
}
일반 MenuItem
ID를 사용하면 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);
}
그리고 각각에 고유 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"
/>
Styles.xml :
<style name="NavigationViewTextAppearance">
<item name="android:ellipsize">end</item>
<item name="android:fontFamily">@font/badscript_regular</item>
</style>
사용자 정의 서체가 아니라 탐색 항목의 글꼴을 변경하는 또 다른 방법입니다. 라는 레이아웃을 만듭니다 design_navigation_item.xml
.
<android.support.design.internal.NavigationMenuItemView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="?attr/listPreferredItemHeightSmall"
android:paddingLeft="?attr/listPreferredItemPaddingLeft"
android:paddingRight="?attr/listPreferredItemPaddingRight"
android:drawablePadding="@dimen/navigation_icon_padding"
android:gravity="center_vertical|start"
android:maxLines="1"
android:fontFamily="sans-serif-thin"
android:textSize="22sp"
android:textAppearance="?attr/textAppearanceListItem" />
그런 다음 fontFamily를 원하는 글꼴로 변경합니다.
대답하기 조금 늦었지만 더 깨끗한 방법을 찾았으므로 공유하고 싶습니다.
사용자 정의보기 만들기
NavFontTextView.java
:import android.content.Context; import android.support.design.internal.NavigationMenuItemView; import android.util.AttributeSet; import utils.CustomFontHelper; public class NavFontTextView extends NavigationMenuItemView { Context mContext; public NavFontTextView(Context context) { super(context); mContext = context; setDefaultFont(); } public NavFontTextView(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; setDefaultFont(); CustomFontHelper.setCustomFont(this, context, attrs); } public NavFontTextView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); mContext = context; setDefaultFont(); CustomFontHelper.setCustomFont(this, context, attrs); } public void setDefaultFont() { CustomFontHelper.setCustomFont(this, "fonts/SourceSansPro-Regular.ttf", mContext); } }
다음과 같은 파일을 만듭니다
CustomFontHelper.java
.import android.content.Context; import android.content.res.TypedArray; import android.graphics.Typeface; import android.util.AttributeSet; import android.widget.TextView; /** * Taken from: http://stackoverflow.com/a/16648457/75579 */ public class CustomFontHelper { /** * Sets a font on a textview based on the custom com.my.package:font attribute * If the custom font attribute isn't found in the attributes nothing happens * @param textview * @param context * @param attrs */ public static void setCustomFont(TextView textview, Context context, AttributeSet attrs) { TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.CustomFont); String font = a.getString(R.styleable.CustomFont_font); setCustomFont(textview, font, context); a.recycle(); } /** * Sets a font on a textview * @param textview * @param font * @param context */ public static void setCustomFont(TextView textview, String font, Context context) { if(font == null) { return; } Typeface tf = FontCache.get(font, context); if(tf != null) { textview.setTypeface(tf); } } }
레이아웃 만들기
layout/design_navigation_item.xml
(이름은 정확히 동일해야 함) :<?xml version="1.0" encoding="utf-8"?> <custom_view.NavFontTextView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="?attr/listPreferredItemHeightSmall" android:drawablePadding="10dp" android:gravity="center_vertical|start" android:maxLines="1" android:paddingLeft="?attr/listPreferredItemPaddingLeft" android:paddingRight="?attr/listPreferredItemPaddingRight" app:font="fonts/SourceSansPro-Bold.ttf" />
SourceSansPro-Bold.ttf
다음 경로에 글꼴 파일 을 배치하십시오.app/src/main/assets/fonts/SourceSansPro-Bold.ttf
당신은 갈 수 있습니다! 이렇게하면 주요 활동을 깔끔하게 유지할 수 있습니다.
사용자 정의 글꼴을 설정하는 다른 방법 :
1. "font"폴더에 글꼴을 추가 한 다음 모든 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>
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>
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"/>
// ------------- 또한 다른 TextView에서이 글꼴을 사용해야하는 경우 다음과 같이 사용할 수 있습니다.
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:fontFamily="@font/nunito_bold"/>
@Moinkhan 답변을 사용하는 사람들을 위해 메뉴의 모든 부분에 글꼴을 적용하려면 해당 솔루션을 사용하고 모든 헤더 섹션에는 ID를 사용하십시오. 메뉴가 이렇게 ..
<item android:title="@string/others" android:id="@+id/nav_others">
<menu>
<item
android:id="@+id/contact"
android:title="@string/contact"/>
</menu>
</item>
그리고 이와 같은 솔루션 ..
navMenu = navView.getMenu();
MenuItem item= navView.getMenu().findItem(R.id.nav_others);
applyFontToMenuItem(item);
누군가에게 도움이 될 수도 있습니다.
나는 "불을 뱉는 드래곤"의 솔루션을 정말 좋아했지만 textview
. 다음을 수행하여 수행 할 수 있습니다.
TextView textView = (CheckedTextView) findViewById(android.support.design.R.id.design_menu_item_text);
public class StyledMenuItem extends NavigationMenuItemView {
public StyledMenuItem(Context context) {
super(context);
}
public StyledMenuItem(Context context, AttributeSet attrs) {
super(context, attrs);
if (!isInEditMode()) {
setCustomFont(context, attrs);
setFilterTouchesWhenObscured(true);
}
}
public StyledMenuItem(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
if (!isInEditMode()) {
setCustomFont(context, attrs);
setFilterTouchesWhenObscured(true);
}
}
private void setCustomFont(Context ctx, AttributeSet attrs) {
TypedArray a = ctx.obtainStyledAttributes(attrs, R.styleable.ProjectView);
String customFont = a.getString(R.styleable.ProjectView_projectFont);
setCustomFont(ctx, customFont);
a.recycle();
}
private void setCustomFont(Context ctx, String asset) {
Typeface typeFace = TypeFaceProvider.getTypeFace(ctx, asset);
TextView textView = (CheckedTextView) findViewById(android.support.design.R.id.design_menu_item_text);
if (typeFace != null && textView != null) {
textView.setTypeface(typeFace);
}
}
design_navigation_item.xml :
<?xml version="1.0" encoding="utf-8"?>
style.xml :
<style name="Body1" parent="Base.TextAppearance.AppCompat.Body1">
<item name="projectFont">Quicksand-Regular.otf</item>
</style>
attrs.xml :
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="ProjectView">
<attr name="projectFont" format="string" />
</declare-styleable>
</resources>
나는 이것에 대한 @adneal의 대답을 리팩토링 했습니다. ID 대신 색인에 따라 메뉴 항목 (하위 항목으로 이동하지 않고 최상위 항목 만)을 반복하고 서체를 설정합니다.
교체 rightNavigationView을 당신의 NavigationView과 함께 {TYPEFACE} 원하는 서체로
final Menu navMenu = rightNavigationView.getMenu();
rightNavigationView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
ArrayList<View> menuItems = new ArrayList<>(); // save Views in this array
rightNavigationView.getViewTreeObserver().removeOnGlobalLayoutListener(this); // remove the global layout listener
for (int i = 0; i < navMenu.size(); i++) {// loops over menu items to get the text view from each menu item
final MenuItem item = navMenu.getItem(i);
rightNavigationView.findViewsWithText(menuItems, item.getTitle(), View.FIND_VIEWS_WITH_TEXT);
}
for (final View menuItem : menuItems) {// loops over the saved views and sets the font
((TextView) menuItem).setTypeface({TYPE}, Typeface.BOLD);
}
}
});
이것은 또 다른 접근 방식입니다.
NavigationView이 라는 아이가 NavigationMenuItemView을 . NavigationMenuItemView에는 두 개의 자식이 있습니다. 하나는 AppCompatCheckedTextView 입니다.
다음 과 같이 NavigationView의 onLayout 메서드를 재정의 하고 AppCompatCheckedTextView의 Typefase 를 변경 합니다.
public final class NavigationViewWithCustomFont extends NavigationView{
private final Context context;
private Typeface fontFace;
public NavigationViewWithCustomFont(Context context, AttributeSet attrs){
super(context, attrs);
this.context = context;
this.fontFace = null;
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom){
super.onLayout(changed, left, top, right, bottom);
final ViewGroup navMenuView = (ViewGroup)getChildAt(0);
final int navMenuItemsCount = navMenuView.getChildCount();
ViewGroup itemView;
if(fontFace == null){
fontFace = Typeface.createFromAsset(context.getAssets(), context.getString(R.string.BTrafficBold));
}
for(int i=0; i<navMenuItemsCount; i++){
itemView = (ViewGroup)navMenuView.getChildAt(i);
if(itemView instanceof NavigationMenuItemView ){
CheckedTextView checkedTextView = (CheckedTextView)itemView.getChildAt(0);
checkedTextView.setTypeface(fontFace, Typeface.BOLD);
}
}
}
}
BottomNavigationView bottom_nav = findViewById(R.id.bottom_nav);
Typeface font = Typeface.createFromAsset(getAssets(), "--your customized font file--");
for (int i = 0; i <bottom_nav.getMenu().size(); i++) {
MenuItem menuItem = bottom_nav.getMenu().getItem(i);
SpannableStringBuilder spannableTitle = new SpannableStringBuilder(menuItem.getTitle());
spannableTitle.setSpan(font.getStyle(), 0, spannableTitle.length(), Spannable.SPAN_INCLUSIVE_INCLUSIVE);
menuItem.setTitle(spannableTitle);
}
res / font / 폴더에 글꼴 파일을 추가하여 글꼴을 리소스로 묶습니다.
그때
스타일 리소스를 사용하여 변경할 수 있습니다. styles.xml에서 :
<style name="Widget.BottomNavigationView"
parent="Widget.Design.BottomNavigationView">
<item name="fontFamily">@font/your_font</item>
</style>
그런 다음보기에서 테마로 적용하십시오.
<android.support.design.widget.BottomNavigationView
...
android:theme="@style/Widget.BottomNavigationView"
/>
applyFontToMenuItem(popup.getMenu().getItem(0));
private void applyFontToMenuItem(MenuItem mi) {
Typeface font = Typeface.createFromAsset(getAssets(), "fonts/Redressed.ttf");
SpannableString mNewTitle = new SpannableString(mi.getTitle());
mNewTitle.setSpan(new CustomTypefaceSpan("", font), 0, mNewTitle.length(),pannable.SPAN_INCLUSIVE_INCLUSIVE);
mi.setTitle(mNewTitle);
}
참고 URL : https://stackoverflow.com/questions/30668346/how-to-set-custom-typeface-to-items-in-navigationview
'program story' 카테고리의 다른 글
"train_test_split"메소드의 매개 변수 "stratify"(scikit Learn) (0) | 2020.11.22 |
---|---|
쉼표 연산자를 언제 오버로드해야합니까? (0) | 2020.11.22 |
iOS 용 Google지도 SDK를 사용하려면 '번들 리소스 복사'아래의 대상에 GoogleMaps.bundle이 포함되어야합니다. (0) | 2020.11.22 |
Ajax POST 요청에 대한 Laravel csrf 토큰 불일치 (0) | 2020.11.22 |
Switch Case 문에서 중복 Const 선언 오류 (0) | 2020.11.22 |