Android小技巧:在通知RemoteViews中显示动画

1,651 阅读1分钟

在Android Notification显示中,我们通常显示一些静态元素,即便使用自定义布局,也不例外,因为RemoteViews有着诸多限制,例如使用的控件只有那些个基本控件,更新界面也必须通过RemoteViews提供的各种set方法。但有时候,我们就是想要去显示动画,因为动画可以提供更好的视觉效果。那么本文提供两种较简单的方法。

代码示例见:gitee.com/spectre1225…

方法一:使用ViewFlipper来实现逐帧动画的效果

第一种方法是利用RemoteViews支持的ViewFlipper控件配合多个ImageView来循环显示,达到类似逐帧动画的效果。自定义通知布局中的对应内容是:

<ViewFlipper
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:layout_gravity="end|center_vertical"
    android:autoStart="true"
    android:flipInterval="90">

    <ImageView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/stat_sys_battery_charge_anim0" />

    <ImageView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/stat_sys_battery_charge_anim15" />

    <ImageView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/stat_sys_battery_charge_anim28" />

    <ImageView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/stat_sys_battery_charge_anim43" />

    <ImageView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/stat_sys_battery_charge_anim57" />

    <ImageView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/stat_sys_battery_charge_anim71" />

    <ImageView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/stat_sys_battery_charge_anim85" />

    <ImageView
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:src="@drawable/stat_sys_battery_charge_anim100" />
</ViewFlipper>

Java代码中不需要额外设置。注意这里的ViewFlipper要设置android:autoStart="true",这样动画才会自动播放起来。

  • 优点:各版本系统兼容性好,都可以使用。
  • 缺点:ImageView过多,代码也多,修改替换麻烦。

方法二:使用AnimatedImageDrawable来显示GIF动画

Android 9.0 中引入了一个新的Drawable来显示GIF图片:AnimatedImageDrawable,对应的xml标签是<animated-image>,这样一来,我们可以直接将一个GIF图片ic_test_gif.gif放到drawable目录中,然后新建一个ic_anim_gif.xml来引用:

<?xml version="1.0" encoding="utf-8"?>
<animated-image xmlns:android="http://schemas.android.com/apk/res/android"
    android:autoStart="true"
    android:autoMirrored="true"
    android:src="@drawable/ic_test_gif" />

在自定义通知布局中直接编写:

<ImageView
    android:id="@+id/iv_logo"
    android:layout_width="40dp"
    android:layout_height="40dp"
    android:src="@drawable/ic_anim_gif" />

这里ImageViewsrc不直接引用gif图片是因为需要用到animated-imageautoStart属性,毕竟RemoteViews没法直接取出ImageView的drawable。

考虑到系统版本兼容,可以选择在代码中将动画资源设置给ImageView

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
    remoteViews.setImageViewResource(R.id.iv_logo, R.drawable.ic_anim_gif);
}

这种方法优缺点如下:

  • 优点:资源少,一个gif,只要一个animated-image的xml,且替换简单。
  • 缺点:只有Android 9.0 以上的系统可以用。