Notification

一、什么是Notification?

Notification是一種有全局效果的通知,可以顯示在系統通知欄。以下內容來自官方文檔。
根據google官方文檔介紹,通知是您可以在應用的常規 UI 外部向用戶顯示的消息。當您告知系統發出通知時,它將先以圖標的形式顯示在通知區域中。用戶可以打開抽屜式通知欄查看通知的詳細信息。 通知區域和抽屜式通知欄均是由系統控制的區域,用戶可以隨時查看。

圖 1. 通知區域中的通知。
圖 2. 抽屜式通知欄中的通知。

二、創建通知

您可以在 NotificationCompat.Builder對象中為通知指定 UI 信息和操作。要創建通知,請調用 NotificationCompat.Builder.build(),它將返回包含您的具體規范的 Notification
對象。要發出通知,請通過調用 NotificationManager.notify()Notification對象傳遞給系統。

必需的通知內容

Notification對象必須包含以下內容:

可選通知內容和設置

所有其他通知設置和內容都是可選的。如需了解有關它們的更多詳情,請參閱 NotificationCompat.Builder參考文檔。

通知操作

盡管通知操作都是可選的,但是您至少應向通知添加一個操作。 操作允許用戶直接從通知轉到應用中的 Activity,他們可在其中查看一個或多個事件或執行進一步的操作。
一個通知可以提供多個操作。您應該始終定義一個當用戶點擊通知時會觸發的操作;通常,此操作會在應用中打開 Activity。 您也可以向通知添加按鈕來執行其他操作,例如,暫停鬧鈴或立即答復短信;此功能自 Android 4.1 起可用。如果使用其他操作按鈕,則您還必須使這些按鈕的功能在應用的Activity
中可用;請參閱處理兼容性部分,以了解更多詳情。
Notification內部,操作本身由 PendingIntent定義,后者包含在應用中啟動 ActivityIntent。要將 PendingIntent與手勢相關聯,請調用NotificationCompat.Builder的適當方法。例如,如果您要在用戶點擊抽屜式通知欄中的通知文本時啟動 Activity,則可通過調用setContentIntent()來添加 PendingIntent。
在用戶點擊通知時啟動 Activity是最常見的操作場景。此外,您還可以在用戶清除通知時啟動 Activity。在 Android 4.1 及更高版本中,您可以通過操作按鈕啟動 Activity。如需了解更多信息,請閱讀參考指南的 NotificationCompat.Builder部分。

通知優先級

您可以根據需要設置通知的優先級。優先級充當一個提示,提醒設備 UI 應該如何顯示通知。 要設置通知的優先級,請調用 NotificationCompat.Builder.setPriority()并傳入一個 NotificationCompat
優先級常量。有五個優先級別,范圍從 PRIORITY_MIN(-2) 到 PRIORITY_MAX(2);如果未設置,則優先級默認為 PRIORITY_DEFAULT(0)。
有關設置適當優先級別的信息,請參閱通知設計指南中的“正確設置和管理通知優先級”。

創建簡單通知

以下代碼段說明了一個指定某項 Activity 在用戶點擊通知時打開的簡單通知。 請注意,該代碼將創建 TaskStackBuilder對象并使用它來為操作創建PendingIntent。啟動 Activity 時保留導航部分對此模式做了更詳盡的闡述:

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.notification_icon)
        .setContentTitle("My notification")
        .setContentText("Hello World!");
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, ResultActivity.class);

// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(
            0,
            PendingIntent.FLAG_UPDATE_CURRENT
        );
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(mId, mBuilder.build());

就這么簡單。您的用戶現已收到通知。

將擴展布局應用于通知

要使通知出現在展開視圖中,請先創建一個帶有所需普通視圖選項的 NotificationCompat.Builder
對象。接下來,調用以擴展布局對象作為其參數的 Builder.setStyle()
請記住,擴展通知在 Android 4.1 之前的平臺上不可用。要了解如何處理針對 Android 4.1 及更早版本平臺的通知,請閱讀處理兼容性部分。
例如,以下代碼段演示了如何更改在前面的代碼段中創建的通知,以便使用擴展布局:

NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.notification_icon)
    .setContentTitle("Event tracker")
    .setContentText("Events received")
NotificationCompat.InboxStyle inboxStyle =
        new NotificationCompat.InboxStyle();
String[] events = new String[6];
// Sets a title for the Inbox in expanded layout
inboxStyle.setBigContentTitle("Event tracker details:");
...
// Moves events into the expanded layout
for (int i=0; i < events.length; i++) {

    inboxStyle.addLine(events[i]);
}
// Moves the expanded layout object into the notification object.
mBuilder.setStyle(inBoxStyle);
...
// Issue the notification here.

處理兼容性

并非所有通知功能都可用于某特定版本,即便用于設置這些功能的方法位于支持庫類 NotificationCompat.Builder中也是如此。 例如,依賴于擴展通知的操作按鈕僅會顯示在 Android 4.1 及更高版本的系統中,這是因為擴展通知本身僅在 Android 4.1 及更高版本的系統中可用。
為了確保最佳兼容性,請使用 NotificationCompat及其子類(特別是 NotificationCompat.Builder)創建通知。此外,在實現通知時,請遵循以下流程:

  1. 為所有用戶提供通知的全部功能,無論他們使用何種版本的 Android 系統。 為此,請驗證是否可從應用的 Activity中獲得所有功能。要執行此操作,您可能需要添加新的 Activity。
    例如,若要使用 addAction()提供停止和啟動媒體播放的控件,請先在應用的 Activity中實現此控件。

  2. 確保所有用戶均可通過點擊通知啟動 Activity來獲得該Activity中的功能。 為此,請為 Activity創建 PendingIntent。調用 setContentIntent()以將 PendingIntent添加到通知。

  3. 現在,將要使用的擴展通知功能添加到通知。請記住,您添加的任何功能還必須在用戶點擊通知時啟動的 Activity中可用。

三、管理通知

當您需要為同一類型的事件多次發出同一通知時,應避免創建全新的通知, 而是應考慮通過更改之前通知的某些值和/或為其添加某些值來更新通知。
例如,Gmail 通過增加未讀消息計數并將每封電子郵件的摘要添加到通知,通知用戶收到了新的電子郵件。 這稱為“堆疊”通知;通知設計指南對此進行了更詳盡的描述。

注:**此 Gmail 功能需要“收件箱”擴展布局,該布局是自 Android 4.1 版本起可用的擴展通知功能的一部分。

下文介紹如何更新和刪除通知。

更新通知

要將通知設置為能夠更新,請通過調用 [NotificationManager.notify()](https://developer.android.com/reference/android/app/NotificationManager.html#notify(int, android.app.Notification))發出帶有通知 ID 的通知。 要在發出之后更新此通知,請更新或創建NotificationCompat.Builder對象,從該對象構建 Notification對象,并發出與之前所用 ID 相同的 Notification。如果之前的通知仍然可見,則系統會根據 Notification對象的內容更新該通知。相反,如果之前的通知已被清除,系統則會創建一個新通知。
以下代碼段演示了經過更新以反映所發生事件數量的通知。 它將通知堆疊并顯示摘要:

mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Sets an ID for the notification, so it can be updated
int notifyID = 1;
mNotifyBuilder = new NotificationCompat.Builder(this)
    .setContentTitle("New Message")
    .setContentText("You've received new messages.")
    .setSmallIcon(R.drawable.ic_notify_status)
numMessages = 0;
// Start of a loop that processes data and then notifies the user
...
    mNotifyBuilder.setContentText(currentText)
        .setNumber(++numMessages);
    // Because the ID remains unchanged, the existing notification is
    // updated.
    mNotificationManager.notify(
            notifyID,
            mNotifyBuilder.build());
...

刪除通知

除非發生以下情況之一,否則通知仍然可見:

  • 用戶單獨或通過使用“全部清除”清除了該通知(如果通知可以清除)。
  • 用戶點擊通知,且您在創建通知時調用了 setAutoCancel()。
  • 您針對特定的通知 ID 調用了 cancel()。此方法還會刪除當前通知。
  • 您調用了 cancelAll()方法,該方法將刪除之前發出的所有通知。

四、啟動 Activity 時保留導航

從通知中啟動 Activity時,您必須保留用戶的預期導航體驗。 點擊“返回”應該使用戶將應用的正常工作流回退到主屏幕,而點擊“最新動態”則應將Activity顯示為單獨的任務。 要保留導航體驗,您應該在全新任務中啟動 Activity。如何設置 PendingIntent以獲得全新任務取決于正在啟動的Activity的性質。一般有兩種情況:

常規 Activity
您要啟動的 Activity是應用的正常工作流的一部分。在這種情況下,請設置 PendingIntent以啟動全新任務并為 PendingIntent提供返回棧,這將重現應用的正?!胺祷亍毙袨?。
Gmail 應用中的通知演示了這一點。點擊一封電子郵件消息的通知時,您將看到消息具體內容。 觸摸返回將使您從 Gmail 回退到主屏幕,就好像您是從主屏幕(而不是通知)進入 Gmail 一樣。
無論您觸摸通知時處于哪個應用,都會發生這種情況。 例如,如果您在 Gmail 中撰寫消息時點擊了一封電子郵件的通知,則會立即轉到該電子郵件。 **觸摸“返回”會依次轉到收件箱和主屏幕,而不是轉到您在撰寫的郵件。

特殊 Activity
僅當從通知中啟動時,用戶才會看到此 Activity。 從某種意義上說,Activity是通過提供很難顯示在通知本身中的信息來擴展通知。對于這種情況,請將 PendingIntent設置為在全新任務中啟動。但是,由于啟動的 Activity不是應用 Activity 流程的一部分,因此無需創建返回棧。點擊“返回”仍會將用戶帶到主屏幕。

設置常規 Activity PendingIntent

要設置可啟動直接進入 ActivityPendingIntent,請執行以下步驟:

  1. 在清單文件中定義應用的 Activity層次結構。
    a.添加對 Android 4.0.3 及更低版本的支持。為此,請通過添加 <meta-data>元素作為 <activity>
    的子項來指定正在啟動的 Activity的父項。對于此元素,請設置 android:name="android.support.PARENT_ACTIVITY"。 設置 android:value="<parent_activity_name>",其中,<parent_activity_name>是父 <activity>元素的 android:name值。請參閱下面的 XML 示例。
    b.同樣添加對 Android 4.1 及更高版本的支持。為此,請將 android:parentActivityName屬性添加到正在啟動的 Activity<activity>元素中。

最終的 XML 應如下所示:

<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>
<activity
    android:name=".ResultActivity"
    android:parentActivityName=".MainActivity">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity"/>
</activity>
  1. 根據可啟動 ActivityIntent創建返回棧:
    a.創建 Intent以啟動 Activity。
    b.通過調用 TaskStackBuilder.create()創建堆棧生成器。
    c.通過調用 addParentStack()將返回棧添加到堆棧生成器。 對于在清單文件中所定義層次結構內的每個 Activity,返回棧均包含可啟動 ActivityIntent對象。此方法還會添加一些可在全新任務中啟動堆棧的標志。
    注:盡管 addParentStack()的參數是對已啟動 Activity的引用,但是方法調用不會添加可啟動 ActivityIntent,而是留待下一步進行處理。
    d.通過調用 addNextIntent(),添加可從通知中啟動 ActivityIntent。 將在第一步中創建的 Intent作為 addNextIntent()的參數傳遞。
    e.如需,請通過調用 TaskStackBuilder.editIntentAt()向堆棧中的 Intent對象添加參數。有時,需要確保目標 Activity在用戶使用“返回”導航回它時會顯示有意義的數據。
    f.通過調用 getPendingIntent() 獲得此返回棧的 PendingIntent。 然后,您可以使用此 PendingIntent作為 setContentIntent() 的參數。
    以下代碼段演示了該流程:
...
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
        stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
...
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());

設置特殊 Activity PendingIntent

下文介紹如何設置特殊 Activity PendingIntent
特殊 Activity無需返回棧,因此您不必在清單文件中定義其 Activity層次結構,也不必調用 addParentStack()來構建返回棧。取而代之的是,您可使用清單文件設置 Activity任務選項,并通過調用 getActivity()創建 PendingIntent

  1. 在清單文件中,將以下屬性添加到 Activity<activity>元素
    android:name="activityclass"
    Activity 的完全限定類名。
    android:taskAffinity=""
    與您在代碼中設置的 FLAG_ACTIVITY_NEW_TASK標志相結合,這可確保此 Activity不會進入應用的默認任務。任何具有應用默認關聯的現有任務均不受影響。
    android:excludeFromRecents="true"
    將新任務從“最新動態”中排除,這樣用戶就不會在無意中導航回它。
    以下代碼段顯示了該元素:
<activity
    android:name=".ResultActivity"
...
    android:launchMode="singleTask"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>
...
  1. 構建并發出通知:
    a.創建可啟動 ActivityIntent
    b.通過使用 FLAG_ACTIVITY_NEW_TASKFLAG_ACTIVITY_CLEAR_TASK標志調用 setFlags(),將 Activity設置為在新的空任務中啟動。
    c.為 Intent設置所需的任何其他選項。
    d.通過調用 getActivity()從 Intent中創建 PendingIntent。 然后,您可以使用此 PendingIntent作為 setContentIntent()的參數。
    以下代碼段演示了該流程:
// Instantiate a Builder object.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
// Creates an Intent for the Activity
Intent notifyIntent =
        new Intent(this, ResultActivity.class);
// Sets the Activity to start in a new, empty task
notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Creates the PendingIntent
PendingIntent notifyPendingIntent =
        PendingIntent.getActivity(
        this,
        0,
        notifyIntent,
        PendingIntent.FLAG_UPDATE_CURRENT
);

// Puts the PendingIntent into the notification builder
builder.setContentIntent(notifyPendingIntent);
// Notifications are issued by sending them to the
// NotificationManager system service.
NotificationManager mNotificationManager =
    (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// Builds an anonymous Notification object from the builder, and
// passes it to the NotificationManager
mNotificationManager.notify(id, builder.build());

五、在通知中顯示進度

通知可能包括動畫形式的進度指示器,向用戶顯示正在進行的操作狀態。 如果您可以估計操作所需的時間以及任意時刻的完成進度,則使用“限定”形式的指示器(進度欄)。 如果無法估計操作的時長,則使用“非限定”形式的指示器(Activity 指示器)。
平臺的 ProgressBar類實現中顯示有進度指示器。
要在 Android 4.0 及更高版本的平臺上使用進度指示器,需調用 setProgress()。對于早期版本,您必須創建包括 ProgressBar視圖的自定義通知布局。
下文介紹如何使用 setProgress()在通知中顯示進度。

顯示持續時間固定的進度指示器

要顯示限定形式的進度欄,請通過調用 setProgress(max, progress, false)將進度欄添加到通知,然后發出通知。隨著操作繼續進行,遞增 progress并更新通知。操作結束時, progress應該等于 max。調用 setProgress()的常見方法是將 max設置為 100,然后將 progress作為操作的“完成百分比”值遞增。
您可以在操作完成后仍保留顯示進度欄,也可以將其刪除。無論哪種情況,都請記住更新通知文本以顯示操作已完成。 要刪除進度欄,請調用setProgress(0, 0, false)。例如:

...
mNotifyManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mBuilder = new NotificationCompat.Builder(this);
mBuilder.setContentTitle("Picture Download")
    .setContentText("Download in progress")
    .setSmallIcon(R.drawable.ic_notification);
// Start a lengthy operation in a background thread
new Thread(
    new Runnable() {
        @Override
        public void run() {
            int incr;
            // Do the "lengthy" operation 20 times
            for (incr = 0; incr <= 100; incr+=5) {
                    // Sets the progress indicator to a max value, the
                    // current completion percentage, and "determinate"
                    // state
                    mBuilder.setProgress(100, incr, false);
                    // Displays the progress bar for the first time.
                    mNotifyManager.notify(0, mBuilder.build());
                        // Sleeps the thread, simulating an operation
                        // that takes time
                        try {
                            // Sleep for 5 seconds
                            Thread.sleep(5*1000);
                        } catch (InterruptedException e) {
                            Log.d(TAG, "sleep failure");
                        }
            }
            // When the loop is finished, updates the notification
            mBuilder.setContentText("Download complete")
            // Removes the progress bar
                    .setProgress(0,0,false);
            mNotifyManager.notify(ID, mBuilder.build());
        }
    }
// Starts the thread by calling the run() method in its Runnable
).start();

顯示持續 Activity 指示器

要顯示非限定形式的 Activity 指示器,請使用 setProgress(0, 0, true)將其添加到通知(忽略前兩個參數),然后發出通知。這樣一來,指示器的樣式就與進度欄相同,只是其動畫還在繼續。
在操作開始之際發出通知。除非您修改通知,否則動畫將一直運行。 操作完成后,調用 setProgress(0, 0, false),然后更新通知以刪除 Activity 指示器。 請務必這樣做;否則,即使操作完成,動畫仍將運行。同時,請記得更改通知文本,以表明操作已完成。
要了解 Activity 指示器的工作方式,請參閱上述代碼段。找到以下幾行:

// Sets the progress indicator to a max value, the current completion
// percentage, and "determinate" state
mBuilder.setProgress(100, incr, false);
// Issues the notification
mNotifyManager.notify(0, mBuilder.build());

將找到的這幾行替換為以下幾行:

 // Sets an activity indicator for an operation of indeterminate length
mBuilder.setProgress(0, 0, true);
// Issues the notification
mNotifyManager.notify(0, mBuilder.build());

六、通知元數據

通知可根據您使用以下 NotificationCompat.Builder方法分配的元數據進行排序:

  • 當設備處于“優先”模式時,setCategory()會告知系統如何處理應用通知(例如,通知代表傳入呼叫、即時消息還是鬧鈴)。
  • 如果優先級字段設置為 PRIORITY_MAX 或 PRIORITY_HIGH的通知還有聲音或振動,則 setPriority()會將其顯示在小型浮動窗口中。
  • addPerson()允許您向通知添加人員名單。您的應用可以使用此名單指示系統將指定人員發出的通知歸成一組,或者將這些人員發出的通知視為更重要的通知。

七、浮動通知

對于 Android 5.0(API 級別 21),當設備處于活動狀態時(即,設備未鎖定且其屏幕已打開),通知可以顯示在小型浮動窗口中(也稱為“浮動通知”)。 這些通知看上去類似于精簡版的通知??,只是浮動通知還顯示操作按鈕。 用戶可以在不離開當前應用的情況下處理或清除浮動通知。

可能觸發浮動通知的條件示例包括:

  • 用戶的 Activity 處于全屏模式中(應用使用 fullScreenIntent),或者
  • 通知具有較高的優先級并使用鈴聲或振動

八、鎖定屏幕通知

隨著 Android 5.0(API 級別 21)的發布,通知現在還可顯示在鎖定屏幕上。您的應用可以使用此功能提供媒體播放控件以及其他常用操作。 用戶可以通過“設置”選擇是否將通知顯示在鎖定屏幕上,并且您可以指定您應用中的通知在鎖定屏幕上是否可見。

設置可見性

您的應用可以控制在安全鎖定屏幕上顯示的通知中可見的詳細級別。 調用 setVisibility()并指定以下值之一:

設置 VISIBILITY_PRIVATE后,您還可以提供其中隱藏了某些詳細信息的替換版本通知內容。例如,短信 應用可能會顯示一條通知,指出“您有 3 條新短信”,但是隱藏了短信內容和發件人。**要提供此替換版本的通知,請先使用 NotificationCompat.Builder創建替換通知。創建專用通知對象時,請通過setPublicVersion()方法為其附加替換通知。

在鎖定屏幕上控制媒體播放

在 Android 5.0(API 級別 21)中,鎖定屏幕不再基于 RemoteControlClient(現已棄用)顯示媒體控件。取而代之的是,將 Notification.MediaStyle模板與 addAction() 方法結合使用,后者可將操作轉換為可點擊的圖標。

注:該模板和 addAction()方法未包含在支持庫中,因此這些功能只能在 Android 5.0 及更高版本的系統上運行。

要在 Android 5.0 系統的鎖定屏幕上顯示媒體播放控件,請將可見性設置為 VISIBILITY_PUBLIC
,如上文所述。然后,添加操作并設置Notification.MediaStyle模板,如以下示例代碼中所述:

Notification notification = new Notification.Builder(context)
    // Show controls on lock screen even when user hides sensitive content.
    .setVisibility(Notification.VISIBILITY_PUBLIC)
    .setSmallIcon(R.drawable.ic_stat_player)
    // Add media control buttons that invoke intents in your media service
    .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0
    .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent)  // #1
    .addAction(R.drawable.ic_next, "Next", nextPendingIntent)     // #2
    // Apply the media style template
    .setStyle(new Notification.MediaStyle()
    .setShowActionsInCompactView(1 /* #1: pause button */)
    .setMediaSession(mMediaSession.getSessionToken())
    .setContentTitle("Wonderful music")
    .setContentText("My Awesome Band")
    .setLargeIcon(albumArtBitmap)
    .build();

注:棄用 RemoteControlClient會對控制媒體產生進一步的影響。如需了解有關用于管理媒體會話和控制播放的新 API 的詳細信息,請參閱媒體播放控件。

九、自定義通知布局

您可以利用通知框架定義自定義通知布局,由該布局定義通知在 RemoteViews對象中的外觀。 自定義布局通知類似于常規通知,但是它們是基于 XML 布局文件中所定義的 RemoteViews。
自定義通知布局的可用高度取決于通知視圖。普通視圖布局限制為 64 dp,擴展視圖布局限制為 256 dp。
要定義自定義通知布局,請首先實例化 RemoteViews對象來擴充 XML 布局文件。然后,調用 setContent(),而不是調用 setContentTitle()等方法。要在自定義通知中設置內容詳細信息,請使用 RemoteViews中的方法設置視圖子項的值:

  1. 在單獨的文件中為通知創建 XML 布局。您可以根據需要使用任何文件名,但必須使用擴展名 .xml。
  2. 在您的應用中,使用 RemoteViews方法定義通知的圖標和文本。通過調用 setContent()將此 RemoteViews對象放入 NotificationCompat.Builder中。避免在 RemoteViews對象上設置背景 Drawable,因為文本顏色可能使文本變得難以閱讀。

此外,RemoteViews類中還有一些方法可供您輕松將 ChronometerProgressBar添加到通知布局。如需了解有關為通知創建自定義布局的詳細信息,請參閱 RemoteViews參考文檔。

注意:使用自定義通知布局時,要特別注意確保自定義布局適用于不同的設備方向和分辨率。 盡管這條建議適用于所有“視圖”布局,但對通知尤為重要,因為抽屜式通知欄中的空間非常有限。 不要讓自定義布局過于復雜,同時確保在各種配置中對其進行測試。

對自定義通知文本使用樣式資源

始終對自定義通知的文本使用樣式資源。通知的背景顏色可能因設備和系統版本的不同而異,使用樣式資源有助于您充分考慮到這一點。 從 Android 2.3 開始,系統定義了標準通知布局文本的樣式。若要在面向 Android 2.3 或更高版本系統的多個應用中使用相同樣式,則應確保文本在顯示背景上可見。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 原文出處: http://www.androidchina.net/6174.html Notification在...
    木木00閱讀 12,395評論 3 32
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,466評論 25 708
  • 轉載自:http://blog.csdn.net/vipzjyno1/article/details/252480...
    HEXG_閱讀 5,933評論 0 2
  • 第一次聽說這個朝代是從我奶奶嘴里,那時候覺得她知識淵博,隨口就能說出唐宋元明清這樣的朝代更替。后來上了中學,老師告...
    瓦萊閱讀 345評論 1 1
  • 睡前回憶今天,那些事可以不做,浪費了時間。 你總是輕易的放過自己。真正的對手,只有自己。
    cleddie閱讀 201評論 0 0