ToolBar控件的使用<一> 通过菜单项设置ToolBar

本文详细介绍Toolbar控件的使用方法,包括如何隐藏ActionBar、在布局文件中配置Toolbar、设置菜单及响应事件,以及如何修改隐藏菜单的弹出位置和样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • Toolbar控件介绍

由于ActionBar存在不少问题,而且使用也不灵活。在更高的版本中,谷歌推出了新的控件Toolbar来替换ActionBar,并提供了低版本的兼容包,Toolbar更加自由灵活,子菜单和logo的设置和响应都比之前的更加方便,还可以随处放置。可以说,Toolbar是对ActionBar的进一步完善和强化,
- 首先看下我们最终实现的效果图

效果图

网上看了一些文章,好些都是把ToolBar,AppBarLayout,CollapsingToolbarLayout,CoordinatorLayout等控件一块结合起来讲,但是我打算本文只单独讲讲ToolBar,后续文章再让Toolbar结合其他几个控件一块讲。
- Toolbar控件的使用

<1> 隐藏ActionBar控件
为了使用ToolBar,首先我们需要隐藏之前的ActionBar,可以通过主题风格来隐藏ActionBar,也可以通过代码隐藏ActionBar,我一般是通过主题风格来实现的:


    <!--设置给ToolbarActivity的风格-->
    <style name="NoActionbarTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--设置Toobar左侧空白消失-->
        <item name="toolbarStyle">@style/ClubToolbar</item>
        <item name="android:windowNoTitle">true</item>
        <item name="windowActionBar">false</item>
    </style>

    <style name="ClubToolbar" parent="Widget.AppCompat.Toolbar">
        <item name="contentInsetStart">0dp</item><!-- 设置该属性解决Toolbar左侧空白部分-->
    </style>

    <!--设置给Toolbar的风格-->
    <style name="ToolBarTheme" parent="@style/ThemeOverlay.AppCompat.Light">
        <item name="android:textColorSecondary">#FFFFFFFF</item>
        <item name="android:colorBackground">#88FFFFFF</item>
        <item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>
        <item name="android:actionOverflowButtonStyle">@style/OverflowButtonStyle</item>
    </style>

    <!--设置toolbar弹出菜单的位置-->
    <style name="OverflowMenuStyle" parent="Widget.AppCompat.Light.PopupMenu.Overflow">
        <item name="overlapAnchor">false</item>  <!--设置为false即可使menu位置位于toolbar之下-->
    </style>
    <!--修改toolbar弹出剩余隐藏菜单条目按钮的样式-->
    <style name="OverflowButtonStyle" parent="@android:style/Widget.ActionButton.Overflow">
        <item name="android:src">@mipmap/ic_menu_setting</item>
    </style>

然后在AndroidManifest.xml中设置ToolBarActivity的主题

<activity android:name=".Toolbar.ToolBarActivity"  
          android:theme="@style/NoActionbarTheme"/>

<2> 把ToolBar控件放入到布局文件中
隐藏好ActionBar之后,我们直接把Toolbar放到布局文件中,可以通过代码和布局文件两种方式来设置Toolbar的logo,navigationIcon,title,subTitle等属性。这里我是通过布局文件来设置title的属性的。具体如下

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    tools:context=".Toolbar.ToolBarActivity_01">

    <ImageView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerCrop"
        android:src="@mipmap/background02"/>

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        app:title="界面标题"
        app:subtitle="二级标题"
        app:navigationIcon="@mipmap/ic_menu_back"
        app:logo="@mipmap/logo"
        android:background="?attr/colorPrimary"
        android:theme="@style/ToolBarTheme"/>

</RelativeLayout>

<3>通过菜单项为ToolBar设置菜单条目以及响应事件

在Activity中,我们首先获取到toolbar,然后再把它设置给当前界面的工具栏。可以通过重写onCreateOptionsMenu方法来给当前Toolbar控件设置具体菜单条目。然后通过setOnMenuItemClickListener方法来监听具体哪个菜单字条被点击,通过setNavigationOnClickListener方法来监听navigationIcon是否被点击。
- java代码

public class ToolBarActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_tool_bar);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        toolbar.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item)  {
                //在这里执行我们的逻辑代码
                switch (item.getItemId()){
                    case R.id.action_edit:
                        Toast.makeText(ToolBarActivity.this,"编辑被点击",Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.action_share:
                        Toast.makeText(ToolBarActivity.this,"分享被点击",Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.action_settings01:
                        Toast.makeText(ToolBarActivity.this,"设置01被点击",Toast.LENGTH_SHORT).show();
                        break;
                    case R.id.action_settings02:
                        Toast.makeText(ToolBarActivity.this,"设置02被点击",Toast.LENGTH_SHORT).show();
                        break;

                }
                return false;
            }
        });
        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //在这里执行我们的逻辑代码
                Toast.makeText(ToolBarActivity.this,"返回按钮被点击",Toast.LENGTH_SHORT).show();
            }
        });

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // 为toolbar创建Menu
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

}
  • R.menu.menu_main对应的menu文件夹下面的menu_main.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:app="http://schemas.android.com/apk/res-auto"
      xmlns:tools="http://schemas.android.com/tools"
      tools:context=".MainActivity">


  <item android:id="@+id/action_edit"
        android:title="@string/action_edit"
        android:orderInCategory="80"
        android:icon="@mipmap/ic_menu_edit"
        app:showAsAction="ifRoom" />

  <item android:id="@+id/action_share"
        android:title="@string/action_share"
        android:orderInCategory="90"
        android:icon="@mipmap/ic_menu_share"
        app:showAsAction="ifRoom" />

  <item android:id="@+id/action_settings01"
        android:title="@string/action_settings01"
        android:orderInCategory="100"
        android:icon="@mipmap/ic_menu_setting"
        app:showAsAction="ifRoom"/>

  <item android:id="@+id/action_settings02"
        android:title="@string/action_settings02"
        android:orderInCategory="100"
        android:icon="@mipmap/ic_menu_setting"
        app:showAsAction="ifRoom"/>

</menu>

你可以利用ActionBar部件提供的全部功能,将你的选项菜单项放在Action Bar的右上角,对用户来说使用更方便,控制该行为的主菜单项属性是android:showAsAction。
  这个属性可接受的值有:
  1、always:这个值会使菜单项一直显示在Action Bar上。
  2、ifRoom:如果有足够的空间,这个值会使菜单项显示在Action Bar上。
  3、never:这个值使菜单项永远都不出现在Action Bar上。
  4、withText:这个值使菜单项和它的图标,菜单文本一起显示。

<4>修改ToolBar隐藏菜单的弹出位置和颜色,弹出按钮的样式
ToolBar弹出隐藏菜单条目的默认位置和Menu处于同一水平高度,这样看起来很不美观,如果我们希望修改隐藏菜单的默认位置和颜色,以及修改弹出按钮的样式,就需要给ToolBar设置新的主题。
修改之前

修改之后
具体代码如下:

    <style name="ToolBarTheme" parent="@style/ThemeOverlay.AppCompat.Light">
        <item name="android:textColorSecondary">#FFFFFFFF</item>
        <item name="android:colorBackground">#88FFFFFF</item>
        <item name="actionOverflowMenuStyle">@style/OverflowMenuStyle</item>
        <item name="android:actionOverflowButtonStyle">@style/OverflowButtonStyle</item>
    </style>

    <!--设置toolbar弹出菜单的位置-->
    <style name="OverflowMenuStyle" parent="Widget.AppCompat.Light.PopupMenu.Overflow">
        <item name="overlapAnchor">false</item>  <!--设置为false即可使menu位置位于toolbar之下-->
    </style>
    <!--修改toolbar弹出剩余隐藏菜单条目按钮的样式-->
    <style name="OverflowButtonStyle" parent="@android:style/Widget.ActionButton.Overflow">
        <item name="android:src">@mipmap/ic_menu_setting</item>
    </style>

然后把这个ToolBarTheme风格设置给ToolBar,
android:theme=”@style/ToolBarTheme”

.ui <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainWindow</class> <widget class="QMainWindow" name="MainWindow"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>600</height> </rect> </property> <property name="windowTitle"> <string>MainWindow</string> </property> <widget class="QWidget" name="centralwidget"> <widget class="QSpinBox" name="spinBox"> <property name="geometry"> <rect> <x>560</x> <y>110</y> <width>91</width> <height>22</height> </rect> </property> </widget> <widget class="QPushButton" name="btn1"> <property name="geometry"> <rect> <x>560</x> <y>150</y> <width>75</width> <height>24</height> </rect> </property> <property name="text"> <string>PushButton</string> </property> </widget> </widget> <widget class="QMenuBar" name="menubar"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>800</width> <height>22</height> </rect> </property> </widget> <widget class="QStatusBar" name="statusbar"/> </widget> <resources/> <connections/> </ui> .h #ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> QT_BEGIN_NAMESPACE namespace Ui { class MainWindow; } QT_END_NAMESPACE class MainWindow : public QMainWindow { Q_OBJECT public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); private: Ui::MainWindow *ui; }; #endif // MAINWINDOW_H .cpp #include <QMainWindow> #include <QMenu> #include <QMenuBar> #include <QToolBar> #include <QStatusBar> #include <QAction> #include <QDockWidget> #include <QDoubleSpinBox> #include <QLabel> #include <QPixmap> #include <QIcon> #include <QVBoxLayout> class MainWindow : public QMainWindow { public: MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) { setupMenus(); setupToolbar(); setupStatusBar(); setupDockWidget(); } private: void setupMenus() { QMenu *fileMenu = menuBar()->addMenu(tr("&File")); QAction *exitAction = fileMenu->addAction(tr("E&xit")); connect(exitAction, &QAction::triggered, this, &QMainWindow::close); QMenu *bitmapMenu = menuBar()->addMenu(tr("&Bitmap")); showAction = bitmapMenu->addAction(tr("显示")); showAction->setCheckable(true); connect(showAction, &QAction::toggled, this, &MainWindow::toggleImage); QMenu *zoomMenu = menuBar()->addMenu(tr("&Zoom")); zoomInAction = zoomMenu->addAction(tr("放大")); zoomOutAction = zoomMenu->addAction(tr("缩小")); resetZoomAction = zoomMenu->addAction(tr("复原")); connect(zoomInAction, &QAction::triggered, this, &MainWindow::zoomIn); connect(zoomOutAction, &QAction::triggered, this, &MainWindow::zoomOut); connect(resetZoomAction, &QAction::triggered, this, &MainWindow::resetZoom); } void setupToolbar() { QToolBar *toolbar = addToolBar(tr("Toolbar")); toolbar->addAction(showAction); toolbar->addAction(zoomInAction); toolbar->addAction(zoomOutAction); toolbar->addAction(resetZoomAction); } void setupStatusBar() { statusBar()->showMessage(tr("Ready")); } void setupDockWidget() { QDockWidget *dockWidget = new QDockWidget(tr("Settings"), this); dockWidget->setAllowedAreas(Qt::RightDockWidgetArea); addDockWidget(Qt::RightDockWidgetArea, dockWidget); QWidget *dockWidgetContents = new QWidget(dockWidget); QVBoxLayout *layout = new QVBoxLayout(dockWidgetContents); QLabel *zoomLabel = new QLabel(tr("缩放比例:")); zoomSpinBox = new QDoubleSpinBox; zoomSpinBox->setRange(0.1, 1.0); zoomSpinBox->setValue(0.8); layout->addWidget(zoomLabel); layout->addWidget(zoomSpinBox); dockWidget->setWidget(dockWidgetContents); } void toggleImage(bool checked) { if (checked) { showAction->setText(tr("隐藏")); // 显示图片 } else { showAction->setText(tr("显示")); // 隐藏图片 } } void zoomIn() { zoomImage(1.2); } void zoomOut() { zoomImage(0.8); } void resetZoom() { zoomImage(1.0); } void zoomImage(double factor) { zoomSpinBox->setValue(zoomSpinBox->value() * factor); // 更新图片缩放 } QAction *showAction; QAction *zoomInAction; QAction *zoomOutAction; QAction *resetZoomAction; QDoubleSpinBox *zoomSpinBox; }; 重新构建代码以完成QT项目(6.8.2) 创建基于QMainWindow的Qt项目,实现如下要求: 创建“位图”菜单,包含菜单项要求如下:菜单项初始为“显示”,点击后在窗口(中心部件里)会显示个图片,此时菜单项的文字由“显示”更改为“隐藏”,再次点击“隐藏”,会隐藏图片,且菜单项内容更改为“显示”; 建立个“缩放”菜单,包含“放大”、“缩小”和“复原”三个菜单项,实现对图像按比例放大或缩小或原尺寸显示功能;(缩放比例在下面可停靠窗口中设置); 建立个可停靠窗口,上面放置个double spin控件,用于设置缩放比例,大小在0.1到1之间,默认缩放比例为0.8; 为每个菜单项定义快捷键和图标,其中要求“显示”或“隐藏”时,对应的图标也不同; 在工具栏添加上面所有动作(QAction)的按钮,要求鼠标移动到对应按钮时,状态栏会显示相应的提示信息;要求显示和隐藏状态不同时,工具栏中显示的图标也不同、状态栏的提示信息也不同;缩放因子大小不同,状态栏的提示的也不同。 缩放比在按下拜托你
最新发布
07-06
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值