BottomNavigationView 支持自定义 TextSize android
Custom TextSize of BottomNavigationView support android
我正在尝试从 android 支持库 25.0.0
更改 BottomNavigationView 的文本大小
<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/colorPrimaryDark"
android:foregroundTint="@color/colorAccent"
app:itemIconTint="@android:color/white"
app:itemTextColor="@android:color/white"
app:layout_anchor="@id/lyt_container"
app:layout_anchorGravity="bottom"
app:itemTextAppearance="@style/TextStyleBNV"
app:menu="@menu/nav_menu" />
<style name="TextStyleBNV">
<item name="android:textSize">@dimen/twelve_sp</item>
<item name="android:padding">0dp</item>
<item name="textAllCaps">false</item>
</style>
有什么遗漏吗
不幸的是,第一个版本的 BottomNavigationView 有很多限制。目前,您不能仅使用支持设计 API 来更改标题大小。因此,要在 google 未实现时解决此限制,您可以这样做:
在您的 dimen.xml 中,您可以输入:
<dimen name="design_bottom_navigation_text_size" tools:override="true">30sp</dimen>
<dimen name="design_bottom_navigation_active_text_size" tools:override="true">30sp</dimen>
这样做您将覆盖 BottomNavigationView 的内部 类 使用的默认维度值。所以要小心。
你可以这样改。您只需要知道 google 支持使用的标签的 ID
BottomNavigationView bottomNavigationView = (BottomNavigationView) fragmentActivity.findViewById(R.id.bottom_navigation);
TextView textView = (TextView) bottomNavigationView.findViewById(R.id.menu_item_home).findViewById(R.id.largeLabel);
textView.setTextSize(8);
Large Label 是 google 在其库中使用的标签的 ID
另一种解决方案是使用 Spannable 来调整大小颜色、字体或其他文本属性....
private static class MenuSpannable extends MetricAffectingSpan{
int color = Color.RED;
int size = 40;
public MenuSpannable() {
setSelected(false);
}
@Override
public void updateMeasureState(TextPaint p) {
p.setColor(color);
p.setTextSize(size);
/* p.setText --- whatever --- */
}
@Override
public void updateDrawState(TextPaint tp) {
tp.setColor(color);
tp.setTextSize(size);
/* tp.setText --- whatever --- */
}
private void setSelected(boolean selected){
if(selected){
color = Color.RED;
size = 40;
}else{
color = Color.BLUE;
size = 20;
}
}
}
然后为任何菜单项设置跨度...
@Override
protected void onCreate(Bundle savedInstanceState) {
BottomNavigationView mBottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_menu);
final Menu menu = mBottomNavigationView.getMenu();
final Font font = Font.getFromContext(this);
for(int i = 0; i < menu.size(); i++) {
SpannableString spannableString = new SpannableString(menu.getItem(i).getTitle());
spannableString.setSpan(new MenuSpannable(),0,spannableString.length(),0);
menu.getItem(i).setTitle(spannableString);
}
}
如果你希望文本随着选择状态的变化而变化
mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Menu menu = mBottomNavigationView.getMenu();
for(int i = 0; i < menu.size(); i++) {
MenuSpannable menuSpannable = new MenuSpannable();
menuSpannable.setSelected(item.getItemId() == menu.getItem(i).getItemId());
SpannableString sString = new SpannableString(menu.getItem(i).getTitle());
sString.setSpan(menuSpannable,0,sString.length(),0);
menu.getItem(i).setTitle(sString);
}
return false;
}
});
为此,我决定重写导航项布局:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/design_bottom_navigation_margin"
android:layout_marginBottom="@dimen/design_bottom_navigation_margin"
android:duplicateParentState="true" />
<android.support.design.internal.BaselineLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:clipToPadding="false"
android:paddingBottom="10dp"
android:duplicateParentState="true">
<TextView
android:id="@+id/smallLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/design_bottom_navigation_text_size"
android:singleLine="true"
android:duplicateParentState="true" />
<TextView
android:id="@+id/largeLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
android:textSize="@dimen/design_bottom_navigation_active_text_size"
android:singleLine="true"
android:duplicateParentState="true" />
</android.support.design.internal.BaselineLayout>
</merge>
只需确保将其命名为 design_bottom_navigation_item
在 UpdateBarTextColor 中添加 TabTextStyle 代码(此空白存在于 BottomBarPageRenderer 中)
void UpdateBarTextColor()
{
if (_disposed || _bottomBar == null)
{
return;
}
//This is linked to styles.xml to set size of text
_bottomBar.SetTextAppearance(Resource.Style.TabTextStyle);
//Set color of text and icon in BottomNavBar
_bottomBar.SetActiveTabColor(Element.BarTextColor.ToAndroid(Color.FromHex("#0094F0")));
// The problem SetActiveTabColor does only work in fiexed mode // haven't found yet how to set text color for tab items on_bottomBar, doesn't seem to have a direct way
}
然后在 styles.xml 中添加:
<style name="TabTextStyle" parent="@android:style/TextAppearance.Medium">
<item name="android:textSize">8dp</item>
</style>
不幸的是,覆盖 dimen 在 com.android.support:design:28.0.0
对我不起作用
最后,我能够通过对 menu.xml 中使用的每个标题字符串资源使用 <font size="8"></font>
标签来更改文本大小。
例如,我在此处声明了一个菜单 menu_bottom_navigation.xml
,其中包含如下项目:
<item
...
android:title="@string/main_navi_item_home"
.../>
在string.xml
中,将目标资源设置为:
<string name="main_navi_item_home"><font size="8">Home</font></string>
您可以通过为组件属性 itemTextAppearanceActive
和 itemTextAppearanceInactive
定义自己的样式来更改 BottomNavigationView
文本外观。默认情况下,他们在文档 Bottom Navigation.
中有 textAppearanceCaption
检查部分 主题属性映射
<android.support.design.widget.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:itemTextAppearanceActive="@style/BottomNavigationView.Active"
app:itemTextAppearanceInactive="@style/BottomNavigationView"
app:menu="@menu/bottom_navigation_main" />
styles.xml
<style name="BottomNavigationView" parent="@style/TextAppearance.AppCompat.Caption">
<item name="android:textSize">10sp</item>
</style>
<style name="BottomNavigationView.Active" parent="@style/TextAppearance.AppCompat.Caption">
<item name="android:textSize">11sp</item>
</style>
接下来,更改选定的文本颜色和图标:
只需在可绘制对象上创建 bottom_nav_icon_color_selector & bottom_nav_text_color_selector 即可编辑默认值。
更改图标颜色 - bottom_nav_icon_color_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/colorPrimary" android:state_checked="true" /> <!-- colorIcon Active -->
<item android:color="@color/colorPrimary" android:state_enabled="true" android:state_pressed="true" /> <!-- colorIcon Active -->
<item android:color="@color/colorIconInActive" /> <!-- colorIcon InActive -->
</selector>
- 用于更改文本颜色 - bottom_nav_text_color_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/colorPrimary" android:state_checked="true" /> <!-- colorText Active -->
<item android:color="@color/colorPrimary" android:state_enabled="true" android:state_pressed="true" /> <!-- colorText Active -->
<item android:color="@color/colorTextInActive" /> <!-- colorText InActive -->
</selector>
- 注意: @color/colorIconInActive是一种颜色disable/inactive,你可以在你的res-values-colors
- 完成,试试看,你的导航底部。颜色图标和文本将更改。
我使用下面的代码片段通过 Material 设计更改了 NavigationView 样式。
<style name="MyBottomNavigationView" parent="Widget.MaterialComponents.BottomNavigationView">
<item name="itemIconTint">@color/bottom_navigation_item_selector</item>
<item name="itemTextColor">@color/bottom_navigation_item_selector</item>
<item name="itemTextAppearanceActive">@style/MyBottomNavigationView.TextAppearance</item>
<item name="itemTextAppearanceInactive">@style/MyBottomNavigationView.TextAppearance</item>
</style>
<style name="MyBottomNavigationView.TextAppearance" parent="TextAppearance.MaterialComponents.Caption">
<item name="android:textSize">11sp</item>
<item name="fontFamily">@font/exo2_medium</item>
</style>
然后将样式设置为 BottomNavigationView 元素
<com.google.android.material.bottomnavigation.BottomNavigationView
...
style="@style/MyBottomNavigationView" />
我正在尝试从 android 支持库 25.0.0
更改 BottomNavigationView 的文本大小<android.support.design.widget.BottomNavigationView
android:id="@+id/bottom_navigation_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/colorPrimaryDark"
android:foregroundTint="@color/colorAccent"
app:itemIconTint="@android:color/white"
app:itemTextColor="@android:color/white"
app:layout_anchor="@id/lyt_container"
app:layout_anchorGravity="bottom"
app:itemTextAppearance="@style/TextStyleBNV"
app:menu="@menu/nav_menu" />
<style name="TextStyleBNV">
<item name="android:textSize">@dimen/twelve_sp</item>
<item name="android:padding">0dp</item>
<item name="textAllCaps">false</item>
</style>
有什么遗漏吗
不幸的是,第一个版本的 BottomNavigationView 有很多限制。目前,您不能仅使用支持设计 API 来更改标题大小。因此,要在 google 未实现时解决此限制,您可以这样做:
在您的 dimen.xml 中,您可以输入:
<dimen name="design_bottom_navigation_text_size" tools:override="true">30sp</dimen>
<dimen name="design_bottom_navigation_active_text_size" tools:override="true">30sp</dimen>
这样做您将覆盖 BottomNavigationView 的内部 类 使用的默认维度值。所以要小心。
你可以这样改。您只需要知道 google 支持使用的标签的 ID
BottomNavigationView bottomNavigationView = (BottomNavigationView) fragmentActivity.findViewById(R.id.bottom_navigation);
TextView textView = (TextView) bottomNavigationView.findViewById(R.id.menu_item_home).findViewById(R.id.largeLabel);
textView.setTextSize(8);
Large Label 是 google 在其库中使用的标签的 ID
另一种解决方案是使用 Spannable 来调整大小颜色、字体或其他文本属性....
private static class MenuSpannable extends MetricAffectingSpan{
int color = Color.RED;
int size = 40;
public MenuSpannable() {
setSelected(false);
}
@Override
public void updateMeasureState(TextPaint p) {
p.setColor(color);
p.setTextSize(size);
/* p.setText --- whatever --- */
}
@Override
public void updateDrawState(TextPaint tp) {
tp.setColor(color);
tp.setTextSize(size);
/* tp.setText --- whatever --- */
}
private void setSelected(boolean selected){
if(selected){
color = Color.RED;
size = 40;
}else{
color = Color.BLUE;
size = 20;
}
}
}
然后为任何菜单项设置跨度...
@Override
protected void onCreate(Bundle savedInstanceState) {
BottomNavigationView mBottomNavigationView = (BottomNavigationView)findViewById(R.id.bottom_menu);
final Menu menu = mBottomNavigationView.getMenu();
final Font font = Font.getFromContext(this);
for(int i = 0; i < menu.size(); i++) {
SpannableString spannableString = new SpannableString(menu.getItem(i).getTitle());
spannableString.setSpan(new MenuSpannable(),0,spannableString.length(),0);
menu.getItem(i).setTitle(spannableString);
}
}
如果你希望文本随着选择状态的变化而变化
mBottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
Menu menu = mBottomNavigationView.getMenu();
for(int i = 0; i < menu.size(); i++) {
MenuSpannable menuSpannable = new MenuSpannable();
menuSpannable.setSelected(item.getItemId() == menu.getItem(i).getItemId());
SpannableString sString = new SpannableString(menu.getItem(i).getTitle());
sString.setSpan(menuSpannable,0,sString.length(),0);
menu.getItem(i).setTitle(sString);
}
return false;
}
});
为此,我决定重写导航项布局:
<?xml version="1.0" encoding="utf-8"?>
<merge xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:id="@+id/icon"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="@dimen/design_bottom_navigation_margin"
android:layout_marginBottom="@dimen/design_bottom_navigation_margin"
android:duplicateParentState="true" />
<android.support.design.internal.BaselineLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|center_horizontal"
android:clipToPadding="false"
android:paddingBottom="10dp"
android:duplicateParentState="true">
<TextView
android:id="@+id/smallLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="@dimen/design_bottom_navigation_text_size"
android:singleLine="true"
android:duplicateParentState="true" />
<TextView
android:id="@+id/largeLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="invisible"
android:textSize="@dimen/design_bottom_navigation_active_text_size"
android:singleLine="true"
android:duplicateParentState="true" />
</android.support.design.internal.BaselineLayout>
</merge>
只需确保将其命名为 design_bottom_navigation_item
在 UpdateBarTextColor 中添加 TabTextStyle 代码(此空白存在于 BottomBarPageRenderer 中)
void UpdateBarTextColor()
{
if (_disposed || _bottomBar == null)
{
return;
}
//This is linked to styles.xml to set size of text
_bottomBar.SetTextAppearance(Resource.Style.TabTextStyle);
//Set color of text and icon in BottomNavBar
_bottomBar.SetActiveTabColor(Element.BarTextColor.ToAndroid(Color.FromHex("#0094F0")));
// The problem SetActiveTabColor does only work in fiexed mode // haven't found yet how to set text color for tab items on_bottomBar, doesn't seem to have a direct way
}
然后在 styles.xml 中添加:
<style name="TabTextStyle" parent="@android:style/TextAppearance.Medium">
<item name="android:textSize">8dp</item>
</style>
不幸的是,覆盖 dimen 在 com.android.support:design:28.0.0
最后,我能够通过对 menu.xml 中使用的每个标题字符串资源使用 <font size="8"></font>
标签来更改文本大小。
例如,我在此处声明了一个菜单 menu_bottom_navigation.xml
,其中包含如下项目:
<item
...
android:title="@string/main_navi_item_home"
.../>
在string.xml
中,将目标资源设置为:
<string name="main_navi_item_home"><font size="8">Home</font></string>
您可以通过为组件属性 itemTextAppearanceActive
和 itemTextAppearanceInactive
定义自己的样式来更改 BottomNavigationView
文本外观。默认情况下,他们在文档 Bottom Navigation.
textAppearanceCaption
检查部分 主题属性映射
<android.support.design.widget.BottomNavigationView
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:itemTextAppearanceActive="@style/BottomNavigationView.Active"
app:itemTextAppearanceInactive="@style/BottomNavigationView"
app:menu="@menu/bottom_navigation_main" />
styles.xml
<style name="BottomNavigationView" parent="@style/TextAppearance.AppCompat.Caption">
<item name="android:textSize">10sp</item>
</style>
<style name="BottomNavigationView.Active" parent="@style/TextAppearance.AppCompat.Caption">
<item name="android:textSize">11sp</item>
</style>
接下来,更改选定的文本颜色和图标:
只需在可绘制对象上创建 bottom_nav_icon_color_selector & bottom_nav_text_color_selector 即可编辑默认值。更改图标颜色 - bottom_nav_icon_color_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/colorPrimary" android:state_checked="true" /> <!-- colorIcon Active -->
<item android:color="@color/colorPrimary" android:state_enabled="true" android:state_pressed="true" /> <!-- colorIcon Active -->
<item android:color="@color/colorIconInActive" /> <!-- colorIcon InActive -->
</selector>
- 用于更改文本颜色 - bottom_nav_text_color_selector.xml
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/colorPrimary" android:state_checked="true" /> <!-- colorText Active -->
<item android:color="@color/colorPrimary" android:state_enabled="true" android:state_pressed="true" /> <!-- colorText Active -->
<item android:color="@color/colorTextInActive" /> <!-- colorText InActive -->
</selector>
- 注意: @color/colorIconInActive是一种颜色disable/inactive,你可以在你的res-values-colors
- 完成,试试看,你的导航底部。颜色图标和文本将更改。
我使用下面的代码片段通过 Material 设计更改了 NavigationView 样式。
<style name="MyBottomNavigationView" parent="Widget.MaterialComponents.BottomNavigationView">
<item name="itemIconTint">@color/bottom_navigation_item_selector</item>
<item name="itemTextColor">@color/bottom_navigation_item_selector</item>
<item name="itemTextAppearanceActive">@style/MyBottomNavigationView.TextAppearance</item>
<item name="itemTextAppearanceInactive">@style/MyBottomNavigationView.TextAppearance</item>
</style>
<style name="MyBottomNavigationView.TextAppearance" parent="TextAppearance.MaterialComponents.Caption">
<item name="android:textSize">11sp</item>
<item name="fontFamily">@font/exo2_medium</item>
</style>
然后将样式设置为 BottomNavigationView 元素
<com.google.android.material.bottomnavigation.BottomNavigationView
...
style="@style/MyBottomNavigationView" />