最近在写 AppWidget 的时候,想实现一个淡入的动画效果,由于 AppWidget 只支持几种 view 并且没有提供实现动画的方法,折腾了很久发现只有使用 LayoutAnimation 可以勉强实现动画效果。
这里就拿淡入动画作为例子。首先在 res/anim
中新建一个动画 fade_in.xml
:
1 2 3 4 5 6
| <?xml version="1.0" encoding="utf-8"?> <alpha xmlns:android="http://schemas.android.com/apk/res/android" android:duration="1200" android:fromAlpha="0.0" android:interpolator="@android:anim/accelerate_interpolator" android:toAlpha="0.8"/>
|
然后再新建一个 layoutAnimation,widget_fade_in.xml
:
1 2
| <layoutAnimation xmlns:android="http://schemas.android.com/apk/res/android" android:animation="@anim/fade_in"/>
|
动画效果准备好后,接下来就是在 AppWidget 布局中使用了。比如 AppWidget 的布局,widget_layout.xml
如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/widget_bg">
<RelativeLayout android:id="@+id/widget_layout_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layoutAnimation="@anim/widget_fade_in">
<ImageView android:id="@+id/widget_iv" android:layout_width="100.0dip" android:layout_height="100.0dip" android:layout_centerInParent="true"/>
</RelativeLayout>
<TextView android:id="@+id/widget_tv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/app_name"> </TextView>
</LinearLayout>
|
要让 ImageView 实现淡入动画,需要将其单独加入到一个 layout 中,然后在 layout 中加入 android:layoutAnimation="@anim/widget_fade_in"
。这样 ImageView 所在的 layout 就有动画效果了,不过这个动画效果只会在 AppWidget 第一次加载的时候有,如果想每隔一段时间去切换,就需要让 AppWidget 不断的实现重新加载的过程,需要使用到 RemoteViews 的 removeAllViews 和 addView 方法,这两个方法可以让 AppWidget 的 layout 刷新来实现重复动画的效果。再新建一个 layout 文件 widget_image.xml
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/widget_layout_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:layoutAnimation="@anim/widget_fade_in">
<ImageView android:id="@+id/widget_iv" android:layout_width="100.0dip" android:layout_height="100.0dip" android:layout_centerInParent="true"/>
</RelativeLayout>
|
这里面的内容保持和 widget_layout.xml
中要实现动画的 layout 一致就行了。
最后需要在 AppWidgetProvider 中使用 removeAllViews 和 addView 方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class ExampleWidget extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { updateWidget(context, appWidgetManager, appWidgetIds); }
public static void updateWidget(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { String pkgName = context.getPackageName(); RemoteViews views = new RemoteViews(pkgName, R.layout.widget_layout); RemoteViews subView = new RemoteViews(pkgName, R.layout.widget_image); views.removeAllViews(R.id.widget_layout); views.addView(R.id.widget_layout, subView); } }
|
最后就是在 Activity 或者 Service 中,在需要更新的时候调用 updateWidget
就有动画效果了。