Android studio:顶部导航栏Toolbar
主流APP在顶部都配有导航栏,在 Android 中,ActionBar
是默认启用的,它是位于屏幕顶部的一个工具栏,用来放置应用的标题、导航和操作菜单。
如果你想使用自定义的 Toolbar
来替代 ActionBar
,应该先关闭它。可以通过设置 NoActionBar
主题或者在代码中手动隐藏 ActionBar
来实现。
一、关闭ActionBar
在 styles.xml
中,继承 Theme.AppCompat.Light.NoActionBar
或Theme.MaterialComponents.DayNight.NoActionBar
来关闭默认的 ActionBar
。
<resources><style name="AppCompatTheme" parent="Theme.AppCompat.Light.NoActionBar"></style></resources>
然后,在 AndroidManifest.xml
中应用该主题。
假设你想应用这个主题到整个应用,你可以在 AndroidManifest.xml
中设置它:
<applicationandroid:theme="@style/AppCompatTheme">...
</application>
或者你也可以在单个活动(Activity)中使用:
<activityandroid:name=".MainActivity"android:theme="@style/AppCompatTheme">
</activity>
二、创建活动页面的XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><androidx.appcompat.widget.Toolbarandroid:id="@+id/tl_head"android:layout_width="match_parent"android:layout_height="wrap_content" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:orientation="vertical"android:padding="5dp"><TextViewandroid:id="@+id/tv_desc"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/black"android:textSize="17sp"android:text="该页面演示工具栏功能" /></LinearLayout></LinearLayout>
在 Android 中,ToolBar
是一个继承自 ViewGroup
的类。ViewGroup
是一个视图容器,它可以包含其他视图(包括其他 View
或 ViewGroup
),而 ToolBar
作为一个 ViewGroup
,也具有这种容器的特性。ToolBar
本质上是一个布局容器,它可以包含多个视图组件(比如按钮、文本、图标等)。这些组件可以通过布局参数进行管理和排列。
三、创建活动页面
public class ToolbarActivity extends AppCompatActivity {private final static String TAG = "ToolbarActivity";@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_toolbar);Toolbar tl_head = findViewById(R.id.tl_head); // 从布局文件中获取名叫tl_head的工具栏tl_head.setTitle("工具栏页面"); // 设置工具栏的标题文本setSupportActionBar(tl_head); // 使用tl_head替换系统自带的ActionBartl_head.setTitleTextColor(Color.RED); // 设置工具栏的标题文字颜色tl_head.setLogo(R.drawable.ic_app); // 设置工具栏的标志图片tl_head.setSubtitle("Toolbar"); // 设置工具栏的副标题文本tl_head.setSubtitleTextColor(Color.YELLOW); // 设置工具栏的副标题文字颜色tl_head.setBackgroundResource(R.color.blue_light); // 设置工具栏的背景tl_head.setNavigationIcon(R.drawable.ic_back); // 设置工具栏左边的导航图标// 给tl_head设置导航图标的点击监听器// setNavigationOnClickListener必须放到setSupportActionBar之后,不然不起作用tl_head.setNavigationOnClickListener(view -> {finish(); // 结束当前页面});}}
其中setSupportActionBar是用自定义工具栏代替系统自带的顶部导航栏ActionBar,之后可以为顶部导航栏设置诸多属性。
下面这段代码是在设置 ToolBar
的导航按钮点击事件监听器。具体来看,代码的作用是:当用户点击 ToolBar
上的导航按钮(通常是左上角的返回按钮)时,执行 finish()
方法来结束当前活动(即关闭当前页面)。
tl_head.setNavigationOnClickListener(view -> {finish();});
半屏效果图如下:
四、溢出菜单
当导航栏的内容不够放,就需要设置溢出菜单,例如下面的三个点图标,点击之后弹出窗口。
1.活动页面XML代码如下:
<LinearLayout 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="match_parent"android:orientation="vertical"><androidx.appcompat.widget.Toolbarandroid:id="@+id/tl_head"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@color/blue_light"app:navigationIcon="@drawable/ic_back" /><LinearLayoutandroid:layout_width="match_parent"android:layout_height="0dp"android:layout_weight="1"android:orientation="vertical"android:padding="5dp"><TextViewandroid:id="@+id/tv_desc"android:layout_width="wrap_content"android:layout_height="wrap_content"android:textColor="@color/black"android:textSize="17sp"android:text="该页面演示溢出菜单功能" /></LinearLayout></LinearLayout>
app:navigationIcon="@drawable/ic_back"
这一属性的作用是为 ToolBar
设置一个导航按钮的图标,通常位于 ToolBar
左侧,常见用途是返回按钮。
2.创建菜单文件:
下面是包含3个菜单项的溢出菜单XML:
<menu xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto" ><itemandroid:id="@+id/menu_refresh"android:icon="@drawable/ic_refresh"app:showAsAction="ifRoom"android:title="刷新"/><itemandroid:id="@+id/menu_about"android:icon="@drawable/ic_about"app:showAsAction="never"android:title="关于"/><itemandroid:id="@+id/menu_quit"android:icon="@drawable/ic_quit"app:showAsAction="never"android:title="退出"/></menu>
<menu>
标签在 Android 开发中主要用于创建菜单,常用于 ToolBar
、PopupMenu
、ContextMenu
、BottomNavigationView
等。
xmlns:app="http://schemas.android.com/apk/res-auto"
是 XML 命名空间声明,它的作用是支持 Android 自定义属性(比如 app:showAsAction
、app:navigationIcon
等)。
在 Android XML 布局文件中,某些自定义属性不是标准的 Android 属性(即 android:
开头的),这些自定义属性通常来自 AndroidX 组件、Material Design 组件或第三方库,xmlns:app="http://schemas.android.com/apk/res-auto"
允许你在 XML 中使用这些库提供的属性。
这里的app:showAsAction有多种取值,例如取never,则该菜单项一定不在导航栏显示。
因此刷新这个选项会显示在导航栏上,而关于、推出则会放入溢出菜单列表。
3.下面是在活动代码中增加对菜单的处理逻辑。
@SuppressLint("SetTextI18n")
public class OverflowMenuActivity extends AppCompatActivity {private TextView tv_desc; // 声明一个文本视图对象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_overflow_menu);Toolbar tl_head = findViewById(R.id.tl_head); // 从布局文件中获取名叫tl_head的工具栏tl_head.setTitle("溢出菜单页面"); // 设置工具栏的标题文字setSupportActionBar(tl_head); // 使用tl_head替换系统自带的ActionBartv_desc = findViewById(R.id.tv_desc);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// 从menu_overflow.xml中构建菜单界面布局getMenuInflater().inflate(R.menu.menu_overflow, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item) {int id = item.getItemId(); // 获取菜单项的编号if (id == android.R.id.home) { // 点击了工具栏左边的返回箭头finish(); // 结束当前页面} else if (id == R.id.menu_refresh) { // 点击了刷新图标tv_desc.setText("当前刷新时间: " + DateUtil.getNowTime());} else if (id == R.id.menu_about) { // 点击了关于菜单项Toast.makeText(this, "这个是工具栏的演示demo", Toast.LENGTH_LONG).show();} else if (id == R.id.menu_quit) { // 点击了退出菜单项finish(); // 结束当前页面}return super.onOptionsItemSelected(item);}}
@SuppressLint("SetTextI18n")
是 Android Lint 的一个注解,用于抑制 SetTextI18n
相关的 Lint 检查警告。在 Android 开发中,TextView.setText()
直接拼接字符串时,Lint 会警告你应该使用国际化(i18n)资源,而不是硬编码的字符串。如果你确定这个警告可以忽略,就可以使用 @SuppressLint("SetTextI18n")
来关闭它。
例如:textView.setText("用户名:" + username);Lint 会报 "Hardcoded text should use @StringRes
instead"(硬编码文本应该使用 strings.xml
) 的警告:警告原因:
直接使用 "用户名:"
这样的硬编码字符串,不利于国际化(i18n),应该使用 strings.xml
定义文本。
onCreate中的代码就是上面提到的用自定义的顶部导航栏代替系统自有的导航栏。
着重看下面的代码:它的主要功能是加载 XML 菜单文件并将其显示在 Toolbar
或 ActionBar
上。
@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// 从menu_overflow.xml中构建菜单界面布局getMenuInflater().inflate(R.menu.menu_overflow, menu);return true;}
onCreateOptionsMenu(Menu menu)
方法原本属于 Activity
类,它是 Android Activity
生命周期的一部分,用于创建选项菜单(Options Menu)。
你需要重写(@Override
)这个方法,因为:
- 默认的
onCreateOptionsMenu()
方法是空实现的,如果你不重写它,菜单不会显示。 - 你需要告诉系统如何创建菜单,并指定菜单的内容(即加载
menu.xml
)。
3.1为什么要使用 Menu
而不是直接在 XML 里写按钮?
Menu
是 专门用于 Toolbar
或 ActionBar
的菜单项,系统会自动管理它们:
- 菜单项会自动适应设备屏幕大小(小屏幕时会隐藏到
...
溢出菜单)。 - 可以动态管理菜单项(比如在不同页面显示不同的菜单)。
- 有统一的交互逻辑(长按、点击、图标显示规则)。
如果你直接在 activity_main.xml
里写 <Button>
,它只是普通按钮,不会自动适配 Toolbar
,体验很糟糕。
3.2 如何确保菜单项显示在顶部导航栏:
setSupportActionBar(tl_head)
方法的作用是设置自定义的 Toolbar
作为该 Activity
的操作栏(ActionBar
)。在设置了自定义的 Toolbar
后,onCreateOptionsMenu
方法中的菜单项(通过 getMenuInflater().inflate(R.menu.menu_overflow, menu)
加载)会自动显示在这个 Toolbar
上,而不是其他地方。
这个行为是由 AppCompatActivity
提供的,它会在 Toolbar
上显示菜单项,前提是调用了 setSupportActionBar(tl_head)
来替换默认的 ActionBar
。
因此,确保菜单项显示在顶部导航栏的关键步骤是:
- 使用
Toolbar
替代默认的ActionBar
:setSupportActionBar(tl_head)
。 - 在
onCreateOptionsMenu
中加载菜单项:getMenuInflater().inflate(R.menu.menu_overflow, menu)
。
3.3 点击事件
int id = item.getItemId(); // 获取菜单项的编号。item.getItemId()
返回的是被点击的菜单项的ID。通过这个ID,后续的 if
语句可以判断是哪一个菜单项被点击了。
最后,调用 super.onOptionsItemSelected(item)
,这样可以让父类继续处理其他未被处理的菜单项,确保系统的其他行为不会受到影响。
3.4 为什么没有写监听器,仍然能通过点击事件判断 ID:
onOptionsItemSelected
方法是用于处理用户点击菜单项时的事件处理。当用户点击菜单项时,系统会自动调用 onOptionsItemSelected
方法,并传递一个 MenuItem
对象。在 onOptionsItemSelected
方法中,你可以通过 item.getItemId()
获取到被点击的菜单项的 ID,从而判断用户点击了哪个菜单项,并执行对应的操作。
不需要显式地为每个菜单项写监听器,因为:
onOptionsItemSelected
方法已经充当了菜单项的事件监听器。- 系统会自动识别哪个菜单项被点击,并通过
item.getItemId()
将菜单项的 ID 传递给onOptionsItemSelected
方法。
所以,你在 onOptionsItemSelected
中通过判断 item.getItemId()
来执行特定操作,系统已经为你处理了菜单项的点击事件,免去了为每个菜单项单独添加监听器的需求。
代码流程概述:
-
在
onCreate
中:- 获取并设置工具栏。
- 使用
setSupportActionBar(tl_head)
来替换默认的ActionBar
,这样就会显示你自定义的工具栏。
-
在
onCreateOptionsMenu
中:- 通过
getMenuInflater().inflate(R.menu.menu_overflow, menu)
将menu_overflow.xml
中的菜单项加载到工具栏上,确保菜单项显示在顶部。
- 通过
-
在
onOptionsItemSelected
中:- 监听菜单项的点击事件,通过
item.getItemId()
判断点击了哪个菜单项,然后执行相应操作。
- 监听菜单项的点击事件,通过
效果:
相关文章:

Android studio:顶部导航栏Toolbar
主流APP在顶部都配有导航栏,在 Android 中,ActionBar 是默认启用的,它是位于屏幕顶部的一个工具栏,用来放置应用的标题、导航和操作菜单。 如果你想使用自定义的 Toolbar 来替代 ActionBar,应该先关闭它。可以通过设置…...

mmap 文件映射
🌈 个人主页:Zfox_ 🔥 系列专栏:Linux 目录 一:🔥 mmap介绍🦋 基本说明🦋 参数介绍🦋 返回值 二:🔥 demo代码🦋 写入映射🦋…...

基于微信小程序的医院预约挂号系统的设计与实现
hello hello~ ,这里是 code袁~💖💖 ,欢迎大家点赞🥳🥳关注💥💥收藏🌹🌹🌹 🦁作者简介:一名喜欢分享和记录学习的在校大学生…...

【Linux】Socket编程—UDP
🔥 个人主页:大耳朵土土垚 🔥 所属专栏:Linux系统编程 这里将会不定期更新有关Linux的内容,欢迎大家点赞,收藏,评论🥳🥳🎉🎉🎉 文章目…...
2025年物联网相关专业毕业论文选题参考,文末联系,选题相关资料提供
一、智能穿戴解决方案研究方向 序号解决方案论文选题论文研究方向1智能腰带健康监测基于SpringBoot和Vue的智能腰带健康监测数据可视化平台开发研究如何利用SpringBoot和Vue技术栈开发一个数据可视化平台,用于展示智能腰带健康监测采集的数据,如心率、血…...

如何在WPS和Word/Excel中直接使用DeepSeek功能
以下是将DeepSeek功能集成到WPS中的详细步骤,无需本地部署模型,直接通过官网连接使用:1. 下载并安装OfficeAI插件 (1)访问OfficeAI插件下载地址:OfficeAI助手 - 免费办公智能AI助手, AI写作,下载…...

DeepSeek之Api的使用(将DeepSeek的api集成到程序中)
一、DeepSeek API 的收费模式 前言:使用DeepSeek的api是收费的 免费版: 可能提供有限的免费额度(如每月一定次数的 API 调用),适合个人开发者或小规模项目。 付费版: 超出免费额度后,可能需要按…...

使用DeepSeek实现AI自动编码
最近deepseek很火,低成本训练大模型把OpenAI、英伟达等股票搞得一塌糊涂。那它是什么呢,对于咱们程序员编码能有什么用呢?DeepSeek 是一款先进的人工智能语言模型,在自然语言处理和代码生成方面表现出色。它经过大量代码数据训练&…...

30~32.ppt
目录 30.导游小姚-介绍首都北京❗ 题目 解析 31.小张-旅游产品推广文章 题目 解析 32.小李-水的知识❗ 题目 解析 30.导游小姚-介绍首都北京❗ 题目 解析 新建幻灯片-从大纲-重置-检查设计→主题对话框→浏览主题:考生文件夹(注意&#x…...
Java的匿名内部类转为lamada表达式
在Java中,匿名内部类通常用于创建没有命名类的实例。例如,你可能需要创建一个实现了某个接口的匿名类,或者在需要重写某个方法时使用它。在Java 8及更高版本中,你可以使用Lambda表达式来替代传统的匿名内部类,使得代码…...

redis高级数据结构Stream
文章目录 背景stream概述消息 ID消息内容常见操作独立消费创建消费组消费 Stream弊端Stream 消息太多怎么办?消息如果忘记 ACK 会怎样?PEL 如何避免消息丢失?分区 Partition Stream 的高可用总结 背景 为了解决list作为消息队列是无法支持消息多播问题,Redis5.0…...
LeetCode781 森林中的兔子
问题描述 在一片神秘的森林里,住着许多兔子,但是我们并不知道兔子的具体数量。现在,我们对其中若干只兔子进行提问,问题是 “还有多少只兔子与你(指被提问的兔子)颜色相同?” 我们将每只兔子的…...
单硬盘槽笔记本更换硬盘
背景 本人的笔记本电脑只有一个硬盘槽,而且没有M.2的硬盘盒,只有一个移动硬盘 旧硬盘:512G 新硬盘:1T 移动硬盘:512G 参考链接:https://www.bilibili.com/video/BV1iP41187SW/?spm_id_from333.1007.t…...
EB生成配置的过程
EB Tresos Studio,简称EB,通过图形化的模式进行配置生成,并根据选项配置生成配置代码,即 MCAL 层各个模块的配置参数。 在 MCAL 代码中,分为静态代码和配置代码。静态代码,就是 AUTOSAR 规范内容,包含对硬件的封装以及标准化接口的封装;配置代码一般用于配置初始化结构…...
量化交易数据获取:xtquant库的高效应用
量化交易数据获取:xtquant库的高效应用 在量化交易领域,历史行情数据的重要性不言而喻。它不仅为策略回测提供基础,也是实时交易决策的重要参考。本文将介绍如何使用xtquant库来高效获取和处理历史行情数据。 技术背景与应用场景 对于量化…...
哨兵模式与 Redis Cluster:高可用 Redis 的深度剖析
深入探讨 Redis 高可用性解决方案:哨兵模式与 Redis Cluster 一、哨兵模式(Redis Sentinel)深入解析 (一)工作原理详解 哨兵模式通过一个或多个哨兵实例监控 Redis 主从复制集群,确保在主节点发生故障时…...

C++20新特性
作者:billy 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 前言 C20 是 C 标准中的一个重要版本,引入了许多新特性和改进,包括模块(Modules)、协程…...

电机实验曲线数据提取
处理Python 代码供参考: 1、曲线数据还原 import cv2 import numpy as np import matplotlib.pyplot as plt# 读取图像 image_path 1.png image cv2.imread(image_path) image_copy image.copy() # 创建图像副本,用于叠加显示# 转换为灰度图像 gray cv2.cvtCo…...

windows蓝牙驱动开发-调试及支持的HCI和事件
调试蓝牙配置文件驱动程序 开发蓝牙配置文件驱动程序时,可以使用驱动程序验证程序来协助其调试。 若要启用验证检查,必须为 Bthusb.sys 启用驱动程序验证程序。 如果不执行此操作,将禁用验证检查。 若要完全利用验证检查,请确保…...

Excel大数据量导入导出
github源码 地址(更详细) : https://github.com/alibaba/easyexcel 文档:读Excel(文档已经迁移) B 站视频 : https://www.bilibili.com/video/BV1Ff4y1U7Qc 一、JAVA解析EXCEL工具EasyExcel Java解析、生成Excel比较…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする
日语学习-日语知识点小记-构建基础-JLPT-N4阶段(33):にする 1、前言(1)情况说明(2)工程师的信仰2、知识点(1) にする1,接续:名词+にする2,接续:疑问词+にする3,(A)は(B)にする。(2)復習:(1)复习句子(2)ために & ように(3)そう(4)にする3、…...

循环冗余码校验CRC码 算法步骤+详细实例计算
通信过程:(白话解释) 我们将原始待发送的消息称为 M M M,依据发送接收消息双方约定的生成多项式 G ( x ) G(x) G(x)(意思就是 G ( x ) G(x) G(x) 是已知的)࿰…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
基础测试工具使用经验
背景 vtune,perf, nsight system等基础测试工具,都是用过的,但是没有记录,都逐渐忘了。所以写这篇博客总结记录一下,只要以后发现新的用法,就记得来编辑补充一下 perf 比较基础的用法: 先改这…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院查看报告小程序
一、开发环境准备 工具安装: 下载安装DevEco Studio 4.0(支持HarmonyOS 5)配置HarmonyOS SDK 5.0确保Node.js版本≥14 项目初始化: ohpm init harmony/hospital-report-app 二、核心功能模块实现 1. 报告列表…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...

前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包
文章目录 现象:mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时,可能是因为以下几个原因:1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...