Android常用UI之Toolbar

时间:2023-01-20 18:46:31

Android常用UI之Toolbar

标签: androiduiToolbar 7437人阅读 评论(3) 收藏 举报 本文章已收录于: Android常用UI之Toolbar Android知识库 Android常用UI之Toolbar 分类:

目录(?)[+]

转载请注明出处:http://blog.csdn.net/h_zhang/article/details/51232773

Android3.0之后引入了ActionBar控件,但是由于ActionBar操作的诸多不便,并且官方也在一定程度上承认ActionBar限制了Android app设计与开发的弹性。所以google官方建议使用Toolbar代替ActionBar,Toolbar比ActionBar使用起来更加灵活。而在material design中也对其做了名称的定义:app bar。

app bar可以向用户提供非常熟悉的可视化结构和交互元素。使用app bar可以让用户快速了解怎样使用你的应用,这就给用户一个很好的体验。 
应用程序中使用app bar可有如下优点: 
1. 可以显示出用户所处的当前位置; 
2. 可以提供一些重要的交互操作,比如搜索(search)操作; 
3. 可以实现导航功能,让用户快速回到Home Activity;

本文就主要介绍一下Android Toolbar的使用方法。


设置Toolbar

即使再简单的Toolbar也应该具有两个元素,左边显示activity的标题,右边显示一个overflow菜单。为了让android 5.0以前也能使用Toolbar,我们得使用support v7包中的Toolbar来为activity设置toolbar。 
设置Toolbar需要注意一下两点: 
1. 你的Activity需要继承自AppCompatActivity 
2. 你得先定义一个NoActionBar的主题,并让你的应用程序使用这个主题。这样做的目的是阻止你的应用程序使用本地ActionBar的功能。

下面贴一个示例程序: 
首先看样式定义文件,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>

<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>

<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>

<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>

</resources>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

主要就是定义了一些主题,其中主题AppTheme中colorPrimary属性就指定了Toolbar的底色。colorPrimaryDark属性指定顶部状态栏的颜色。

接下来在activity布局文件中加上Toolbar的布局。 
activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="cn.hebut.toolbar2.MainActivity">


<LinearLayout
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:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:theme="@style/AppTheme.AppBarOverlay"
app:title="首页"
app:logo="@mipmap/ic_launcher"
app:popupTheme="@style/AppTheme.PopupOverlay"/>


<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"/>


</LinearLayout>

</android.support.design.widget.CoordinatorLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

利用android.support.v7.widget.Toolbar定义了Toolbar的布局。通过app:title属性设置Toolbar的标题,通过app:logo属性设置Toolbar的图标。还可以通过app:titleTextColor属性设置标题文字颜色等等。

接着再看MainActivity.Java中用代码如何设置Toolbar:

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.menu_main, menu);

return true;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

代码相当简单,通过setSupportActionBar()方法将布局文件中的Toolbar设置进去就可以了。

在menu_main.xml布局文件中添加action按钮。 
menu_main.xml :

<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="cn.hebut.toolbar2.MainActivity">


<item
android:id="@+id/action_setting"
android:icon="@mipmap/ic_settings"
android:title="设置"
app:showAsAction="never"/>


</menu>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

action按钮通过item标签设置。其中icon属性指定action按钮的图标,如果anction按钮在Toolbar中显示就显示该图标;title属性指定action按钮的名称,如果anction按钮在overflow中显示就显示title。注意,在overflow按钮中,系统默认只显示title,而不显示icon;最后showAsAction属性设置为”never”,表示该action按钮只在overflow按钮中显示,showAsAction属性还可以指定为ifRoom,ifRoom表示如果Toolbar中有空间,就在Toolbar中显示,如果Toolbar中没有足够的空间,就在overflow中显示。

下面是manifest文件:

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme.NoActionBar">

<activity
android:name=".MainActivity"
android:label="@string/app_name">

<intent-filter>
<action android:name="android.intent.action.MAIN"/>

<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

第6行,设置app的样式为AppTheme.NoActionBar,这样应用程序就可以阻止使用系统自带的ActionBar。

运行程序,得到如下效果: 


Android常用UI之Toolbar 

上图中最右边的三个点就是overflow按钮。点击overflow会发现里面有个title为”设置”的action按钮。


响应action按钮点击事件

在menu_main.xml文件中添加几个action按钮; 
menu_main.xml

<item
android:id="@+id/action_search"
android:icon="@mipmap/ic_search"
android:title="搜索"
app:showAsAction="ifRoom"/>

<item
android:id="@+id/action_add"
android:icon="@mipmap/ic_add"
android:title="添加"
app:showAsAction="ifRoom"/>

<item
android:id="@+id/action_setting"
android:icon="@mipmap/ic_settings"
android:title="设置"
app:showAsAction="never"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

action按钮的事件响应主要在Activity中的onOptionsItemSelected()方法中实现,具体代码如下。 
MainActivity.java :

public boolean onOptionsItemSelected(MenuItem item)
{
switch (item.getItemId())
{
case R.id.action_search:
Toast.makeText(MainActivity.this, "搜索", Toast.LENGTH_SHORT).show();
break;
case R.id.action_add:
Toast.makeText(MainActivity.this, "添加", Toast.LENGTH_SHORT).show();
break;
case R.id.action_setting:
Toast.makeText(MainActivity.this, "设置", Toast.LENGTH_SHORT).show();
break;
}

return super.onOptionsItemSelected(item);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

程序运行效果图: 


Android常用UI之Toolbar 


添加导航按钮

导航按钮可以让用户很容易的返回app的主界面,这就能够产生非常好的用户体验。给Toolbar添加导航按钮功能也是非常简单的,通过如下两步即可: 
1. 在manifest文件中通过android:parentActivityName属性为Activity配置parent activity 
2. 在代码中通过ActionBar.setDisplayHomeAsUpEnabled(true)方法使能导航按钮

下面我们就来实现一下,先做一些准备工作。在首页增加一个按钮; 
activity_main.xml :

 <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/AppTheme.AppBarOverlay"
app:title="首页"
app:logo="@mipmap/ic_launcher"
app:popupTheme="@style/AppTheme.PopupOverlay"/>


<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"/>


<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="child activity"
android:onClick="start"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

相当简单,就是增加了一个Button按钮,点击button执行start()方法。 
MainActivity.java :

public void start(View view)
{
Intent i = new Intent(this, ChildActivity.class);
startActivity(i);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

start()方法启动了一个child activity。 
ChildActivity.java :

public class ChildActivity extends AppCompatActivity
{


@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_child);
Toolbar toolbar = (Toolbar) findViewById(R.id.child_toolbar);
setSupportActionBar(toolbar);
ActionBar ab = getSupportActionBar();

//使能app bar的导航功能
ab.setDisplayHomeAsUpEnabled(true);
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
return super.onOptionsItemSelected(item);
}

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

第11行,通过getSupportActionBar()方法得到ActionBar实例;第14行,调用ActionBar的setDisplayHomeAsUpEnabled()使能导航功能。

接下来看一下child activity的布局文件

<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="cn.hebut.toolbar3.MainActivity">


<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">


<android.support.v7.widget.Toolbar
android:id="@+id/child_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
android:elevation="4dp"
android:theme="@style/AppTheme.AppBarOverlay"
app:title="childActivity"
app:logo="@mipmap/ic_launcher"
app:popupTheme="@style/AppTheme.PopupOverlay"/>


<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="this is child activity!"
android:textSize="22sp"/>


</LinearLayout>

</android.support.design.widget.CoordinatorLayout>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

没什么好说的。最后,在manifest文件中为ChildActivity指定parent Activity。

<activity
android:name=".ChildActivity"
android:label="@string/title_activity_child"
android:parentActivityName=".MainActivity">


<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity"/>

</activity>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

通过android:parentActivityName属性指定ChildActivity的parent Activity。注意:meta-data标签是为了兼容android 4.0或者更小的版本。

程序运行效果图: 


Android常用UI之Toolbar 

最后需要注意一点:你不需要对导航按钮的点击事件做出响应。因为点击导航按钮的响应事件,父类已经已经实现好了,你只需要调用父类方法即可。代码如下:

public boolean onOptionsItemSelected(MenuItem item)
{
return super.onOptionsItemSelected(item);
}
  • 1
  • 2
  • 3
  • 4
  • 1
  • 2
  • 3
  • 4

添加Action View

Action View和Action按钮大致类似,都是为了通过Toolbar和用户进行交互操作。不过Action View提供了更加丰富的功能。举个例子:一个搜索功能的Action View可以让用户实现搜索操作,并且这个操作就在Toolbar中完成,而不需要切换activity或者fragment。support v7包中提供了很多现成的Action View,其中就包括SearchView,用来实现搜索功能。下面我们来实现一下。

添加一个Action View只需要在menu_main.xml中为item标签添加actionViewClass属性即可。 
menu_main.xml:

<item
android:id="@+id/action_search"
android:icon="@mipmap/ic_search"
android:title="搜索"
app:showAsAction="ifRoom|collapseActionView"
app:actionViewClass="android.support.v7.widget.SearchView"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

actionViewClass属性指定为support v7包下SearchView;showAsAction指定为ifRoom|collapseActionView,其中collapseActionView表示:如果用户没有和action view交互,该Action view该如何在Toolbar中显示。

下面贴一下效果: 


Android常用UI之Toolbar 

可以看到,如果用户不点击Action View,Action View将会和普通Action按钮一样;如果用户点了Action View的icon,Action View将会展开填充整个Toolbar。

你还可以在代码中对SearchView的属性就行配置,这些工作主要在Activity的onCreateOptionsMenu()方法中实现。

public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.menu_main, menu);

MenuItem searchItem = menu.findItem(R.id.action_search);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
//配置searchView...

return true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

有的时候应用程序需要在Action View展开与合并的时候显示不同的界面。这时程序就可以对Action View的展开与合并进行监听。

public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.menu_main, menu);

MenuItem searchItem = menu.findItem(R.id.action_search);

//定义一个监听器
OnActionExpandListener expandListener = new OnActionExpandListener()
{
@Override
public boolean onMenuItemActionExpand(MenuItem item)
{
Toast.makeText(MainActivity.this, "expand", Toast.LENGTH_SHORT).show();
return true;
}

@Override
public boolean onMenuItemActionCollapse(MenuItem item)
{
Toast.makeText(MainActivity.this, "collapse", Toast.LENGTH_SHORT).show();
return true;
}
};

//设置监听器
MenuItemCompat.setOnActionExpandListener(searchItem, expandListener);

return true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

下面给个效果图: 


Android常用UI之Toolbar 


添加Action Provider

Action Provider的功能就更加丰富了,Action Provider可以使用自定义布局。一个Action Provider初始状态也和Action按钮相似,可以显示在Toolbar中,也可以显示在Overflow按钮中。当用户点击Action Provider,用户可以按照自己想要的方式控制点击的响应事件。比如说,点击Action Provider后,用户可以展示一个子菜单。

下面我们自定义一个简单的Action Provider用于展示子菜单功能。

使用Action Provider很简单,只需要在menu资源文件中的item标签设置app:actionProviderClass属性即可:

menu_main.xml:

<item
android:id="@+id/action_add"
android:icon="@mipmap/ic_add"
android:title="添加"
app:showAsAction="ifRoom"
app:actionProviderClass="cn.hebut.toolbar2.MyActionProvider"/>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

可以看到actionProviderClass设置了一个自定义的MyActionProvider。下面我们来看如果自定义ActionProvider:

public class MyActionProvider extends ActionProvider
{

public MyActionProvider(Context context)
{
super(context);
}

@Override
public View onCreateActionView()
{
return null;
}

@Override
public void onPrepareSubMenu(SubMenu subMenu)
{
subMenu.clear();

subMenu.add("sub item 1")
.setIcon(R.mipmap.ic_launcher)
.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener()
{
@Override
public boolean onMenuItemClick(MenuItem item)
{
return true;
}
});
subMenu.add("sub item 2")
.setIcon(R.mipmap.ic_launcher)
.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener()
{
@Override
public boolean onMenuItemClick(MenuItem item)
{
return true;
}
});
}

@Override
public boolean hasSubMenu()
{
return true;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46

我们定义了MyActionProvider类并继承ActionProvider。为了表示这个Action Provider有子菜单,需要重写hasSubMenu()方法并返回true。然后在onPrepareSubMenu()方法中通过SubMenu的add()方法添加子菜单。

好,最后我们看一下自定义ActionProvider的执行效果图: 


Android常用UI之Toolbar 

可以发现,这个自定义ActionProvier的功能和overflow很相似。


OK,关于Android的Toolbar的使用用法就说这么多,相信通过对本篇文章的学习,大家基本能掌握Toolbar的使用方法了。

参考文章: 
Android Developers: http://developer.android.com/intl/zh-cn/training/appbar/index.html 
郭霖大神的文章:http://blog.csdn.net/guolin_blog/article/details/18234477