前期准备:
添加小组件Android Studio =>New=>AppWidget
配置详情:
widget_info.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:description="@string/app_widget_description"
android:initialKeyguardLayout="@layout/quote_widget_small"
android:initialLayout="@layout/quote_widget_small"// 初始化的layout布局
android:minWidth="110dp"// 宽度对应格子2
android:minHeight="40dp"//高度对应格子1
android:previewImage="@drawable/example_appwidget_preview"//预览外观
android:previewLayout="@layout/quote_widget_small"//预览布局仅用于 API 级别 31 及更高版本
android:resizeMode="horizontal|vertical"//指示是否以及如何调整此小部件的大小
android:targetCellWidth="2"//设置宽度格子数仅用于 API 级别 31 及更高版本
android:targetCellHeight="1"//设置高度格子数仅用于 API 级别 31 及更高版本
android:updatePeriodMillis="86400000"//设置自动刷新间隔毫秒数,最小为30分钟
android:widgetCategory="home_screen" />//设置桌面小组件
实现思路:
小组件为Remoteviews,布局受到限制。
RemoteViews
仅限于支持以下布局:
实现:RemoteViews不支持直接使用动画,所以尝试使用ViewFlipper嵌套ImageView的方式实现动图。
<ViewFlipper
android:id="@+id/flipper"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="end|center_vertical"
android:autoStart="true"
android:flipInterval="90">
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/blue"
android:scaleType="fitXY"
android:contentDescription="蓝色" />
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:src="@drawable/green"
android:scaleType="fitXY"
android:contentDescription="绿色" />
</ViewFlipper>
测试结果发现可以实现动画效果。
问题:现在是写死的,就算重新去设置图片也非常麻烦。而且每一帧的图片需要上传到drawable,再去每帧图片设置,很不科学。
拓展:如果资源文件上传一个GIF,再把GIF每一帧拆分成BitMap,再把BitMap设置成ImageView,然后作为ViewFlipper的子控件就可以了。
实现过程:
第一步:
上传GIF到Drawable文件夹。
要把GIF拆分成帧,使用 android-gif-drawable。(如果只是动画的简单显示和加载就可以使用Glide)
implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.27'
第二步:
拿到GifDrawable对象,得到GIF的每一帧。
try {
GifDrawable gifDrawable = new GifDrawable(context.getResources(), drawableIds[new Random().nextInt(drawableIds.length)]);
int frameCount = gifDrawable.getNumberOfFrames();
Log.e(TAG, "Number of frames: " + frameCount);
for (int i = 0; i < frameCount; i++) {
// 获取当前帧的 Bitmap
Bitmap frameBitmap = gifDrawable.seekToFrameAndGet(i);
}
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
} catch (IOException e) {
throw new RuntimeException(e);
}
第三步:
提前准备好一个ImageView的xml文件
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
style="@style/Widget.Android.AppWidget.Container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="0dp"
android:theme="@style/Theme.Android.AppWidgetContainer">
<ImageView
android:id="@+id/custom"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scaleType="fitXY" />
</RelativeLayout>
把拿到的每一帧BitMap对象,转换成RemoteViews。
RemoteViews views2 = new RemoteViews(context.getPackageName(), R.layout.custom_image);
views2.setImageViewBitmap(R.id.custom, frameBitmap);
第四步:
把每一帧图片生成的RemoteViews 加入到小组件的RemoteViews中的ViewFlipper下。
views.addView(R.id.flipper, views2);
完整代码
private static final String TAG = "eWidgetTall";
// static int[] drawableIds = {R.drawable.ceshi, R.drawable.ceshi2, R.drawable.ceshi3, R.drawable.ceshi4,R.drawable.ceshi6};
static int[] drawableIds = {R.drawable.ceshi8, R.drawable.ceshi};
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
CharSequence widgetText = context.getString(R.string.appwidget_text);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.quote_widget_tall);
// views.setTextViewText(R.id.appwidget_text, widgetText);
views.removeAllViews(R.id.flipper);
//点击切换Gif图
Intent intent = new Intent(context, QuoteWidgetTall.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
int[] arr = {appWidgetId};
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS,arr);
PendingIntent pendingIntent = PendingIntent
.getBroadcast(context, appWidgetId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
views.setOnClickPendingIntent(R.id.widget_tall, pendingIntent);
try {
GifDrawable gifDrawable = new GifDrawable(context.getResources(), drawableIds[new Random().nextInt(drawableIds.length)]);
int frameCount = gifDrawable.getNumberOfFrames();
Log.e(TAG, "Number of frames: " + frameCount);
for (int i = 0; i < frameCount; i++) {
// 获取当前帧的 Bitmap
Bitmap frameBitmap = gifDrawable.seekToFrameAndGet(i);
Log.e(TAG, i + " frameBitmap: " + frameBitmap);
// 在此处对获取到的 Bitmap 进行操作,例如保存到文件、显示在 ImageView 等
RemoteViews views2 = new RemoteViews(context.getPackageName(), R.layout.custom_image);
views2.setImageViewBitmap(R.id.custom, frameBitmap);
views.addView(R.id.flipper, views2);
}
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
} catch (IOException e) {
throw new RuntimeException(e);
}
}