Toolbar
Toolbar与ActionBar最大的区别就是Toolbar更加自由、可控。这也是Google在逐渐使用Toolbar替换ActionBar的原因,要使用Toolbar必须引入appcompat-v7支持,并设置主题为NoActionBar,因此在styles.xml文件中,使用如下所示代码进行设置。
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<!-- toolbar颜色 -->
<item name="colorPrimary">@color/colorPrimary</item>
<!-- 状态栏颜色 -->
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<!-- 窗口的背景颜色 -->
<item name="android:windowBackground">@android:color/white</item>
<!-- SearchView -->
<item name="searchViewStyle">@style/MySearchView</item>
</style>
<style name="MySearchView" parent="Widget.AppCompat.SearchView"/>
菜单配置与ActionBar基本类似,代码如下所示:
<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=".MainActivity" >
<item
android:id="@+id/ab_search"
android:orderInCategory="80"
android:title="action_search"
app:actionViewClass="android.support.v7.widget.SearchView"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_share"
android:orderInCategory="90"
android:title="action_share"
app:actionProviderClass="android.support.v7.widget.ShareActionProvider"
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="action_settings"
app:showAsAction="never"/>
</menu>
下面演示Toolbar与DrawerLayout结合使用的例子:
Activity:
public class ToolbarActivity extends AppCompatActivity {
private Toolbar mToolbar;
private ShareActionProvider mShareActionProvider;
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mDrawerToggle;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_toolbar);
mToolbar = (Toolbar) findViewById(R.id.toolbar);
// 添加标题和图标
mToolbar.setLogo(R.mipmap.ic_launcher);
// 标题的文字需在setSupportActionBar之前,不然会无效
mToolbar.setTitle("主标题");
mToolbar.setSubtitle("副标题");
setSupportActionBar(mToolbar);
// 将Toolbar与DrawerLayout结合起来,实现android 5.X 中DrawerToggle状态变化的动态效果,
// 即最左边的Toggle在DrawerLayout滑动时,会从三条横线间变成一个箭头状的图案。
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
mDrawerToggle = new ActionBarDrawerToggle(
this, mDrawerLayout, mToolbar,
R.string.abc_action_bar_home_description,
R.string.abc_action_bar_home_description_format);
mDrawerToggle.syncState();
mDrawerLayout.setDrawerListener(mDrawerToggle);
// 菜单的监听可以在toolbar里设置,
// 也可通过Activity的onOptionsItemSelected回调方法来处理
mToolbar.setOnMenuItemClickListener(
new Toolbar.OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_settings:
Toast.makeText(ToolbarActivity.this,
"action_settings", Toast.LENGTH_SHORT).show();
break;
default:
break;
}
return true;
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
/* ShareActionProvider配置 */
mShareActionProvider = (ShareActionProvider) MenuItemCompat.getActionProvider(menu
.findItem(R.id.action_share));
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/*");
mShareActionProvider.setShareIntent(intent);
return super.onCreateOptionsMenu(menu);
}
}
布局文件:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<include layout="@layout/toolbar" />
<android.support.v4.widget.DrawerLayout
android:id="@+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- 内容界面 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/holo_blue_light"
android:orientation="vertical" >
<Button
android:layout_width="100dp"
android:layout_height="match_parent"
android:text="内容界面"/>
</LinearLayout>
<!-- 侧滑菜单内容 必须指定其水平重力 -->
<LinearLayout
android:id="@+id/drawer_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
android:orientation="vertical" >
<Button
android:layout_width="200dp"
android:layout_height="match_parent"
android:text="菜单界面"/>
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
引用的toolbar布局:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?attr/colorPrimary"
android:minHeight="?attr/actionBarSize"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"
app:theme="@style/ThemeOverlay.AppCompat.ActionBar" >
</android.support.v7.widget.Toolbar>
Notification
Notification作为一个事件触发通知型的交互提示接口,让我们可以在获得消息的时候,在状态栏、锁屏界面得到相应的提示信息。
Google在Android 5.0 上又进一步改进了通知栏,优化了Notification。当长按Notification的时候,会显示消息来源。Notification会有一个从白色到灰色的动画切换效果,最终显示发出这个Notification的调用者。同时,在Android 5.X 设备上,锁屏状态下我们也可以看见Notification通知了。
下面我们就分四重境界来看看如何在5.0下使用Notification
基本Notification
public void basicNotify(View view) {
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.baidu.com"));
// 构造PendingIntent
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, intent, 0);
// 创建Notification对象
Notification.Builder builder = new Notification.Builder(this);
// 设置Notification的各种属性
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentIntent(pendingIntent);
builder.setAutoCancel(true);
builder.setLargeIcon(BitmapFactory.decodeResource(
getResources(), R.drawable.ic_launcher));
builder.setContentTitle("Basic Notifications");
builder.setContentText("I am a basic notification");
builder.setSubText("it is really basic");
// 通过NotificationManager来发出Notification
NotificationManager notificationManager =
(NotificationManager) getSystemService(
NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID_BASIC,
builder.build());
}
折叠式Notification
折叠式Notification也是一种自定义视图的Notification,常常用于显示长文本。它拥有两个视图状态,一个是普通状态下的视图状态,另一个是展开状态下的视图状态。
public void collapsedNotify(View view) {
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse("http://www.sina.com"));
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, intent, 0);
Notification.Builder builder = new Notification.Builder(this);
builder.setSmallIcon(R.drawable.ic_launcher);
builder.setContentIntent(pendingIntent);
builder.setAutoCancel(true);
builder.setLargeIcon(BitmapFactory.decodeResource(
getResources(), R.drawable.ic_launcher));
// 将一个布局指定为Notification正常状态下的视图
RemoteViews contentView =
new RemoteViews(getPackageName(),
R.layout.notification);
contentView.setTextViewText(R.id.textView,
"show me when collapsed");
Notification notification = builder.build();
notification.contentView = contentView;
// 将另一个展开的布局指定为Notification展开时的视图
RemoteViews expandedView =
new RemoteViews(getPackageName(),
R.layout.notification_expanded);
notification.bigContentView = expandedView;
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
nm.notify(NOTIFICATION_ID_COLLAPSE, notification);
}
notification.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center_horizontal">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:textColor="#ff43aebe"
android:gravity="center" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/imageView"
android:src="@drawable/robot" />
</LinearLayout>
notification_expanded.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="right|top">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="I am now expanded"
android:textColor="#ff43aebe"
android:layout_gravity="center_vertical"
android:layout_alignParentTop="false"
android:layout_alignParentLeft="true"
android:layout_toLeftOf="@+id/imageView"
android:gravity="center"
android:layout_centerVertical="true" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/robot_expanded"
android:layout_gravity="right|top"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:id="@+id/imageView" />
</RelativeLayout>
</LinearLayout>
悬挂式Notification
悬挂式Notification是在Android 5.0 中新增的方式,这种被称为Headsup的Notification方式,可以在屏幕上方产生Notification且不会打断用户的操作,能给用户以Notification形式的通知。
public void headsupNotify(View view) {
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setPriority(Notification.PRIORITY_DEFAULT)
.setCategory(Notification.CATEGORY_MESSAGE)
.setContentTitle("Headsup Notification")
.setContentText("I am a Headsup notification.");
Intent push = new Intent();
push.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
push.setClass(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this, 0, push, PendingIntent.FLAG_CANCEL_CURRENT);
builder.setContentText("Heads-Up Notification on Android 5.0")
.setFullScreenIntent(pendingIntent, true);
//通过setFullScreenIntent将一个Notification变成悬挂式Notification
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
nm.notify(NOTIFICATION_ID_HEADSUP, builder.build());
}
显示等级的Notification
Android 5.X 中新加入了一种模式——Notification显示等级。
Notification被分成了三个等级。
- VISIBILITY_PRIVATE——表明只有当没有锁屏的时候会显示
- VISIBILITY_PUBLIC——表明在任何情况下都会显示
- VISIBILITY_SECRET——表明在pin、password等安全锁和没有锁的情况下才能够显示
public void visibilityNotify(View view) {
RadioGroup radioGroup = (RadioGroup) findViewById(
visibility_radio_group);
Notification.Builder builder = new Notification.Builder(this)
.setContentTitle("Notification for Visibility Test");
switch (radioGroup.getCheckedRadioButtonId()) {
case R.id.radio_button_public:
builder.setVisibility(Notification.VISIBILITY_PUBLIC);
builder.setContentText("Public");
builder.setSmallIcon(R.drawable.ic_public);
break;
case R.id.radio_button_private:
builder.setVisibility(Notification.VISIBILITY_PRIVATE);
builder.setContentText("Private");
builder.setSmallIcon(R.drawable.ic_private);
break;
case R.id.radio_button_secret:
builder.setVisibility(Notification.VISIBILITY_SECRET);
builder.setContentText("Secret");
builder.setSmallIcon(R.drawable.ic_secret);
break;
}
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
nm.notify(NOTIFICATION_ID_VISIBILITY, builder.build());
}
Notification在Android 5.X中的改动非常多,还有比如其他两种:
设置Notification背景颜色
builder.setColor(Color.RED)
设置Notification的category,category用来确定Notification显示的位置,参数就是各种category的类型
builder.setCategory(Nofitication.CCATEGORY_MESSAGE)