Material Design概述
Material Design是Google在Android 5.0推出的全新的设计语言,它是由Google工程师们基于传统优秀的设计原则并且结合丰富的创意以及科技所组成的。Material Design的核心思想,就是将物理世界中的体验带入屏幕,并且去掉物理世界中的杂质,再配合虚拟世界的灵活特性,达到最贴近真实的体验。
使用Material Design能够大幅度的增加我们程序的界面的美观度和与用户的交互性,所以在Android进阶的第一章就来学习一下Material Design中几个常用的控件吧!
Toolbar
Toolbar简单来说就是一个可以编辑的ActionBar。ActionBar就是简单来说就是每个活动最上面的那个标题栏,我们之前在初步学习Android的时候所建立的布局使用的都是ActionBar。由于ActionBar被其自身的设计原因所限制,所以我们很难在它身上做“手脚”,因此在Material Design中就引入了Toolbar。
如果我们要使用Toolbar,那么第一步要做的就是将系统默认的ActionBar给替换掉。我们新建一个项目,然后打开res—values—styles.xml,会看到显示如下内容:
这里我们着重看到
我们将主题修改为浅色的不带ActionBar。接着我们看到这个里面的其他属性,这些属性所代表的意思我们可以用一张图来解释:
接着我们就可以在布局中将Toolbar添加进去了:
首先是在开头我们定义了一个xmlns:app命名空间,有了它我们就可以在后面的属性中使用app这个空间了,这样做的好处就是能够让 Material Design兼容低系统的手机。接着就是添加Toolbar这个控件了,这里面的属性设置我们可能之前从来没有遇到过,所以这里来分别的解释一下:
- android:layout_height="?attr/actionBarSize"
在设置控件的高度时我们传入的值是?attr/actionBarSize
,它的意思是指我们让Toolbar的宽度和原来的ActionBar的宽度保持一致。 - android:background="?attr/colorPrimary"
在设置控件的背景颜色时我们传入的参数是?attr/colorPrimary
,它的意思是我们的颜色要和colorPrimary的颜色保持一致。 - android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar"
这个属性是用来设置我们控件的主题的,在这里我们使用的是深色ActionBar主题。 - app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
在这里我们使用了app的命名空间,这个属性主要是用来设置我们Toolbar中的菜单项的颜色主题的。
上面这些完成之后,我们就成功的将ActionBar替换成了Toolbar了,接下来就可以来为Toolbar添加功能了。我们先来在它的右上角添加几个按钮和菜单。我们点击res—new—Diectory来创建一个menu,接着在menu下新建一个Menu resource,然后修改代码:
我们还是先在开始添加了app的命名空间,然后就是为menu添加控件,这里面的属性我们大多数都是见过的,只有app:showAsAction
这一项,它的意思是指控件是否展示出来,一般都是有三个参数可以选择:always(一直都展示出来)、ifRoom (如果有位置就展示出来,没有位置就放在折叠栏里面)和never(一直放在折叠栏里面不展示出来),需要注意的时如果使用的never则我们为它设置的背景图片是无法再折叠栏中展示出来的。
接着我们修改主代码,将menu加载进布局:
package com.example.yzbkaka.toolbartest;
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); //启用Toolbar
}
public boolean onCreateOptionsMenu(Menu menu){ //加载menu
getMenuInflater().inflate(R.menu.toolbar,menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item){ //menu子项的点击事件
switch (item.getItemId()){
case R.id.backup:
Toast.makeText(this, "backup", Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(this, "delete", Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this, "setting", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return true;
}
}
我们先是使用了setSupportActionBar()的方法来将Toolbar启用,接着就是重写onCreateOptionsMenu()和onOptionsItemSelected()方法来分别将menu加载进来和为menu中的子项添加点击时间。
滑动菜单
滑动菜单在我们现在使用的大多数app里面都可以见到,它就是在程序的界面中用手指在靠近屏幕左边的地方向右滑动即可出现一个菜单栏,在这个菜单栏中我们可以添加点击事件和图片等控件。
我们在布局中修改代码:
我们在这里使用的是DrawerLayout这个布局的排列方式,这个布局是允许我们放入两个直接的子控件的:第一个子控件就是在主屏幕中显示的内容;第二个子控件就是我们滑动菜单的内容了。这里我们是将TextView添加到滑动菜单中,主要在设置第二个子控件时我们必须要设置android:layout_gravity
这个属性,它是来设置菜单是从左向右滑动还是从右向左滑动出现的,left表示菜单在屏幕的左边,right表示菜单在屏幕的右边,而start则是系统自动进行判断。
接下来来我们就来对滑动菜单中添加控件。Android官方推荐我们使用Navigation-View来对滑动菜单进行编辑,它是由Design Support库中提供的,因此我们需要先为我们的程序添加依赖,在dependencise闭包中添加:
implementation 'com.android.support:design:26.1.0'
然后我们来对滑动菜单进行修改吧!具体的规划是在滑动菜单的上部添加一张图片,而在下部就是添加相应menu以及点击事件。我们先从上部开始,在layout—new—Layout resource中新建一个nav_header.xml的布局,然后修改代码:
我们将header的宽度设置为match_parent
,而高度设置为180dp,这是对于header来说比较合适的设置。然后在背景上我是选择了一张bing的背景图片,并且让它的四周有着10dp的留白。
接着就是来为滑动菜单添加menu了,我们在menu文件夹中新建一个目录,然后是修改代码:
我们在这里是添加几个简单的子项。接着是修改主布局:
在滑动菜单栏的那一项布局当中,我们使用app:menu
和app:headerLayout
属性将我们之前创建好的布局给添加了进去。最后就是修改主代码了:
package com.example.yzbkaka.toolbartest;
import android.support.design.widget.NavigationView;
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);
NavigationView navigationView = (NavigationView)findViewById(R.id.nav_view); //获取实例
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() { //设置监听
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.name:
Toast.makeText(MainActivity.this, "name", Toast.LENGTH_SHORT).show();
break;
case R.id.call:
Toast.makeText(MainActivity.this, "call", Toast.LENGTH_SHORT).show();
break;
case R.id.email:
Toast.makeText(MainActivity.this, "email", Toast.LENGTH_SHORT).show();
break;
case R.id.age:
Toast.makeText(MainActivity.this, "age", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
});
}
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, "backup", Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(this, "delete", Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this, "setting", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return true;
}
}
我们先是获取到NavigationView的实例,然后就是使用setNavigationItemSelected-Listener()为该实例添加监听和相应的点击事件。
现在我们就将滑动菜单给设置好了,但是还会存在这样一种情况,即用户可能不知道我们的程序存在一个滑动菜单,因此我们最后再来在左上角设置一个按钮,当点击之后能够自动的将滑动菜单显示出来。我们直接修改主代码:
package com.example.yzbkaka.toolbartest;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
private DrawerLayout drawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar)findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
NavigationView navigationView = (NavigationView)findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.name:
Toast.makeText(MainActivity.this, "name", Toast.LENGTH_SHORT).show();
break;
case R.id.call:
Toast.makeText(MainActivity.this, "call", Toast.LENGTH_SHORT).show();
break;
case R.id.email:
Toast.makeText(MainActivity.this, "email", Toast.LENGTH_SHORT).show();
break;
case R.id.age:
Toast.makeText(MainActivity.this, "age", Toast.LENGTH_SHORT).show();
break;
}
return true;
}
});
drawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout); //获取实例
ActionBar actionBar = getSupportActionBar();
if(actionBar != null){
actionBar.setDisplayHomeAsUpEnabled(true); //让按钮显示出来
}
}
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, "backup", Toast.LENGTH_SHORT).show();
break;
case R.id.delete:
Toast.makeText(this, "delete", Toast.LENGTH_SHORT).show();
break;
case R.id.settings:
Toast.makeText(this, "setting", Toast.LENGTH_SHORT).show();
break;
case android.R.id.home: //添加点击事件
drawerLayout.openDrawer(GravityCompat.START);
break;
default:
break;
}
return true;
}
}
我们在这里先是获取到了DrawerLayout实例,然后是得到一个ActionBar的对象,并且使用该对象的setDisplayHomeAsUpEnabled()方法来让导航按钮显示出来,最后就是为该按钮添加点击事件了,我们这里是使用openDrawer()方法来打开滑动菜单的,在这里需要注意的是导航按钮相当于是系统内置的,因此它的id永远是android.R.id.home
。
悬浮按钮
我们接着来修改我们的界面。有的时候我们使用新闻类APP时,当我们往下浏览新闻时在我们的屏幕右下角会出现一个圆形的按钮,我们可以点击它之后马上回到APP的顶端进行刷新。这样一个按钮就是悬浮按钮。
悬浮按钮的添加方法也是非常简单的,我们先修改主布局代码:
......
......
我们直接在之前的项目中的android:layout_gravity="bottom|end"
的意思是指将这个控件放在屏幕的右下角。android:layout_margin="16dp"
则是来设置控件距离屏幕四周的间距的。
接着我们来修改主代码,给悬浮按钮添加点击事件:
......
FloatingActionButton floatingActionButton = (FloatingActionButton)findViewById(R.id.float_action_button);
floatingActionButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Toast.makeText(MainActivity.this, "folatingActionButton", Toast.LENGTH_SHORT).show();
}
});
......
悬浮按钮的点击方法也是很简单的,与普通按钮的设置方法是一样的,这里我们就是简单的设置一段短消息提醒即可。
OK,到这里我们就使用Material Design编写出了一个漂亮的界面了,但是Material Design中的控件远不止这么一点,所以如果想要了解更多的知识和控件的话,可以访问Material Design官方介绍。