Android基础控件之Toolbar

  • Post author:
  • Post category:其他




开个头

总结

Toolbar

基本用法



简介

从 Android 3.0(API level11)开始,所有使用默认主题的 Activity 均使用

ActionBar

作为应用栏。不过,经过不同 Android 版本的演化,应用栏功能已逐渐添加到原生

ActionBar

中。因此,原生

ActionBar

的行为会随设备使用的 Android 系统的版本而发生变化。相比之下,最新功能已添加到支持库版本的

Toolbar

中,并且这些功能可以在任何能够使用该支持库的设备上使用。

因此,您应使用支持库的

Toolbar

类来实现 Activity 的应用栏。使用

support library



Toolbar

有助于确保您的应用在最大范围的设备上保持一致的行为。例如,

Toolbar

小部件能够在运行 Android 2.1(API 级别 7)或更高版本的设备上提供 Material Design 体验,但除非设备运行的是 Android 5.0(API level 21)或更高版本,否则原生操作栏不会支持 Material Design。



使用Toolbar

  1. 首先导入V7包。现在的AS创建工程的时候,已经默认给我们导入了。
	app build.gradle
	
	dependencies {
	   ...
	    implementation 'com.android.support:appcompat-v7:27.1.1'
	}
  1. 让所有用到

    Toolbar

    的 Activity都继承

    AppCompatActivity
public class MainActivity extends AppCompatActivity {
}
  1. 设置我们应用的主题为 appcompat 里的

    NoActionBar

    主题,这样就不会使用原生的

    ActionBar

    了。我经常用的就是这个

    Theme.AppCompat.Light.NoActionBar
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
    </style>


  1. xml

    布局文件中添加

    Toolbar
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">
	<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:elevation="4dp">
    </android.support.v7.widget.Toolbar>
</LinearLayout>

Material Design 规范建议应用栏具有 4 dp 的仰角。

5. 在activity中调用

setSupportActionBar()



Toolbar

设置为 app bar,并且可以让

Toolbar

使用

ActionBar

的特性。

	//将 Toolbar设置为app bar
	setSupportActionBar(myToolbar);
	//请调用 Activity 的 getSupportActionBar() 方法。此方法将返回对 appcompat ActionBar 对象的引用。
	//获得该引用后,您就可以调用任何一个 ActionBar 方法来调整应用栏。例如,要隐藏应用栏,请调用 ActionBar.hide()。
	//ActionBar actionBar = getSupportActionBar();

看下效果

在这里插入图片描述

现在只是效果出来,然后我们开始增砖添瓦。



添加action button和overflowmenu



1创建menu文件



res/menu/

文件夹下创建

main_toolbar_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <!-- about showAsAction
           ifRoom: The action will display as a button,if there is enough room in app bar for it.
           If there is not enough room, the action will be send to the overflow menu.
           never: The action will always listed in the overflow menu.
    -->
    <item
        android:id="@+id/action_serch"
        android:icon="@android:drawable/ic_menu_search"
        android:title="one"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_call"
        android:icon="@android:drawable/ic_menu_call"
        android:title="two"
        app:showAsAction="never" />
</menu>


2设置menu.xml文件


2.1没调用setSupportAtionBar()

如果没有调用 setSupportActionBar()方法 。那么很简单直接用

Toolbar



inflateMenu()

方法。

	toolbar.inflateMenu(R.menu.main_toolbar_menu.xml);


2.2调用了setSupportActionBar()

如果调用了setSupportActionBar()方法。就是将

Toolbar

当做

ActionBar

,所以用如下方法

public class MainActivity extends AppCompatActivity{
	...
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main_toorbar_menu, menu);
        return true;
    }
}


3.响应menu点击事件


3.1没调用setSupportAtionBar()

如果没有调用

setSupportAtionBar()

我们要自己来处理menu的点击事件。

toolbar.setOnMenuItemClickListener(
        new Toolbar.OnMenuItemClickListener() {
            @Override
            public boolean onMenuItemClick(MenuItem item) {
                // Handle menu item click event
                return true;
            }
});


3.2调用了setSupportAtionBar()



Toolbar

设置为

ActionBar

,我们处理方式如下

public class MainActivity extends AppCompatActivity{
	...
 	@Override
    public boolean onOptionsItemSelected(MenuItem item) {
    	switch (item.getItemId()) {
	        case R.id.action_serch:
	            showSnackBar(item.getTitle().toString());
	            return true;
	        case R.id.action_call:
	            showSnackBar(item.getTitle().toString());
	            return true;
	        default:
	            // If we got here, the user's action was not recognized.
	            // Invoke the superclass to handle it.
	            return super.onOptionsItemSelected(item);
	    }
    }
    //弹出一个snackBar
    public void showSnackBar(String string) {
        Snackbar.make(getDecorView(), string, Snackbar.LENGTH_LONG).show();
    }
    private View getDecorView() {
        return getWindow().getDecorView();
    }
}

建议调用

setSupportActionBar()

方法,因为设置了之后,

Toolbar

才会有material design效果。

在这里插入图片描述



细节调整



1.关于返回键

在app bar 左边添加返回键图片,或者其他图片

	//使用actionbar自带的返回键图片
	ActionBar actionBar = getSupportActionBar();
	actionBar.setDisplayHomeAsUpEnabled(true);
	//使用actionbar,自定义返回键图片
	actionBar.setHomeAsUpIndicator(int redId);
	
	//使用toolbar自定义返回键图片
	toolbar.setNavigationIcon(int redId);

如果是设置了

setDisplayHomeAsUpEnable(true)

,想改变返回键图片的颜色,可以用如下方法

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <!--在主题中 设置 colorControlNomal参数即可改变,返回键的颜色-->
        <item name="colorControlNormal">@color/white</item>
    </style>
</resources>


2.关于标题
	//actioBar设置标题
	actionBar.setTitle();
	//actionBar设置子标题
	actionBar.setSubtitle();
	
	//toolbar设置标题
    toolbar.setTitle("MaterialDesign");
    //toolbar设置标题颜色
    toolbar.setTitleTextColor(Color.WHITE);
    //toolbar设置子标题
    toolbar.setSubtitle("sub title");
    //toolbar设置子标题颜色
    toolbar.setSubtitleTextColor(Color.BLACK);

设置标题的颜色和字体大小,还可以通过设置 style的方式来设置

 <!--主标题-->
<style name="ToolbarTitle" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Title">
       <item name="android:textColor">#ffffff</item>
        <item name="android:textSize">15sp</item>
</style>

 <!--子标题-->
<style name="ToolbarSubtitle" parent="@style/TextAppearance.Widget.AppCompat.Toolbar.Subtitle">
        <item name="android:textColor">#ffffff</item>
        <item name="android:textSize">10sp</item>
</style>

设置完了之后,在布局文件中给

Toolbar

设置对应的style就可以

	<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        app:subtitleTextAppearance="@style/ToolbarSubtitle"
        app:titleTextAppearance="@style/ToolbarTitle"
        android:elevation="4dp">
	</android.support.v7.widget.Toolbar>

如果感觉以上的方法设置标题比较麻烦,可以完全定义一个

TextView

当做标题。

    <android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        android:elevation="4dp">
        
        <TextView
            android:id="@+id/tvTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:text="title"
            android:textColor="#FFFFFF"
            android:textSize="18sp" />
    </android.support.v7.widget.Toolbar>

用此方式设置标题的时候要注意,如果调用了

setSupportActionBar()

方法设置了

Toolbar

,要调用如下方法来禁用使用appNamae来作为默认标题

//actionbar默认会将appName设置为标题,以下是不让actionbar的默认标题展示。我们自已定一个TextView作为标题来维护
actionBar.setDisplayShowTitleEnabled(false);


3.关于overflow menu


Toolbar

的action button 只显示图标还可以接受,而overflow menu里面的item 只显示文字有时会让你很难受。那么如何让overflow menu里的item同时显示图标和文字呢。因为系统没有暴露这个方法,我们只能通过反射的方法来解决,如下。

    @Override
    public boolean onMenuOpened(int featureId, Menu menu) {
        if (menu != null) {
            if ("MenuBuilder".equalsIgnoreCase(menu.getClass().getSimpleName())) {
                try {
                    @SuppressLint("PrivateApi")
                    Method method = menu.getClass().getDeclaredMethod("setOptionalIconsVisible", Boolean.TYPE);
                    method.setAccessible(true);
                    method.invoke(menu, true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return super.onMenuOpened(featureId, menu);
    }

细心的同学还会发现,overflow menu 点开的时候,会覆盖

Toolbar

.解决方法如下

    <!--toolbar overflow menu 下拉风格-->
    <style name="OverflowMenu" parent="Base.Widget.AppCompat.PopupMenu.Overflow">
        <!--下拉框 不是从状态栏开始,而是从toolbar底部开始-->
        <item name="overlapAnchor">false</item>
    </style>
    
 	定义好了style之后,在布局文件里面,给Toolbar设置overflow的style
	<android.support.v7.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="?attr/colorPrimary"
        app:popupTheme="@style/OverflowMenu"
        android:elevation="4dp">
	</android.support.v7.widget.Toolbar>

最后是加上了返回键,自定义了标题栏,优化了overflow menu之后的效果图

在这里插入图片描述



参考


google官方文档 add the app bar



Stack Overflow 关于toolbar.inflateMenu()方法的问题

如果错误,欢迎指正!



版权声明:本文为xy4_android原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。