1.什么是material desing
一套全新的界面设计语言,包含了视觉、运动、互动效果等特性。一言以蔽之,好看!
2.Toolbar
1.打开res/values/styles.xml文件,代码如下所示
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
定义了一个叫AppTheme的主题,然后指定它的parent主题是
Theme.AppCompat.Light.DarkActionBar。
这个DarkActionBar是一个深色的ActionBar主题,
我们之前所有的项目中自带的ActionBar就是因为指定了这个主题才出现的
现在我们准备使用Toolbar来替代ActionBar,因此需要指定一个不带ActionBar的主题,
通常有Theme.AppCompat.NoActionBar 和Theme.AppCompat.Light.NoActionBar这两种主题可选。
其中Theme.AppCompat.NoActionBar表示深色主题,它会将界面的主体颜色设成深色,陪衬颜色设成
淡色。而Theme.AppCompat.Light.NoActionBar表示淡色主题,它会将界面的主体颜色设成淡
色,陪衬颜色设成深色,因此,改成
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
属性指定颜色区域:
2.现在已经将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">
<androidx.appcompat.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>
//注意,是androidx.appcompat.widget.Toolbar,而不是android.support.v7.widget.Toolbar
3.修改mainactivity
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);
}
}
4.再学习一些Toolbar比较常用的功能吧,比如修改标题栏上显示的文字内容,在AndroidManifest.xml中指定
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="Fruits">
...
</activity>
</application>
//给activity 增加了一个android:label 属性,用于指定在Toolbar中显示的文字内容,
如果没有指定的话,会默认使用application 中指定的label 内容,也就是我们的应用名
称。
5.只有一个标题的Toolbar看起来太单调了,我们还可以再添加一些action 按钮来让Toolbar
更加丰富一些,这里我提前准备了几张图片来作为按钮的图标,将它们放在了drawable-xxhdpi目
录下。现在右击res目录→New→Directory,创建一个menu文件夹。然后右击menu文件夹
→New→Menu resource file,创建一个toolbar.xml文件
<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按钮只会显示文字
6.修改MainActivity中的代码
public class MainActivity extends AppCompatActivity {
...
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;
}
}
3.滑动菜单
1.Drawerlayout
简单介绍一下DrawerLayout的用法吧。首先它是一个布局,在布局中允许放入两个直接子
控件,第一个子控件是主屏幕中显示的内容,第二个子控件是滑动菜单中显示的内容
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.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>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:text="This is menu"
android:textSize="30sp"
android:background="#FFF" />
</androidx.drawerlayout.widget.DrawerLayout>
注意,是androidx.drawerlayout.widget.DrawerLayout,而不是 android.support.v4.widget.DrawerLayout
layout_gravity 这个属性是必须指定的,因为我们需要告诉DrawerLayout滑动菜单是在屏幕的左边还是右边,
指定left表示滑动菜单在左边,指定right表示滑动菜单在右边。
这里我指定了start,表示会根据系统语言进行判断,如果系统语言是
从左往右的,比如英语、汉语,滑动菜单就在左边,
如果系统语言是从右往左的,比如阿拉伯语,滑动菜单就在右边。
修改MainActivity中的代码
public class MainActivity extends AppCompatActivity {
private DrawerLayout mDrawerLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeAsUpIndicator(R.drawable.ic_menu);
}
}
...
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
break;
...
default:
}
return true;
}
}
首先调用findViewById() 方法得到了DrawerLayout的实例,
然后调用getSupportActionBar() 方法得到了ActionBar的实例,虽然这个ActionBar的具体
实现是由Toolbar来完成的。接着调用ActionBar的setDisplayHomeAsUpEnabled() 方法让导
航按钮显示出来,又调用了setHomeAsUpIndicator() 方法来设置一个导航按钮图标。实际
上,Toolbar最左侧的这个按钮就叫作HomeAsUp按钮,它默认的图标是一个返回的箭头,含义
是返回上一个活动。很明显,这里我们将它默认的样式和作用都进行了修改。
接下来在onOptionsItemSelected() 方法中对HomeAsUp按钮的点击事件进行处理,
HomeAsUp按钮的id永远都是android.R.id.home 。然后调用DrawerLayout的
openDrawer() 方法将滑动菜单展示出来,注意openDrawer() 方法要求传入一个Gravity
参数,为了保证这里的行为和XML中定义的一致,我们传入了GravityCompat.START 。
2.NavigationView
1.安装依赖
implementation 'com.android.support:design:29.0.2'
implementation 'de.hdodenhof:circleimageview:2.1.0'
//第一行就是Design Support库,第二行是一个开源项目
//CircleImageView,它可以用来轻松实现图片圆形化的功能,我们待会就会用到它。
//CircleImageView 的项目主页地址是:https://github.com/hdodenhof/CircleImageView
2.menu和headerLayout
menu是用来在NavigationView中显示具体的菜单项的,headerLayout则是用来在NavigationView中显示头部布局的。
3.menu
事先找了几张图片来作为按钮的图标,并将它们放在了drawable-xxhdpi目录下。然后右击menu文件→New→Menu resource file,创建一个nav_menu.xml文件
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="@+id/nav_call"
android:icon="@drawable/nav_call"
android:title="Call" />
<item
android:id="@+id/nav_friends"
android:icon="@drawable/nav_friends"
android:title="Friends" />
<item
android:id="@+id/nav_location"
android:icon="@drawable/nav_location"
android:title="Location" />
<item
android:id="@+id/nav_mail"
android:icon="@drawable/nav_mail"
android:title="Mail" />
<item
android:id="@+id/nav_task"
android:icon="@drawable/nav_task"
android:title="Tasks" />
</group>
</menu>
首先在<menu> 中嵌套了一个<group> 标签,然后将group的checkableBehavior 属性
指定为single 。group表示一个组,checkableBehavior 指定为single 表示组中的所有菜
单项只能单选。一共定义了5个item,分别使用android:id 属性指
定菜单项的id,android:icon 属性指定菜单项的图标,android:title 属性指定菜单项显
示的文字。
4.headerlayout
右击layout文件夹→New→Layout resource file,创建一个nav_header.xml文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="180dp"
android:padding="10dp"
android:background="?attr/colorPrimary">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/icon_image"
android:layout_width="70dp"
android:layout_height="70dp"
android:src="@drawable/nav_icon"
android:layout_centerInParent="true" />
<TextView
android:id="@+id/mail"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:text="110119112@gmail.com"
android:layout_centerHorizontal="true"
android:textColor="#FFF"
android:textSize="14sp" />
<TextView
android:id="@+id/username"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@id/mail"
android:text="Tang Lei"
android:layout_centerHorizontal="true"
android:textColor="#FFF"
android:textSize="14sp" />
</RelativeLayout>
5.修改activity_main.xml中的代码
<androidx.drawerlayout.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.appcompat.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