Material Design 实战 之第一弹——Toolbar详解

----

本模块共有六篇文章,参考郭神的《第一行代码》,对Material Design的学习做一个详细的笔记,大家可以一起交流一下:


写在文首,什么是Material Design?这里参考一下郭神的说法:

关于Toolbar

不过ActionBar由于其设计原因,被限定只能位于活动的顶部,从而不能实现一些Material Design的效果,因此官方现在已经不建议使用ActionBar了。

    <FrameLayout
        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.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
            app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
    </FrameLayout>

虽然这段代码不长,但是里面着实有不少技术点是需要我们去仔细琢磨一下的。

  1. 首先看一下第2行,这里使用xmlns:app指定了一个新的命名空间。 思考一下,正是由于每个布局文件都会使用xmtns:android来指定一个命名空间,因此我们才能一直使用android:id、android:layoutwidth等写法, 那么这里指定了xmtns:app,也就是说现在可以使用app:attribute这样的写法了。 但是为什么这里要指定一个xmlns:app的命名空间呢? 这是由于MaterialDesign是在Android5.0系统中才出现的,而很多的Material属性在5.0之前的系统中并不存在,那么为了能够兼容之前的老系统,我们就不能使用android:attribute这样的写法了,而是应该使用app:attribute
  2. 接下来定义了一个Toolbar控件,这个控件是由appcompat-v7库提供的。 这里我们给Toolbar指定了一个id,将它的 宽度设置为matchparent, 高度设置为actionBar的高度, 背景色设置为colorPrimary。
  3. 不过下面的部分就稍微有点难理解了, 由于我们刚才在styles.xml中将程序的主题指定成了淡色主题,因此Toolbar现在也是淡色主题(“白底(黑字)”),而TooIbar上面的各种元素就会自动使用深色主题(“(白底)黑字”),这是为了和主体颜色区别开(具体可以看文章开头对于深色浅色主题的解释)。

在styles.xml中将程序的主题指定成了淡色主题,Toolbar现在也是淡色主题,TooIbar上面的各种元素就会自动使用深色主题

  1. 但是这个效果看起来就会很差之前使用ActionBar时文字都是白色的,现在变成黑色会很难看。那么为了能让Toolbar单独(全局是用由APPTheme制定的浅色主题的,故相对而言这里用“单独”)使用深色主题,这里我们使用android:theme属性,将Toolbar的主题指定成了ThemeOverlay.AppCompat.Dark.ActionBar。
  2. 但是这样指定完了之后又会出现新的问题,如果Toolbar中有菜单按钮,那么弹出的菜单项也会变成深色主题,这样就再次变得十分难看,于是这里使用了app:popupTheme属性单独将弹出的菜单项指定成了淡色主题。
  3. 之所以使用app:popupTheme,是因为popupTheme这个属性是在Android5.0系统中新增的,我们使用app:popupTheme的话就可以兼容Android5.0以下的系统了。

小结:

  1. 为了能够兼容之前的老系统,使用app:attribute,而不是android:attribute;
  2. 在styles.xml中将程序的主题指定成了淡色主题;
  3. 使用android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"让Toolbar单独使用深色主题;
  4. 使用app:popupTheme="@style/ThemeOverlay.AppCompat.Light"单独将弹出的菜单项指定成了淡色主题;
  5. 之所以使用app:popupTheme,是因为popupTheme这个属性是在Android5.0系统中新增的,我们使用app:popupTheme的话就可以兼容Android5.0以下的系统了。
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

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

现在运行一下程序,效果如图:

接下来在学习一些Toolbar比较常用的功能,比如修改标题栏上显示的文字内容,这段文字是在AndroidManifest.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">
    <item
        android:id="@+id/backup"
        android:icon="@drawable/ic_backup"
        android:title="Backup"
        app:showAsAction="always"/>
    <item
        android:id="@+id/delete"
        android:icon="@drawable/ic_delete"
        android:title="Delete"
        app:showAsAction="ifRoom"/>
    <item
        android:id="@+id/settings"
        android:icon="@drawable/ic_settings"
        android:title="Settings"
        app:showAsAction="never"/>
</menu>
  • 可以看到,我们通过 <item>标签来定义action按钮, android:id用于指定按钮的id, android:icon用于指定按钮的图标, android:title用于指定按钮的文字。
  • 接着使用app:showAsAction来指定按钮的显示位置, 之所以这里再次使用了app命名空间,同样是为了能够兼容低版本的系统。
  • showAsAction主要有以下几种值可选: always表示永远显示在Toolbar中,如果屏幕空间不够则不显示; ifRoom表示屏幕空间足够的情况下显示在Toolbar中,不够的话就显示在菜单当中; never则表示永远显示在菜单当中。
  • 注意, Toolbar中的action按钮只会显示图标, 菜单中的action按钮只会显示文字。

接下来就是创建菜单的套路了,修改MainActivity中的代码,如下所示:

package com.example.materialtest;

import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
    }
    
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.toolbar,menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()){
            case R.id.backup:
                Toast.makeText(this,"You clicked Backup" , Toast.LENGTH_SHORT).show();
                break;
            case R.id.delete:
                Toast.makeText(this,"You clicked Delete" , Toast.LENGTH_SHORT).show();
                break;
            case R.id.settings:
                Toast.makeText(this,"You clicked Settings" , Toast.LENGTH_SHORT).show();
                break;
            default:
        }
        return true;
    }

}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏三流程序员的挣扎

Android 动画总结(8) - Activity 转场动画

从 Android 5.0 之后,可以用 ActivityOptions 来实现,ActivityOptionsCompat 是 support v4 的兼容实...

1.2K20
来自专栏移动开发面面观

React Native的列表显示

16540
来自专栏AndroidTv

关于RecyclerView你知道的不知道的都在这了(下)目录正文

28430
来自专栏郭霖

Android图片滚动,加入自动播放功能,使用自定义属性实现,霸气十足!

大家好,记得上次我带着大家一起实现了一个类似与客户端中带有的图片滚动播放器的效果,但是在做完了之后,发现忘了加入图片自动播放的功能(或许是我有意忘记加的.......

72390
来自专栏程序员叨叨叨

Android大坑集锦

这些方法有的可以,有的不行,或许跟版本有关,或许Android本身不是很支持用setImageUri从网上获取图片吧!与其煞费苦心让这个方法有效,不如用Imag...

9140
来自专栏Android Note

Android上的自定义字体 - 通过XML进行动态字体选择

14260
来自专栏Android开发小工

完全自定义样式的一句话实现RecyclerView的单选多选

今天的主题是封装RecyclerView的单选多选,现在大家应该都是用的RecyclerView开发列表数据吧。

22450
来自专栏Android 开发者

[译] 论 Android 中 Span 的正确打开方式

23550
来自专栏向治洪

React Native控件之ListView

概述 ListView作为核心组件之一,主要用于高效地显示一个可以垂直滚动的变化的数据列表。经过自定义组装,我们还可以用它实现九宫格等页面效果。 在Reac...

29570
来自专栏郭霖

Android Scroller完全解析,关于Scroller你所需知道的一切

2016大家新年好!这是今年的第一篇文章,那么应CSDN工作人员的建议,为了能给大家带来更好的阅读体验,我也是将博客换成了宽屏版。另外,作为一个对新鲜事物从来后...

28460

扫码关注云+社区

领取腾讯云代金券