Skip to content

Commit c2bfcbb

Browse files
committed
Merge pull request square#388 from square/dimitris/remote-view
Add support to load into remote views.
2 parents 078115e + 3ff3046 commit c2bfcbb

File tree

16 files changed

+599
-6
lines changed

16 files changed

+599
-6
lines changed

picasso-sample/AndroidManifest.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,13 @@
3838
<activity android:name=".SampleGalleryActivity"/>
3939
<activity android:name=".SampleListDetailActivity"/>
4040

41+
<receiver android:name="SampleWidgetProvider">
42+
<intent-filter>
43+
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
44+
</intent-filter>
45+
<meta-data android:name="android.appwidget.provider"
46+
android:resource="@xml/sample_widget_info"/>
47+
</receiver>
48+
4149
</application>
4250
</manifest>
6.59 KB
Loading
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
3+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
4+
android:layout_width="match_parent"
5+
android:layout_height="match_parent"
6+
android:orientation="horizontal"
7+
>
8+
<ImageView
9+
android:id="@+id/photo"
10+
android:layout_width="wrap_content"
11+
android:layout_height="wrap_content"
12+
/>
13+
<TextView
14+
android:layout_width="0dp"
15+
android:layout_height="wrap_content"
16+
android:layout_weight="1"
17+
android:layout_marginLeft="8dp"
18+
android:layout_gravity="center_vertical"
19+
android:text="@string/sample_notification"
20+
/>
21+
</LinearLayout>
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
3+
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
4+
android:id="@+id/image"
5+
android:layout_width="match_parent"
6+
android:layout_height="match_parent"
7+
android:contentDescription="@string/sample_widget"
8+
/>

picasso-sample/res/values/dimens.xml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@
22
<resources>
33
<dimen name="faux_action_bar_size">48dp</dimen>
44
<dimen name="list_detail_image_size">60dp</dimen>
5+
<dimen name="widget_min_width">110dp</dimen>
6+
<dimen name="widget_min_height">110dp</dimen>
7+
<dimen name="notification_icon_width_height">64dp</dimen>
58
</resources>

picasso-sample/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
<string name="app_name">Picasso Samples</string>
44
<string name="hide">HIDE</string>
55
<string name="more">MORE</string>
6+
<string name="sample_widget">Picasso Sample Widget</string>
7+
<string name="sample_notification">Picasso Sample Notification</string>
68
<string name="select_picture">Select Picture</string>
79
<string name="disk_cache_description">On Ice Cream Sandwich and above, a disk cache is
810
automatically used so that subsequent requests for the same URL do not re-download the
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
3+
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
4+
android:minWidth="@dimen/widget_min_width"
5+
android:minHeight="@dimen/widget_min_height"
6+
android:updatePeriodMillis="86400000"
7+
android:initialLayout="@layout/sample_widget"
8+
android:widgetCategory="home_screen"
9+
/>
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright (C) 2014 Square, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.example.picasso;
17+
18+
import android.graphics.Bitmap;
19+
import android.graphics.BitmapShader;
20+
import android.graphics.Canvas;
21+
import android.graphics.ColorMatrix;
22+
import android.graphics.ColorMatrixColorFilter;
23+
import android.graphics.Paint;
24+
import android.graphics.PorterDuff;
25+
import android.graphics.PorterDuffXfermode;
26+
import com.squareup.picasso.Picasso;
27+
import com.squareup.picasso.Transformation;
28+
import java.io.IOException;
29+
30+
import static android.graphics.Bitmap.createBitmap;
31+
import static android.graphics.Paint.ANTI_ALIAS_FLAG;
32+
import static android.graphics.Shader.TileMode.REPEAT;
33+
34+
public class GrayscaleTransformation implements Transformation {
35+
36+
private final Picasso picasso;
37+
38+
public GrayscaleTransformation(Picasso picasso) {
39+
this.picasso = picasso;
40+
}
41+
42+
@Override public Bitmap transform(Bitmap source) {
43+
Bitmap result = createBitmap(source.getWidth(), source.getHeight(), source.getConfig());
44+
Bitmap noise;
45+
try {
46+
noise = picasso.load(R.drawable.noise).get();
47+
} catch (IOException e) {
48+
throw new RuntimeException("Failed to apply transformation! Missing resource.");
49+
}
50+
51+
BitmapShader shader = new BitmapShader(noise, REPEAT, REPEAT);
52+
53+
ColorMatrix colorMatrix = new ColorMatrix();
54+
colorMatrix.setSaturation(0);
55+
ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix);
56+
57+
Paint paint = new Paint(ANTI_ALIAS_FLAG);
58+
paint.setColorFilter(filter);
59+
60+
Canvas canvas = new Canvas(result);
61+
canvas.drawBitmap(source, 0, 0, paint);
62+
63+
paint.setColorFilter(null);
64+
paint.setShader(shader);
65+
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY));
66+
67+
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint);
68+
69+
source.recycle();
70+
noise.recycle();
71+
72+
return result;
73+
}
74+
75+
@Override public String key() {
76+
return "grayscaleTransformation()";
77+
}
78+
}

picasso-sample/src/main/java/com/example/picasso/PicassoSampleAdapter.java

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,57 @@
11
package com.example.picasso;
22

33
import android.app.Activity;
4+
import android.app.Notification;
5+
import android.app.NotificationManager;
46
import android.content.Context;
57
import android.content.Intent;
8+
import android.support.v4.app.NotificationCompat;
69
import android.view.LayoutInflater;
710
import android.view.View;
811
import android.view.ViewGroup;
912
import android.widget.BaseAdapter;
13+
import android.widget.RemoteViews;
1014
import android.widget.TextView;
15+
import com.squareup.picasso.Picasso;
16+
import java.util.Random;
1117

1218
final class PicassoSampleAdapter extends BaseAdapter {
19+
20+
private static final int NOTIFICATION_ID = 666;
21+
1322
enum Sample {
1423
GRID_VIEW("Image Grid View", SampleGridViewActivity.class),
1524
GALLERY("Load from Gallery", SampleGalleryActivity.class),
1625
CONTACTS("Contact Photos", SampleContactsActivity.class),
17-
LIST_DETAIL("List / Detail View", SampleListDetailActivity.class);
26+
LIST_DETAIL("List / Detail View", SampleListDetailActivity.class),
27+
SHOW_NOTIFICATION("Sample Notification", null) {
28+
@Override public void launch(Activity activity) {
29+
RemoteViews remoteViews =
30+
new RemoteViews(activity.getPackageName(), R.layout.notification_view);
31+
32+
NotificationCompat.Builder builder =
33+
new NotificationCompat.Builder(activity).setSmallIcon(R.drawable.icon)
34+
.setContent(remoteViews);
35+
36+
Notification notification = builder.getNotification();
37+
38+
NotificationManager notificationManager =
39+
(NotificationManager) activity.getSystemService(Context.NOTIFICATION_SERVICE);
40+
notificationManager.notify(NOTIFICATION_ID, notification);
1841

19-
private final Class<?> activityClass;
42+
// Now load an image for this notification.
43+
Picasso.with(activity) //
44+
.load(Data.URLS[new Random().nextInt(Data.URLS.length)]) //
45+
.resizeDimen(R.dimen.notification_icon_width_height,
46+
R.dimen.notification_icon_width_height) //
47+
.into(remoteViews, R.id.photo, NOTIFICATION_ID, notification);
48+
}
49+
};
2050

51+
private final Class<? extends Activity> activityClass;
2152
private final String name;
2253

23-
Sample(String name, Class<?> activityClass) {
54+
Sample(String name, Class<? extends Activity> activityClass) {
2455
this.activityClass = activityClass;
2556
this.name = name;
2657
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/*
2+
* Copyright (C) 2014 Square, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.example.picasso;
17+
18+
import android.appwidget.AppWidgetManager;
19+
import android.appwidget.AppWidgetProvider;
20+
import android.content.Context;
21+
import android.widget.RemoteViews;
22+
import com.squareup.picasso.Picasso;
23+
import java.util.Random;
24+
25+
public class SampleWidgetProvider extends AppWidgetProvider {
26+
27+
@Override
28+
public void onUpdate(final Context context, AppWidgetManager appWidgetManager,
29+
int[] appWidgetIds) {
30+
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.sample_widget);
31+
// Load image for all appWidgetIds.
32+
Picasso picasso = Picasso.with(context);
33+
picasso.load(Data.URLS[new Random().nextInt(Data.URLS.length)]) //
34+
.placeholder(R.drawable.placeholder) //
35+
.error(R.drawable.error) //
36+
.transform(new GrayscaleTransformation(picasso)) //
37+
.into(updateViews, R.id.image, appWidgetIds);
38+
}
39+
}
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright (C) 2014 Square, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package com.squareup.picasso;
17+
18+
import android.app.Notification;
19+
import android.app.NotificationManager;
20+
import android.appwidget.AppWidgetManager;
21+
import android.content.Context;
22+
import android.graphics.Bitmap;
23+
import android.widget.RemoteViews;
24+
25+
abstract class RemoteViewsAction extends Action<Void> {
26+
final RemoteViews remoteViews;
27+
final int viewId;
28+
29+
RemoteViewsAction(Picasso picasso, Request data, RemoteViews remoteViews, int viewId,
30+
int errorResId, boolean skipCache, String key) {
31+
super(picasso, null, data, skipCache, false, errorResId, null, key);
32+
this.remoteViews = remoteViews;
33+
this.viewId = viewId;
34+
}
35+
36+
@Override void complete(Bitmap result, Picasso.LoadedFrom from) {
37+
remoteViews.setImageViewBitmap(viewId, result);
38+
update();
39+
}
40+
41+
@Override public void error() {
42+
if (errorResId != 0) {
43+
setImageResource(errorResId);
44+
}
45+
}
46+
47+
void setImageResource(int resId) {
48+
remoteViews.setImageViewResource(viewId, resId);
49+
update();
50+
}
51+
52+
abstract void update();
53+
54+
static class AppWidgetAction extends RemoteViewsAction {
55+
private final int[] appWidgetIds;
56+
57+
AppWidgetAction(Picasso picasso, Request data, RemoteViews remoteViews, int viewId,
58+
int[] appWidgetIds, boolean skipCache, int errorResId, String key) {
59+
super(picasso, data, remoteViews, viewId, errorResId, skipCache, key);
60+
this.appWidgetIds = appWidgetIds;
61+
}
62+
63+
@Override void update() {
64+
AppWidgetManager manager = AppWidgetManager.getInstance(picasso.context);
65+
manager.updateAppWidget(appWidgetIds, remoteViews);
66+
}
67+
}
68+
69+
static class NotificationAction extends RemoteViewsAction {
70+
private final int notificationId;
71+
private final Notification notification;
72+
73+
NotificationAction(Picasso picasso, Request data, RemoteViews remoteViews, int viewId,
74+
int notificationId, Notification notification, boolean skipCache, int errorResId,
75+
String key) {
76+
super(picasso, data, remoteViews, viewId, errorResId, skipCache, key);
77+
this.notificationId = notificationId;
78+
this.notification = notification;
79+
}
80+
81+
@Override void update() {
82+
NotificationManager manager =
83+
(NotificationManager) picasso.context.getSystemService(Context.NOTIFICATION_SERVICE);
84+
manager.notify(notificationId, notification);
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)