热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

AndroidStudio使用BottomNavigationView实现底部tabs(一)

一、在androidStudio中实现tabs比较简单,新建项目就可以选择tabs模板进行创建,默认实现tabs功能:直接运行项目就可以看到效果:可以说非常简单,但是我们在实际开发

一、在androidStudio中实现tabs比较简单,新建项目就可以选择tabs模板进行创建,默认实现tabs功能:

直接运行项目就可以看到效果:

可以说非常简单,但是我们在实际开发中默认的效果往往无法满足我们的需求,那么就需要根据自己的需求进行完善优化。

比如我们需要有五个tab,比如需要tab不仅可以点击,还可以滑动切换等等。

二、首先扩充tab至5个,只需要修改res/menu/navigation.xml 这个文件,新增两个配置即可:



android:id="@+id/navigation_home"
android:icon="@drawable/ic_home_black_24dp"
android:title="@string/title_home" />
android:id="@+id/navigation_dashboard"
android:icon="@drawable/ic_dashboard_black_24dp"
android:title="@string/title_dashboard" />
android:id="@+id/navigation_notifications"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_notifications" />
android:id="@+id/navigation_tab4"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_tab4" />
android:id="@+id/navigation_tab5"
android:icon="@drawable/ic_notifications_black_24dp"
android:title="@string/title_tab5" />

同时需要在Strings.xml里添加tabtitle配置:


TabsDem
Home
Dashboard
Notifications
tab4
tab5

还需要修改MainActivity里的方法:

private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
mTextMessage.setText(R.string.title_home);
return true;
case R.id.navigation_dashboard:
mTextMessage.setText(R.string.title_dashboard);
return true;
case R.id.navigation_notifications:
mTextMessage.setText(R.string.title_notifications);
return true;
case R.id.navigation_tab4:
mTextMessage.setText(R.string.title_tab4);
return true;
case R.id.navigation_tab5:
mTextMessage.setText(R.string.title_tab5);
return true;
}
return false;
}
};

此时运行项目会看到已经添加成功:

此时会发现,不管点击哪个tab,只有当前tab的text会显示,其他tab只显示图标,这显然是有问题的,这是因为BottomNavigationView 默认是三个tab的,如果超过三个,就会出现当前问题。

据说在API28之前是需要使用反射机制解决的,28及之后 加一个配置即可 app:labelVisibilityMode="labeled":

由于我们使用的API28编译,所以运行效果正常,此时我们吧编译环境改为27,再次运行会发现报错:

说的是没有找到 labelVisibilityMode 这个属性,因为现在是API27编译,此时还没有这个属性,那么之后就需要使用反射机制来解决。

这里的问题出在 BottomNavigationMenuView 的 mShiftingMode 上,可以查看源码:

当tab大于3时,会将ShiftingMode设置为true,那么我们现在就需要将所有tab的ShiftingMode这是为false即可:这里新建一个类,这里注意当api大于等于28就不需要以下处理:

public class BottomNavigationViewHelper {
@SuppressLint("RestrictedApi")
public static void disableShiftMode(BottomNavigationView view) {
BottomNavigationMenuView menuView = (BottomNavigationMenuView) view.getChildAt(0);
try {
Field shiftingMode = menuView.getClass().getDeclaredField("mShiftingMode");
shiftingMode.setAccessible(true);
shiftingMode.setBoolean(menuView, false);
shiftingMode.setAccessible(false);
for (int i = 0; i BottomNavigationItemView item = (BottomNavigationItemView) menuView.getChildAt(i);
item.setShiftingMode(false); //设置每一个tab为fales
item.setChecked(item.getItemData().isChecked());
}
} catch (NoSuchFieldException e) {
Log.e("BNVHelper", "Unable to get shift mode field", e);
} catch (IllegalAccessException e) {
Log.e("BNVHelper", "Unable to change value of shift mode", e);
}
}
}

在MainActivity的onCreate最后一行添加: BottomNavigationViewHelper.disableShiftMode(navigation); 如:

此时运行项目,会发现tab已经都可以正常显示了:

三、那么能不能加到6个呢,尝试之后发现会报错:

Caused by: java.lang.IllegalArgumentException: Maximum number of items supported by BottomNavigationView is 5. Limit can be checked with BottomNavigationView#getMaxItemCount()
at android.support.design.internal.BottomNavigationMenu.addInternal(BottomNavigationMenu.java:45)
……………………………………

为什么呢?进入 BottomNavigationView 源码看一下,会发现源码里有这么一句:

直接返回最大item数量为5个,已经在代码里固定了,所以以上错误会显示最大数量为5 的错误。


实例代码:https://download.csdn.net/download/ssdate/11040915



推荐阅读
  • RecyclerView初步学习(一)
    RecyclerView初步学习(一)ReCyclerView提供了一种插件式的编程模式,除了提供ViewHolder缓存模式,还可以自定义动画,分割符,布局样式,相比于传统的ListVi ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 本文将介绍如何编写一些有趣的VBScript脚本,这些脚本可以在朋友之间进行无害的恶作剧。通过简单的代码示例,帮助您了解VBScript的基本语法和功能。 ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • 1.如何在运行状态查看源代码?查看函数的源代码,我们通常会使用IDE来完成。比如在PyCharm中,你可以Ctrl+鼠标点击进入函数的源代码。那如果没有IDE呢?当我们想使用一个函 ... [详细]
  • 本文详细介绍了如何使用 Yii2 的 GridView 组件在列表页面实现数据的直接编辑功能。通过具体的代码示例和步骤,帮助开发者快速掌握这一实用技巧。 ... [详细]
  • 本文详细介绍了Java中org.eclipse.ui.forms.widgets.ExpandableComposite类的addExpansionListener()方法,并提供了多个实际代码示例,帮助开发者更好地理解和使用该方法。这些示例来源于多个知名开源项目,具有很高的参考价值。 ... [详细]
  • 使用 Azure Service Principal 和 Microsoft Graph API 获取 AAD 用户列表
    本文介绍了一段通用代码示例,该代码不仅能够操作 Azure Active Directory (AAD),还可以通过 Azure Service Principal 的授权访问和管理 Azure 订阅资源。Azure 的架构可以分为两个层级:AAD 和 Subscription。 ... [详细]
  • Python自动化处理:从Word文档提取内容并生成带水印的PDF
    本文介绍如何利用Python实现从特定网站下载Word文档,去除水印并添加自定义水印,最终将文档转换为PDF格式。该方法适用于批量处理和自动化需求。 ... [详细]
  • XNA 3.0 游戏编程:从 XML 文件加载数据
    本文介绍如何在 XNA 3.0 游戏项目中从 XML 文件加载数据。我们将探讨如何将 XML 数据序列化为二进制文件,并通过内容管道加载到游戏中。此外,还会涉及自定义类型读取器和写入器的实现。 ... [详细]
  • Explore a common issue encountered when implementing an OAuth 1.0a API, specifically the inability to encode null objects and how to resolve it. ... [详细]
  • 本文深入探讨 MyBatis 中动态 SQL 的使用方法,包括 if/where、trim 自定义字符串截取规则、choose 分支选择、封装查询和修改条件的 where/set 标签、批量处理的 foreach 标签以及内置参数和 bind 的用法。 ... [详细]
  • 本文详细介绍了Akka中的BackoffSupervisor机制,探讨其在处理持久化失败和Actor重启时的应用。通过具体示例,展示了如何配置和使用BackoffSupervisor以实现更细粒度的异常处理。 ... [详细]
  • 在当前众多持久层框架中,MyBatis(前身为iBatis)凭借其轻量级、易用性和对SQL的直接支持,成为许多开发者的首选。本文将详细探讨MyBatis的核心概念、设计理念及其优势。 ... [详细]
  • Android LED 数字字体的应用与实现
    本文介绍了一种适用于 Android 应用的 LED 数字字体(digital font),并详细描述了其在 UI 设计中的应用场景及其实现方法。这种字体常用于视频、广告倒计时等场景,能够增强视觉效果。 ... [详细]
author-avatar
顺大顺麻麻1009_388
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有