天天看點

Android UI學習 - 使用者通知

    本文是在網上的文章《Android開發指南-使用者界面-使用者通知》的基礎上添加内容的。裡面的相同内容,版權歸原翻譯作者所有。

通知使用者Notifying the User

    某些情況下需要通知使用者你的應用程式中發生了一個事件。一些事件請求使用者應答而另外一些則不需要。比如:

  • 當一個事件比如儲存檔案結束時,應該出現一條消息确認儲存成功。(Toast适用)
  • 如果一個背景運作的應用程式需要使用者關注,這個應用程式應該建立一個通知來允許使用者在友善時進行應答。(背景程式,狀态欄通知适用)
  • 如果這個應用程式在執行一個使用者必須等待的任務(比如加載一個檔案),那麼應用程式應該顯示一個盤旋的進度輪或進度條。(進度條Dialog适用)

    所有這些通知任務可以通過一個不同的技術擷取到:

  • 一個消息條通知Toast Notification, 用于從背景出現的簡短資訊。for brief messages that come from the background.
  • 一個狀态條通知A Status Bar Notification, 用于來自背景的持續提醒并請求使用者應答。
  • 一個對話框通知A Dialog Notification, 用于活動相關的通知。

消息條通知Toast Notification

    一個消息條通知是一個在視窗表面彈出的資訊。它隻填充内容所需的空間并且使用者目前活動仍然保持可見和可互動。這個通知自動漸入漸出,而且不接受互動事件。因為消息條可以從一個背景服務Service中建立,即便應用程式不可見,它也将呈現出來。

Android UI學習 - 使用者通知
Android UI學習 - 使用者通知

預設的Toast    自定義的Toast

Toast的建立和顯示都很簡單,如果不使用自定義的view,隻是顯示文字,makeText函數就能做到了:

Toast.makeText(getApplicationContext(),   // Context context      
"This is a simple toast!", //顯示的text或者引用resource.string的id      
Toast.LENGTH_LONG)         //顯示的時間長度,      
//LENGTH_LONG - 時間長些,>1s;      
//LENGTH_SHORT- 時間短      
.show(); //顯示出來      
自定義Toast

而如果想使用custom view,首先要寫個custom Layout xml檔案(toastlayout.xml):

<?xml version="1.0" encoding="utf-8"?>      
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"      
android:id="@+id/toast_layout"      
android:orientation="horizontal"      
android:layout_width="fill_parent"      
android:layout_height="fill_parent"      
android:padding="10dp"      
android:background="#DAAA"      
>      
<ImageView      
android:id="@+id/toast_icon"      
android:layout_width="wrap_content"      
android:layout_height="fill_parent"      
android:layout_marginRight="10dp"      
android:src="@drawable/icon"      
/>      
<TextView      
android:id="@+id/toast_text"      
android:layout_width="wrap_content"       
android:layout_height="fill_parent"      
android:textColor="#FFF"      
/>      
</LinearLayout>      

注意: TextView的layout_height設定為wrap_content的話,發現左邊的圖檔會跟随文字内容的高度而變化,就是說當文字隻有一行的時候,圖檔的高度就變得隻有一行的高度,不好看!圖檔的src可以不在xml檔案裡面定義,可以在真正顯示時用以下語句來設定:

ImageView p_w_picpath = (ImageView) layout.findViewById(R.id.p_w_picpath);       
p_w_picpath.setImageResource(R.drawable.android);      

以下是顯示custom toast view:

//加載Layout      
View view = getLayoutInflater().inflate(      
R.layout.toastlayout,                         //resource id      
(ViewGroup) findViewById(R.id.toast_layout)); //ViewGroup對象      
//設定Text      
((TextView) view.findViewById(R.id.toast_text))      
.setText("This is a custom toast!");       
//建立Toast      
Toast toast = new Toast(getApplicationContext());      
// 設定顯示的位置       
toast.setGravity(       
Gravity.CENTER_VERTICAL, //垂直居中      
0, //xOffset      
0  //yOffset      
);      
toast.setDuration(Toast.LENGTH_LONG);      
toast.setView(view); // ** 這個很重要      
toast.show();      

** 官方提示:隻有使用custom view,setView(View)的時候,才使用new Toast(Content content)來得到Toast對象,否則必須用makeText(Context, int, int)方法來建立toast對象。

消息條Toast是用來顯示簡短文本資訊的最好方法,比如“檔案已儲存”,當你很确信使用者正在關注螢幕時。一個消息條不能接受使用者互動事件;如果你希望使用者應答并采取相應動作,請考慮使用一個狀态條通知Status Bar Notification。

狀态條通知Status Bar Notification

    一個狀态條通知添加一個圖示到系統狀态欄上(以及一個可選的滾動條文本資訊)以及在這個“通知”視窗中的一個擴充消息。當使用者選擇這個擴充消息時,Android發出這個通知所定義的一個意圖(通常是啟動一個活動)。你也可以配置這個通知來通過一個聲音,震動和裝置上的閃爍燈來警告使用者。

    當你的應用程式以背景服務運作并需要通知使用者事件時,這類通知是一個理想的方式。如果你需要在活動仍處于焦點下時警告使用者一個發生的事件,請考慮使用對話框通知Dialog Notification 。

Android UI學習 - 使用者通知

自定義View和預設的Notification

狀态欄Notification的建立流程大概是這樣的:

// 擷取NotificationManager      
mNotificationManager =       
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);      
// 建立PendingIntent, 明确響應後轉向的Activity      
contentIntent = PendingIntent.getActivity(      
getApplicationContext(),      
0,      
new Intent(getApplicationContext(),      
FrameDemo.class), //響應Notification轉向的Activity      
0);       
//執行個體化一個Notification,并指定其圖示和标題(在提示欄上顯示)      
mNotification = new Notification(      
R.drawable.icon, // icon      
"Notification",  // 狀态欄上顯示的滾動提示文字tickerText      
System.currentTimeMillis());//Notification計劃執行的開始時間      
//設定Notification的Title和詳細内容(打開提示欄後在通知清單中顯示)      
mNotification.setLatestEventInfo(      
getApplicationContext(),      
"Notification open", // Title      
"This is a simple notification", //content      
contentIntent);      //PendingIntent是在這時候用的      
//100 毫秒延遲後,震動 250 毫秒,暫停 100 毫秒後,再震動 500 毫秒      
mNotification.vibrate = new long[] { 100, 250, 100, 500 };      
//mNotification.defaults |= Notification.DEFAULT_VIBRATE; //或者設定預設的震動效果      
//設定閃燈綠光,也可以設定預設的效果,請參考API DOC      
mNotification.ledARGB = 0xff00ff00;      
mNotification.ledOnMS = 300;      
mNotification.ledOffMS = 1000;      
mNotification.flags |= Notification.FLAG_SHOW_LIGHTS;      
//設定聲音,可以選擇以下任一方式,但要注意,當defaults已經包含了DEFAULT_SOUND,将覆寫之前指定的音頻檔案的設定      
mNotification.defaults |= Notification.DEFAULT_SOUND; //系統預設的通知聲音      
//mNotification.sound = Uri.parse("file:///sdcard/notification/ringer.mp3"); //或者指定某個音頻檔案      
//設定聲音持續重複,直至使用者點選或者清除通知      
mNotification.flags |= Notification.FLAG_INSISTENT;      
//最後一步: NotificationManager發出通知      
mNotificationManager.notify(      
R.id.notice1,  //該Notification的ID      
mNotification);      
清除通知Clear

    如果需要把Notification清除(clear),則調用NotificationManager.cancel(Notification的ID),或者直接NotificationManager.clearAll()清除所有。也可以添加Notification對象的FLAG_AUTO_CANCEL屬性來自動清除。

更新通知Update the notification

    可以通過notification對象的setLatestEventInfo()方法來修改/更新資訊,也可以通過其他函數來修改notification對象的屬性,最後是調用NotificationManager.notify(原來的ID, 修改/更新後的notification對象)完成的。

//修改Title & content      
mNotification.setLatestEventInfo(      
getApplicationContext(),      
"Notification update", // Title      
"This is the second notification", //content      
contentIntent);      
//修改Icon      
mNotification.icon = R.drawable.robot;      
//設定自動清除      
mNotification.flags |= Notification.FLAG_AUTO_CANCEL;      
//重新發出通知      
mNotificationManager.notify(R.id.notice1, mNotification);      
自定義view的Notification

首先定義Layout xml檔案(notifylayout.xml):

<?xml version="1.0" encoding="utf-8"?>      
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"      
android:id="@+id/notify_layout"      
android:orientation="horizontal"      
android:layout_width="fill_parent"      
android:layout_height="fill_parent"      
android:padding="3dp"      
>      
<ImageView       
android:id="@+id/notify_p_w_picpath"      
android:layout_width="wrap_content"      
android:layout_height="fill_parent"      
android:layout_marginRight="10dp"      
/>      
<TextView       
android:id="@+id/notify_text"      
android:layout_width="wrap_content"      
android:layout_height="fill_parent"      
android:textColor="#000"      
/>      
</LinearLayout>      

 然後使用RemoteView加載Layout,并設定Image,Text:

RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.notifylayout);      
contentView.setImageViewResource(R.id.notify_p_w_picpath, R.drawable.robot);      
contentView.setTextViewText(R.id.notify_text, "Hello, this message is in a custom expanded view");      
Notification notification = new Notification(      
R.drawable.icon, //icon      
"Notification", // 狀态欄上顯示的提示文字      
System.currentTimeMillis());      
notification.contentIntent = contentIntent;      
notification.contentView = contentView; //就是這裡不同,set view      
// 以R.layout.notify_layout為ID      
mNotificationManager.notify(R.layout.notifylayout, notification);      

    官方提示,使用custom view的Notification要注意在不同規格的螢幕下的顯示效果。個人認為,Notification的自定義View用途不大。更詳細的内容可以查閱http://androidappdocs.appspot.com/guide/topics/ui/notifiers/notifications.html

對話框通知Dialog Notification