写在文首,什么是Material Design?这儿参考一下郭神的说法:
####文章提要与总结
1. 关于android:theme的详细理解(附图);
(运用:运用Toolbar代替ActionBar时,须将Theme.AppCompat.Light.DarkActionBar改成Theme.AppCompat.Light.NoActionBar)
2. 在activity_main.xml中运用Toolbar代替ActionBar;
关于命名空间:android app;
关于Toolbar控件的特点;
尤其android:theme以及app:popupTheme的用法理解;
3. 关于activity.android:label;
4. 经过Menu resource file菜单文件式(一起为xml格式)来为Toolbar添加action按钮;
文件中:
<item>标签来界说action按钮,
android:id用于指定按钮的id,
android:icon用于指定按钮的图标,
android:title用于指定按钮的文字;
运用app:showAsAction来指定按钮的显现方位,再次运用了app命名空间,相同是为了能够兼容低版本的体系;
showAsAction的几种选值:always ifRoom never
留意,
Toolbar中的action按钮只会显现图标,
菜单中的action按钮只会显现文字;
5. onCreateOptionsMenu()加载描述Toolbar的action按钮的Menu resource file;
onOptionsItemSelected()办法中处理各个按钮的点击事情;
作用图:
#正文
####关于Toolbar
Toolbar相关于ActionBar;
不过ActionBar因为其规划原因,被限定只能位于活动的顶部,从而不能完成一些Material Design的作用,因而官方现在已经不建议
运用ActionBar了。
首要要知道,任何一个新建的项目默许都是会显现ActionBar的。 ActionBar是依据项目中指定的主题来显现, 翻开AndroidManifest.xml文件:
能够看到这儿用android:theme指定了一个AppTheme的主题。 翻开res/values/styles.xml文件能够检查其界说出处:
这儿界说了一个叫AppTheme的主题并指定它的parent主题是Theme.AppCompat.Light.DarkActionBar。 DarkActionBar是一个深色的ActionBar主题,所有的新建项目中自带的ActionBar便是因为指定了这个主题才呈现的。
要运用TooIbar来代替ActionBar时需要指定一个不带ActionBar的主题, 对应的一般有Theme.AppCompat.NoActionBar和Theme.AppCompat.Light.NoActionBar这两种主题可选; 其中:
- Theme.AppCompat.NoActionBar表明深色主题,它会将界面的主体色彩设成深色,烘托色彩设成淡色;
- Theme.AppCompat.Light.NoActionBar表明淡色主题,它会将界面的主体色彩设成淡色,烘托色彩设成深色。
详细能够依据状况去设置,这儿首要选用淡色主题,如下所示:
调查代码中AppTheme中的特点重写: 可见这儿重写了colorPrimary、colorPrimaryDark和colorAccent这3个特点的色彩。 特点指定色彩称号对应的方位,如图:
可见除了上述3个特点之外,咱们还能够经过textColorPrimary、windowBackground和navigationBarCotor等特点来操控更多方位的色彩。 不过colorAccent这个特点比较特别,它不仅仅用来指定这样一个按钮的色彩,而是更多表达了一个着重的意思,比方一些控件的选中状况也会运用colorAccent的色彩。
至此已将ActionBar隐藏,接下来运用Toolbar来代替ActionBar。 修正activity_main.xml:
<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>
下面解析一下这段代码:
- 首要看一下第2行,这儿运用xmlns:app指定了一个新的命名空间。 正是因为每个布局文件都会运用xmlns:android来指定一个命名空间,因而咱们才干一向运用android:id、android:layoutwidth等写法, 这儿指定了xmlns:app,现在便能够运用app:attribute这样的写法了。
可是为什么这儿要指定一个xmlns:app的命名空间呢? 这是因为MaterialDesign是在Android5.0体系中才呈现的,而很多的Material特点在5.0之前的体系中并不存在,那么为了能够兼容之前的老体系,咱们就不能运用android:attribute这样的写法了,
而是应该运用app:attribute
-
接下来
界说了一个Toolbar控件
,这个控件是由appcompat-v7库供给的。 这儿咱们给Toolbar指定了一个id,将它的 宽度设置为matchparent, 高度设置为actionBar的高度, 背景色设置为colorPrimary。 -
接下来,关于主题: 因为咱们刚才
在styles.xml中将程序的主题指定成了淡色主题
,因而Toolbar现在也是淡色主题
(“蓝底(黑字)”),而TooIbar上面的各种元素就会主动运用深色主题
(“(黑底)X字”),这是为了和主体色彩区别开(详细能够看文章开头对于深色淡色主题的解释)。 -
可是这个作用看起来就会很差
,之前
运用ActionBar时文字都是白色
的,现在变成黑色
的会很丑陋
。那么为了能让Toolbar独自(大局是用由APPTheme拟定的淡色主题的,故相对而言这儿用“独自”)运用深色主题
,这儿咱们运用android:theme
特点,将Toolbar的主题指定成了ThemeOverlay.AppCompat.Dark.ActionBar。
-
可是这样指定完了之后又会呈现新的问题,假如Toolbar中有菜单按钮,那么弹出的菜单项也会变成深色主题,这样就
再次变得非常丑陋
,于是这儿运用了app:popupTheme特点独自将弹出的菜单项指定成了淡色主题。
-
之所以运用app:popupTheme,是因为popupTheme这个特点是在Android5.0体系中新增的,咱们运用app:popupTheme的话就能够兼容Android5.0以下的体系了。
小结:
- 为了能够兼容之前的老体系,运用
app:attribute
,而不是android:attribute
;- 在styles.xml中将程序的主题指定成了淡色主题;
- 运用
android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
让Toolbar独自运用深色主题;- 运用
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
独自将弹出的菜单项指定成了淡色主题;- 之所以运用app:popupTheme,是因为popupTheme这个特点是在Android5.0体系中新增的,咱们运用app:popupTheme的话就能够兼容Android5.0以下的体系了。
**接下来修正MainActivity:**
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
}
这儿, 首要用findViewByid()得到Toolbar的实例, 然后调用setSupportActionBar()办法一起传入Toolbar的实例, 至此便完成了既运用Toolbar,又让它的外观与功用都同ActionBar一致。
现在运转一下程序,作用如图:
>**这个标题栏虽然看上去和之前的没什么两样,但其实它已经是Toolbar而不是ActionBar了,它现在也具备了完成MaterialDesign作用的能力。**
**接着实战一些Toolbar比较常用的功用,比方修正标题栏上显现的文字内容, 这段文字是在AndroidManifest.xml中指定的,如下所示:** ![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9bbb51ac44204aac8683e836e4345256~tplv-k3u1fbpfcp-zoom-1.image)
这儿给activity增加了一个android:label特点,用于指定在Toolbar中显现的文字内容, 假如没有指定的话,会默许运用application中指定的label内容,也便是咱们的运用称号。
接下来再添加一些action按钮来丰厚Toolbar: 先预备了几张图片来作为按钮的图标,将它们放在了drawable-xxhdpi目录下; 右击res目录→New→Directory,创立一个menu文件夹; 右击menu文件夹→New→Menuresourcefile,创立一个toolbar.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>
-
能够看到,咱们经过 标签来界说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;
}
}
上述代码: 在onCreate0ptionsMenu()中加载toolbar.xml这个菜单文件, 在onOptionsItemSelected()中处理各个按钮的点击事情。 从头运转一下程序,作用如图:
可见Toolbar上面现在显现了两个action按钮,这是因为 Backup按钮指定的显现方位是alway, Delete按钮指定的显现方位是ifRoom,而现在屏幕空间足够。因而两个按钮都会显现在Toolbar中。 Settings按钮则因为指定的显现方位是never,所以显现在菜单中(点击最右边的三个小点即知)。
一起留意这些action按钮都是能够响应点击事情的!