Material Design 控件 (一)
Toolbar
ActionBar 由于设计的原因,被限定只能位于活动的顶部,从而不能实现一些Material Design的效果,因此官方已经不再建议使用ActionBar了。
使用Toolbar来代替ActionBar,Toolbar不仅继承了ActionBar的所有功能,而且灵活性更高,可以配合其他控件来完成Material Design的效果。
首先在创建工程的时候,我们的主题通常是 android:theme="@style/AppTheme"这个,而这个的主题是带ActionBar的,
<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>
所以在使用Toolbar代替时,应该将主题设成: android:theme="@style/AppTheme.NoActionBar",只要是NoActionBar的主题就可以。
如果这里没有设置,在用Toolbar代替时会报以下的错:
java.lang.RuntimeException: Unable to start activity ComponentInfo {com.android50materialdesign/com.android50materialdesign.ToorBarActivity}: java.lang.IllegalStateException: This Activity already has an action bar supplied by the window decor. Do not request Window.FEATURE_SUPPORT_ACTION_BAR and set windowActionBar to false in your theme to use a Toolbar instead.
新建一个Activity,那么布局中就可以直接使用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"
android:id="@+id/activity_toor_bar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<android.support.v7.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:background="@color/colorPrimaryDark"
android:layout_height="?attr/actionBarSize" />
</LinearLayout>
在这里我们可以引入xmlns:app="http://schemas.android.com/apk/res-auto"
,这这个xmlns:app命名空间上我们可以使用一些新属性。为什么不直接使用xmlns:android这个命名空间呢?因为Material Design是在Android 5.0 中才出现的,使用为了兼容老版本,我们更应该使用app命名空间下的属性。
在Activity中使用Toolbar。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toor_bar);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
//把Toolbar设置成ActionBar
setSupportActionBar(toolbar);
}
运行就如下图所示:
如普通的ActionBar是一样的。
如果要更改上面的title。可以在AndroidManifest.xml文件在修改.
<activity android:name=".ToorBarActivity"
android:theme="@style/AppTheme.NoActionBar"
android:label="Change">
那么标题就改成了Change。
同样我们可以在Toolbar上添加按钮。
右击res目录 New->Directory,创建memu文件夹。然后点击menu文件夹 New->Menu resource file 创建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/first"
android:icon="@drawable/button_emoji_press"
android:title="first"
app:showAsAction="always" />
<item
android:id="@+id/second"
android:icon="@drawable/ic_comment_love_yellow"
android:title="second"
app:showAsAction="ifRoom" />
<item
android:id="@+id/third"
android:icon="@drawable/button_mic_press"
android:title="third"
app:showAsAction="never" />
</menu>
在代码中有这个 app:showAsAction="" . 这个用于指定按钮显示的位置的。使用app命名也是为了兼容旧版本。
showAsAction有以下属性(通常使用的为以下三个)
- always :表示永远显示在Toolbar上,如果屏幕空间不够则不显示。
- ifRoom :表示屏幕空间足够的情况下显示在Toolbar上,如果不够就显示在菜单上
- never :永远显示在菜单上
设置了菜单后就要让Toolbar应用上。
在Activity上编写
@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.first:
Toast.makeText(ToorBarActivity.this,"first",Toast.LENGTH_SHORT).show();
break;
case R.id.second:
Toast.makeText(ToorBarActivity.this,"second",Toast.LENGTH_SHORT).show();
break;
case R.id.third:
Toast.makeText(ToorBarActivity.this,"third",Toast.LENGTH_SHORT).show();
break;
}
return true ;
}
效果如下(上面已经修改了标题为Change)
DrawerLayout
我们常见的菜单。
DrawerLayout是一个布局,在布局中允许放入两个直接子控件,第一个控件是主屏幕中显示的内容,第二个是滑动菜单中显示的内容。
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/activity_dawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="主\n页\n面"
android:textSize="150sp" />
<Button
android:id="@+id/btn_open"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_alignParentTop="true"
android:layout_marginStart="20dp"
android:layout_marginTop="21dp"
android:text="打开菜单" />
</RelativeLayout>
<TextView
android:id="@+id/tv"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="left"
android:background="#00FF00"
android:gravity="center"
android:text="菜\n单"
android:textSize="150sp" />
</android.support.v4.widget.DrawerLayout>
注意的是:第二个子控件 android:layout_gravity="" 这个属性必须指定。
这个实现是告诉DraweLayout滑动菜单是在屏幕的左边还是右边。
- left :屏幕的左边
- right :屏幕的右边
- start :根据系统的语言来选择,如果系统的语言是从左往右的,就在左边滑出。反之...
可以用代码控制菜单的打开与关闭
private DrawerLayout dl;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dawer_layout);
dl = (DrawerLayout) findViewById(R.id.activity_dawer_layout);
Button btnOpen = (Button) findViewById(R.id.btn_open);
TextView tv = (TextView) findViewById(R.id.tv);
btnOpen.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//打开菜单
dl.openDrawer(GravityCompat.START);
}
});
tv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//关闭菜单
dl.closeDrawers();
}
}
);
}
NavigationView
NavigationView是Design Support 库中提供的一个控件。他严格按照了Material Design 的要求来进行设计。
-
要使用它首先要添加依赖:
compile 'com.android.support:design:23.4.0' -
右击res目录 New->Directory,创建memu文件夹。然后点击menu文件夹 New->Menu resource file 创建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"> <item android:id="@+id/first" android:icon="@drawable/ic_comment_love_yellow" android:title="first" /> <item android:id="@+id/second" android:icon="@drawable/ic_comment_love_yellow" android:title="second" /> <item android:id="@+id/third" android:icon="@drawable/ic_comment_love_yellow" android:title="third" /> </menu>
-
编写headlayout:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:orientation="vertical"> <ImageView android:layout_width="50dp" android:layout_height="50dp" android:src="@color/colorAccent" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="菜单" android:textSize="25sp" /> </LinearLayout>
-
把NavigationView设置成菜单
<android.support.design.widget.NavigationView android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="left" android:background="#00FF00" app:menu="@menu/menu" app:headerLayout="@layout/headlayout" />
同样放置在drawerlayout中。 app:menu="@menu/menu"、app:headerLayout="@layout/headlayout"引入了刚刚的所写的菜单和布局。
可以用以下代码对NavigationView中的item进行操作:
NavigationView nv = (NavigationView) findViewById(R.id.nv);
nv.setNavigationItemSelectedListener(new
NavigationView.OnNavigationItemSelectedListener() {
@Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.first:
//处理点击事件
..........
break;
...........
}
return true;
}
});
效果如下:
FloatingActionButton
这个控件可以是我们轻松的实现悬浮按钮的效果。
<android.support.design.widget.FloatingActionButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_comment_love_yellow"
app:elevation="4dp"
android:layout_centerInParent="true"/>
app:elevation="4dp":高度值,高度值越大,投影范围越大,但是投影效果越淡;高度值越小,投影范围越小,但是投影效果越浓。
添加点击事件(与普通的按钮是一样的):
FloatingActionButton btn = (FloatingActionButton) findViewById(R.id.btn);
btn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Toast.makeText(FloatingActionButtonActivity.this,"点击",Toast.LENGTH_SHORT).show();
}
});