一、Notification的基本情形
元素:
1. 标题 Title/Name
2. 大图标 Icon/Photo
3. 内容文字
4. 内容信息 MESSAGE
5. 小图标 Secondary Icon
6. 通知的时间 Timestamp,默认为系统发出通知的时间,也可通过setWhen()来设置
二、app中的通知实现方式及特点
Banner :在不中断当前操作的情况下告知用户新消息,会对当前有干扰,但不打断,应用中要注意停留时间和用户错过后的找寻路径;
Alert :强打断型提醒,提醒内容与当前应用有联系时可以接受;
标记 :一种不紧急的提醒方式,增量很难记住,部分用户有强迫清零的习惯;
Toast :纯告知,不需要处理;针对正在操作的反馈;
预览 :可辅助用户判断是否需要查看该信息详情,但要注意结合“标记为已读”机制;
通知栏 :是一种被普遍接受的通知方式,优点是“集中处理”。
三、实现方式
activity_main.xml
<?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="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/notifi_bt1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Base消息框" />
<Button
android:id="@+id/notifi_bt2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="更新消息框" />
<Button
android:id="@+id/notifi_bt3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="清除消息框" />
<Button
android:id="@+id/notifi_bt4"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Media消息框" />
<Button
android:id="@+id/notifi_bt5"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="清除Media消息框" />
<Button
android:id="@+id/notifi_bt6"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="清除所有消息框" />
<Button
android:id="@+id/notifi_bt7"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="自定义消息框" />
<Button
android:id="@+id/notifi_bt8"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="自定义提示框" />
</LinearLayout>
self_define_notification.xml 【自定义notification布局文件】
<?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="match_parent"
android:orientation="vertical">
<ImageView
android:id="@+id/image"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:layout_marginRight="10dp" />
<TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:textColor="#000" />
</LinearLayout>
self_define_dialog.xml 【自定义Dialog的实现】
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/self_define_body"
android:background="#04000000" />
<LinearLayout
android:id="@+id/self_define_body"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="@color/white"
android:orientation="vertical">
<!--分割线-->
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/light_black" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<RelativeLayout
android:id="@+id/self_define_cancel"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/kill" />
</RelativeLayout>
<Button
android:layout_width="0dp"
android:layout_height="50dp"
android:layout_weight="6"
android:background="@color/white"
android:text="提示"
android:textColor="@color/text_black"
android:textSize="22sp" />
<RelativeLayout
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:gravity="center" />
</LinearLayout>
<!--分割线-->
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/light_black" />
<TextView
android:layout_width="match_parent"
android:layout_height="100dp"
android:gravity="center"
android:text="自定义提示框提示内容"
android:textSize="22sp" />
<!--分割线-->
<View
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="@color/light_black" />
<Button
android:id="@+id/self_define_ensure"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_weight="6"
android:background="@color/white"
android:text="确定"
android:textColor="@color/blue"
android:textSize="22sp" />
</LinearLayout>
</RelativeLayout>
MainActivity的实现
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
/**
* Base消息框
*/
private Button bt1;
/**
* 更新消息框
*/
private Button bt2;
/**
* 取消常规消息框
*/
private Button bt3;
/**
* Media消息框
*/
private Button bt4;
/**
* 清除Media消息框
*/
private Button bt5;
/**
* 清除所有消息框
*/
private Button bt6;
/**
* 自定义消息框
*/
private Button bt7;
/**
* 自定义提示框
*/
private Button bt8;
/**
* Base消息框
*/
private int Notification_ID_BASE = 110;
private Notification baseNF;
/**
* Media消息框
*/
private int Notification_ID_MEDIA = 119;
private Notification mediaNF;
/**
* 通知管理器
*/
private NotificationManager nm;
/**
* 通知显示内容
*/
private PendingIntent pd;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Intent intent = new Intent(this, MainActivity.class);
pd = PendingIntent.getActivity(MainActivity.this, 0, intent, 0);
initView();
initListener();
}
/**
* 初始化监听器
*/
private void initListener() {
bt1.setOnClickListener(this);
bt2.setOnClickListener(this);
bt3.setOnClickListener(this);
bt4.setOnClickListener(this);
bt5.setOnClickListener(this);
bt6.setOnClickListener(this);
bt7.setOnClickListener(this);
bt8.setOnClickListener(this);
}
/**
* 初始化View
*/
private void initView() {
bt1 = (Button) findViewById(R.id.notifi_bt1);
bt2 = (Button) findViewById(R.id.notifi_bt2);
bt3 = (Button) findViewById(R.id.notifi_bt3);
bt4 = (Button) findViewById(R.id.notifi_bt4);
bt5 = (Button) findViewById(R.id.notifi_bt5);
bt6 = (Button) findViewById(R.id.notifi_bt6);
bt7 = (Button) findViewById(R.id.notifi_bt7);
bt8 = (Button) findViewById(R.id.notifi_bt8);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
/**
* base消息框
*/
case R.id.notifi_bt1:
//新建状态栏通知
baseNF = new Notification();
//设置通知在状态栏显示的图标
baseNF.icon = R.drawable.beautiful;
//通知时在状态栏显示的内容
baseNF.tickerText = "你点击了Base消息框!";
//通知的默认参数 DEFAULT_SOUND, DEFAULT_VIBRATE, DEFAULT_LIGHTS.
//如果要全部采用默认值, 用 DEFAULT_ALL.
//此处采用默认声音
baseNF.defaults |= Notification.DEFAULT_SOUND;
baseNF.defaults |= Notification.DEFAULT_VIBRATE;
baseNF.defaults |= Notification.DEFAULT_LIGHTS;
//让声音、振动无限循环,直到用户响应
baseNF.flags |= Notification.FLAG_INSISTENT;
//通知被点击后,自动消失
baseNF.flags |= Notification.FLAG_AUTO_CANCEL;
//点击'Clear'时,不清除该通知(QQ的通知无法清除,就是用的这个)
baseNF.flags |= Notification.FLAG_NO_CLEAR;
//第二个参数 :下拉状态栏时显示的消息标题 expanded message title
//第三个参数:下拉状态栏时显示的消息内容 expanded message text
//第四个参数:点击该通知时执行页面跳转
baseNF.setLatestEventInfo(MainActivity.this, "Base消息框", "Base消息框内容", pd);
//发出状态栏通知
//Notification_ID_BASE 消息通知的特有ID
//baseNF 消息对象
nm.notify(Notification_ID_BASE, baseNF);
break;
/**
* 更新消息框
*/
case R.id.notifi_bt2:
//更新通知
//比如状态栏提示有一条新短信,还没来得及查看,又来一条新短信的提示。
//此时采用更新原来通知的方式比较。
//(再重新发一个通知也可以,但是这样会造成通知的混乱,而且显示多个通知给用户,对用户也不友好)
if (baseNF != null) {
baseNF.setLatestEventInfo(MainActivity.this, "更新消息框", "更新消息框内容", pd);
nm.notify(Notification_ID_BASE, baseNF);
}
break;
/**
* 取消消息框
*/
case R.id.notifi_bt3:
//清除 baseNF,依据特有ID清除
nm.cancel(Notification_ID_BASE);
break;
/**
* Media消息框
*/
case R.id.notifi_bt4:
mediaNF = new Notification();
mediaNF.icon = R.drawable.beautiful;
mediaNF.tickerText = "帅哥,你点击了Media消息框!";
//自定义声音
mediaNF.sound = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "6");
//通知时发出的振动
//第一个参数: 振动前等待的时间
//第二个参数: 第一次振动的时长、以此类推【仓储PDA震动使用相似】
long[] vir = {0, 100, 200, 300};
mediaNF.vibrate = vir;
mediaNF.setLatestEventInfo(MainActivity.this, "Media消息框", "Media消息框内容", pd);
nm.notify(Notification_ID_MEDIA, mediaNF);
break;
/**
* 取消Media消息框
*/
case R.id.notifi_bt5:
//清除 mediaNF
nm.cancel(Notification_ID_MEDIA);
break;
/**
* 清除所有消息框
*/
case R.id.notifi_bt6:
nm.cancelAll();
break;
/**
* 自定义消息框
*/
case R.id.notifi_bt7:
//自定义下拉展示视图,比如下载软件时,显示的进度条。
Notification notification = new Notification();
notification.icon = R.drawable.beautiful;
notification.tickerText = "自定义消息框!";
RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.self_define_notification);
contentView.setImageViewResource(R.id.image, R.drawable.beautiful);
contentView.setTextViewText(R.id.text, "这是一个自定义消息框!");
notification.contentView = contentView;
//使用自定义下拉视图时,不需要再调用setLatestEventInfo()方法
//但是必须定义 contentIntent
notification.contentIntent = pd;
nm.notify(3, notification);
break;
/**
* 自定义提示框
*/
case R.id.notifi_bt8:
showEnsureDialog();
break;
}
}
/**
* 展示确认弹出框
*/
private void showEnsureDialog() {
final AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.show();//show需要在渲染其内部内容之前展示
Window window = alertDialog.getWindow();
window.setContentView(R.layout.self_define_dialog);
RelativeLayout selfDefineCancel = (RelativeLayout) window.findViewById(R.id.self_define_cancel);
selfDefineCancel.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
alertDialog.dismiss();
}
});
Button selfDefineEnsure = (Button) window.findViewById(R.id.self_define_ensure);
selfDefineEnsure.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/**
* 确认事件
*/
}
});
}
}
展示效果:
越是不经意的表演,越是需要刻意地练习。