主要介绍Android常用于消息提示的组件:ALertDialog、Toast、Notification的使用场景以及它们的基本用法,探讨一些高级主题,最后总结一些开发过程中常见的问题。
本文代码地址:https://github.com/JueYingCoder/AndroidNotice
首先我们来对这三种消息提示机制来一个直观的认识,分别是AlertDialog Toast、Notification
接下来分别介绍这三种机制各自对应的使用场景和用法
AlertDialog
使用场景:AlertDialog在应用内的使用还是很常见的,常用于让用户做出某种选择,而这种选择一定是简单的交互,如果是复杂的就应该用另一个Activity来承接而非AlertDialog,基本用法和高级主题:请参考我以前写过的这篇文章,介绍的很详细:http://blog.csdn.net/qwm8777411/article/details/45420451
Toast的使用
使用场景:首先Toast有两个显著的特点:
1,Toast提示消息不会获得焦点;
2,Toast提示消息过一段时间会自动消失。
基于以上两点,Toast常用于提示一些不需要和用户交互的简单消息,
基本用法:既可以创建简单的用于文本提示的Toast,也可以创建自定义View的Toast
使用简单Toast的基本步骤:
1,通过Toast的静态方法makeText()创建一个Toast对象
2,调用Toast的其他方法设置属性
3,调用show()方法将它显示出来;
它的使用比较简单,大部分用来显示简单的文本提示;如果应用需要显示诸如图片、列表之类的复杂提示、一般使用对话框来完成。当然可以通过setView()方法实现定制的Toast视图;
显示文本的简单Toast
Toast toast=ToastmakeText(context,"文本消息",Toast.LENGTH_SHORT);toast.show();
自定义View的Toast:
Toast toast=new Toast(Context context);toast.setGravity(Gravity.CENTER,0,0);//设置显示位置toast.setView(R.layout.toast_view);//设置视图toast.setDuration(Toast.LENGTH_SHORT);//设置显示时长toast.show();
Notification的使用
**使用场景:**Notification是那些不可见的应用程序组件(BroadcastReceiver、Service、非活动状态的Activity)的首选机制用来提醒用户,需要他们注意的事件已经发生。也可以用来指示持续运行的后台Service。
Notification是应用程序提醒用户发生某些事件的一种方式,无需某个Activity可见,Notification是由NotificationManager进行处理的;当前包括以下功能:
- 显示状态栏图标 :
- 灯光闪烁
- 让手机振动
- 发出声音提醒
- 在通知托盘中使用交互式操作来广播Intent
使用Notification的基本步骤:
1,创建NotificationManager
NotificationManager nm= (NotificationManager)getSystemService(SEREVICE_NOTIFICATION);
2,一般方法创建Notification
int icon=R.drawable.icon;String ticker="一条新消息";Long when=System.currentTimeMillis;//分别对应通知显示的图标,ticker文字和显示顺序按时间排列Notification notification=new Notification(icon,ticker,when);
3,使用Notification Builder创建Notification
Notification还有另外一种创建方法,Notification Builder是在Android 3.0引入的,简化了上述过程;
Notification.Builder builder=new Notification.Builder(Context context);builder.setSmallcon(R.drawable.icon);builder.setDefaults();NotificationManager manager=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);/**此处的ID值作为Notification的唯一标示,*/manager.notify(int id,builder.build());//触发Notification
通过以上步骤我们已经可以创建一个Notification并且显示在通知栏中,但还有几点需要注意:
//也可以通过以下方法设置Notification属性setLastEventInfo(context,string ticker,string content,PendingIntent intent); //如果ID相同的话将被更新而不是重建(例如连续下载)manager.notify(ID,notification);//更新通知:通知不应该一直在通知栏里,需要复用或者更新通知,可以使用一个计数器setNumber(4);//清除通知:manager.cancel(ID);//或者使用builder.setAutoCancel(true);
使用自定义View的Notification:
RemoteView:RemoteView view=new RemoteView(getPackageName(),R.layout.remote);//自定义的视图
notification.setView(view);
有了上面的知识我们来实现一个综合练习,实现的效果:
MainActivity.java
:
public class MainActivity extends ActionBarActivity implements View.OnClickListener {
private Button simpleToast,customToast;private Button simpleNotification,customNotification;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);simpleToast= (Button) findViewById(R.id.simple_toast);customToast= (Button) findViewById(R.id.custom_toast);simpleNotification= (Button) findViewById(R.id.simple_notification);customNotification= (Button) findViewById(R.id.custom_notification);simpleToast.setOnClickListener(this);customToast.setOnClickListener(this);simpleNotification.setOnClickListener(this);customNotification.setOnClickListener(this);}@Overridepublic void onClick(View view) {switch (view.getId()){case R.id.simple_toast:simpleToast();break;case R.id.custom_toast:customToast();break;case R.id.simple_notification:simpleNotification();break;case R.id.custom_notification:customNotification();break;}}public void simpleToast(){// 显示一个简单的文本信息Toast toast=Toast.makeText(MainActivity.this, "This is a simple Toast", Toast.LENGTH_SHORT);toast.show();}public void customToast(){Toast toast=new Toast(MainActivity.this);// 设置Toast的显示位置toast.setGravity(Gravity.BOTTOM, 0, 0);// 设置Toast的视图,这里我们添加一张图片LinearLayout layout=new LinearLayout(getApplicationContext());layout.setOrientation(LinearLayout.VERTICAL);ImageView imageView=new ImageView(getApplicationContext());imageView.setImageResource(R.mipmap.touxiang);//设置一张图片layout.addView(imageView,new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,LinearLayout.LayoutParams.MATCH_PARENT));toast.setView(layout);// 设置显示时长toast.setDuration(Toast.LENGTH_SHORT);toast.show();}public void simpleNotification(){// 获取NotificationManager实例NotificationManager manager= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);// 构造Notification.Builder 对象NotificationCompat.Builder builder=new NotificationCompat.Builder(MainActivity.this);// 设置Notification图标builder.setSmallIcon(R.mipmap.ic_launcher);//builder.setLargeIcon(myIcon);// 设置Notification tickertextbuilder.setTicker("A new Message");// 设置通知的题目builder.setContentTitle("A new notification");// 设置通知的内容builder.setContentText("This is content text");builder.setContentInfo("Info");// 设置通知可以被自动取消builder.setAutoCancel(true);// 设置通知栏显示的Notification按时间排序builder.setWhen(System.currentTimeMillis());// 设置其他物理属性,包括通知提示音、震动、屏幕下方LED灯闪烁builder.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION));//这里设置一个本地文件为提示音builder.setVibrate(new long[]{
1000,1000,1000,1000});builder.setLights(Color.RED,0,1);// 设置该通知点击后将要启动的Intent,这里需要注意PendingIntent的用法,构造方法中的四个参数(context,int requestCode,Intent,int flags);Intent intent=new Intent(MainActivity.this,AnotherActivity.class);PendingIntent pi=PendingIntent.getActivity(MainActivity.this,0,intent,0);builder.setContentIntent(pi);// 实例化NotificationNotification notification=builder.build();//notify(int id,notification对象);id用来标示每个notificationmanager.notify(1,notification);}public void customNotification(){NotificationManager manager= (NotificationManager) getSystemService(NOTIFICATION_SERVICE);NotificationCompat.Builder builder=new NotificationCompat.Builder(MainActivity.this);builder.setTicker("音乐正在播放");builder.setSmallIcon(R.mipmap.ic_launcher);builder.setWhen(System.currentTimeMillis());builder.setAutoCancel(true);// 设置自定义RemoteViewRemoteViews view=new RemoteViews(getPackageName(),R.layout.remote_view);builder.setContent(view);PendingIntent pi=PendingIntent.getActivity(MainActivity.this,1,new Intent(MainActivity.this,AnotherActivity.class),0);builder.setContentIntent(pi);builder.setOngoing(true);manager.notify(2, builder.build());}}
通过上面的练习我们已经基本掌握了Notification的用法,下面是常用的一些高级主题:
- builder.setLargeIcon(Bitmap 对象); //设置一个大图片
- builder.setProgress(Max,value,false);//设置通知显示为一个进度条
- 手动设置setContentView(RemoteView对象)时;必须同时设置setContentIntent
- 要触发一个Notification,需要把它和一个整型的引用ID传递给Notification Manager的notify方法。如果已经使用一个Notification Builder构造,可以使用builder。getNotification();
- 要更新一个Notification就需要把相同的ID传给Notification Manager,既可以传入一个相同的Notification对象,又可以传入一个不同的,只要ID值相同,新的Notification就会替换原来的,要更新Notification而不引起相关联的闪灯、音频、和振动,可以使用NotificationBuilder.setOnlyAlertOnce(true);另外可以使用Notificationmanager.flags=Notification.FLAG_ONLY_ALERT_ONCE;
- 通常是点击操作后取消通知:单击后自动取消自己setAutoCancel(true);
- 也可以使用NotificationManager manager.cancel(ID);
配置持续和连续的Notification:
通过Notification的FLAG_INSISTENT 和 FLAG_ONGOING_EVENT标志,可以将Notification配置成连续的和不连续的。
标记为持续的Notification可以表示那些当前正在进行的事件(如正在下载)
- 使用builder.setOngoing(true);
- 也可以使用Notification.flags=FLAG_ONGOING_EVENT,前台service必须具有连续的Notification(音乐播放?)
连续的Notification会一直重复音频、振动和闪屏,直到取消为止。这些Notification通常用于需要立即注意和处理的事件,一般不常用
-
- 可以通过notification.flags=Notification.FLAG_INSISTENET,不推荐第三方应用使用,所以builder中无此方法
为RemoteView中的View附加单击监听器:
需要传入关联的View资源ID和当view点击后的PendingIntent
Intent i=new Intent(BUTTON_CLICK);
PendingIntent pi=PendingIntent.getActivity(MyActivity.this,2.i,0);notification.contentView.setOnClickPendingIntent(R.id.status_progress,pi);//单击Notification布局中任何没有采用这种方式绑定的区域将会触发Notification的内容Intent
总结:设计有用的通知:
Android平台的通知功能非常强健,以至于你有可能过度使用,下面是一些良好的建议:
* 只有在应用不处于前台是使用通知,否则使用Toast和AlertDialog
* 允许用户选择他想要的通知类型和频率,以及在什么情况下触发通知
* 经常性地清理通知以避免向用户提供过时的消息
* 在不确定的情况下,使用柔和的通知语言
* 确保在通知的Ticker文字,标题和正文包含有用的消息,并且运行有意义的Intent;
通知框架虽然轻量但却很强大,不过,诸如闹钟和股票监控器这样的软件可能会需要提供超越通知框架的功能,在这种情况下,它们可能会使用后台服务并且在特定事件到达时使用自己完整的Activity,应用程序可以使用通知来与用户交互,而超越其自身Activity的界限。通知既可以是视觉上的,也可以是听觉上的,或者使用设备的振动功能。可以使用各种方法来自定义通知以便向用户传递更丰富的信息。不过需要特别注意的是通知要适当而且数量要事宜,否则用户将对应用程序感到厌烦。
参考资料:
* Android 4 高级编程(第3版)
* Android In Practice
* Android移动应用开发 卷2:提高篇