上周,我們已經奠定了加載圖片到 Glide target 的基礎。如果你還沒有讀過,請預覽[內容](https://futurestud.io/blog/glide-loading-images-into-notifications-and-appwidgets),為學這篇文章打一個基礎。這周我們要繼續增加2個額外的特殊用途的 target: 通知 和 應用程序小部件。如果你需要去加載圖片到這兩個中的一個,請閱讀!
**加載圖片到 Notifications?**

通知欄圖標對用戶來說是重要的上下文。用 [NotificationCompat.Builder](https://developer.android.com/reference/android/support/v4/app/NotificationCompat.Builder.html?hl=zh-cn) 來直接設置大的通知圖片,但是圖像必須以 Bitmap 的形式。如果圖片在手機上已經是可用的,這并沒什么問題。然而,如果圖片斌不在設備上并且需要從網上加載的話,使用標準的方式來處理就變得不可能了。
讓 Glide 來做吧。上篇博客中,我們看了如何用 `SimpleTarget` 將圖片以 Bitmap 的形式下載下來。理論上說,你可以利用這種方式去加載圖片到你的通知欄中。但這并不是必須的,因為 Glide 提供了一個更加方便舒適的方式:`NotificationTarget`。
**NotificationTarget?**
所以,讓我們來看代碼。現在你知道 Glide target 是如何工作的了,因此我們不會再去用它了。為了顯示一張大圖片在通知欄,你可以使用 `RemoteViews` 并顯示一個自定義的通知欄。

我們自定義的通知欄比較簡單:
~~~
<?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="wrap_content"
android:background="@android:color/white"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="2dp">
<ImageView
android:id="@+id/remoteview_notification_icon"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginRight="2dp"
android:layout_weight="0"
android:scaleType="centerCrop"/>
<LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:orientation="vertical">
<TextView
android:id="@+id/remoteview_notification_headline"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textSize="12sp"/>
<TextView
android:id="@+id/remoteview_notification_short_message"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:paddingBottom="2dp"
android:singleLine="true"
android:textSize="14sp"
android:textStyle="bold"/>
</LinearLayout>
</LinearLayout>
</LinearLayout>
~~~
下面的代碼用了上面的布局文件為我們創建了一個自定義通知。
~~~
final RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.remoteview_notification);
rv.setImageViewResource(R.id.remoteview_notification_icon, R.mipmap.future_studio_launcher);
rv.setTextViewText(R.id.remoteview_notification_headline, "Headline");
rv.setTextViewText(R.id.remoteview_notification_short_message, "Short Message");
// build notification
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.future_studio_launcher)
.setContentTitle("Content Title")
.setContentText("Content Text")
.setContent(rv)
.setPriority( NotificationCompat.PRIORITY_MIN);
final Notification notification = mBuilder.build();
// set big content view for newer androids
if (android.os.Build.VERSION.SDK_INT >= 16) {
notification.bigContentView = rv;
}
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(NOTIFICATION_ID, notification);
~~~
這個代碼片段為我們創建了三個重要的對象, `notification` 和 `RemoteViews` 以及常量 `NOTIFICATION_ID`。我們會需要這些去創建一個通知 target。
~~~
private NotificationTarget notificationTarget;
...
notificationTarget = new NotificationTarget(
context,
rv,
R.id.remoteview_notification_icon,
notification,
NOTIFICATION_ID);
~~~
最后,我們要調用 Glide,正如我們之前博客所做的,將 target 作為 `.into() `的參數。
~~~
Glide
.with( context.getApplicationContext() ) // safer!
.load( eatFoodyImages[3] )
.asBitmap()
.into( notificationTarget );
~~~
**App Widgets**?
讓我們來看另一個 Glide target。 應用小部件一直以來都是 Android 的一部分。如果你的 App 提供了小部件并且包含圖像,這部分應該會讓你感興趣的。 Glide 的[AppWidgetTarget](http://bumptech.github.io/glide/javadocs/latest/com/bumptech/glide/request/target/AppWidgetTarget.html) 能顯著的讓你非常簡單的實現。
來看看一個簡單的 `AppWidgetProvider` 實例:
~~~
public class FSAppWidgetProvider extends AppWidgetProvider {
private AppWidgetTarget appWidgetTarget;
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.custom_view_futurestudio);
appWidgetTarget = new AppWidgetTarget( context, rv, R.id.custom_view_image, appWidgetIds );
Glide
.with( context.getApplicationContext() ) // safer!
.load( GlideExampleActivity.eatFoodyImages[3] )
.asBitmap()
.into( appWidgetTarget );
pushWidgetUpdate(context, rv);
}
public static void pushWidgetUpdate(Context context, RemoteViews rv) {
ComponentName myWidget = new ComponentName(context, FSAppWidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, rv);
}
}
~~~
幾行重要的代碼聲明了 `appWidgetTarget` 對象以及 Glide 的建造者。這里的好處是,你不需要去定制 `AppWidgetTarget` 并重寫任何 `AppWidgetTarget` 方法。Glide 都自動幫你做好了。太棒了!
**Outlook?**
這篇博客,我們總結了 Glide target 的一些進階方法。你已經學會如何去異步加載圖片在任何情況下, `ImageViews`,通知,Bitmap 回調等。
下次,我們要看看處理錯誤。當出現錯誤時,會發生什么?如果 URL 是不存在或者無效的情況下會發生什么?敬請期待下周的博客。
- 前言
- 一開始
- 二加載進階
- 三ListAdapter(ListView, GridView)
- 四占位符 和 漸現動畫
- 五圖片重設大小 和 縮放
- 六顯示 Gif 和 Video
- 七緩存基礎
- 八請求優先級
- 九縮略圖
- 十回調:SimpleTarget 和 ViewTarget 用于自定義視圖類
- 十一加載圖片到通知欄和應用小部件中
- 十二異常:調試和錯誤處理
- 十三自定義轉換
- 十四用 animate() 自定義動畫
- 十五集成網絡棧
- 十六用 Module 自定義
- 十七Module 實例:接受自簽名證書的 HTTPS
- 十八Module 實例:自定義緩存
- 十九Module 實例:用自定義尺寸優化加載的圖片
- 二十動態使用 Model Loader
- 二十一如何旋轉圖像
- 二十二系列綜述