最近接了个任务,在小部件(AppWidget)中播放动画。android中小部件是使用RemoteViews加载布局。但RemoteViews支持的View很少,并且不支持自定义View。
如果让RemoteViews支持自定义View,需要在将该View放到framewoke下编译。现记录实现过程如下:
1.自定义View,将class文件放到\frameworks\base\core\java\android\widget/目录下,并在代码第一行添加@RemoteViews.RemoteView标签。代码如下:
自定义的RobotAnimView是一个动画类,主要增加播放动画方法。
package android.widget; import android.R; import android.animation.ValueAnimator; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.ColorFilter; import android.graphics.Matrix; import android.graphics.PixelFormat; import android.graphics.PointF; import android.graphics.drawable.Drawable; import android.util.AttributeSet; import android.view.View; import android.view.animation.Interpolator; import android.view.animation.LinearInterpolator; import android.widget.RemoteViews; @RemoteViews.RemoteView public class RobotAnimView extends View { private WaveRobotAnimator mAnimator; public RobotAnimView(Context context) { super(context); init(); } public RobotAnimView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public RobotAnimView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } public void startRobotAnimator(boolean start) { if (start) { startRobotAnimator(); } else { endRobotAnimator(); } } public void startRobotAnimator() { init(); mAnimator.start(); } public void endRobotAnimator() { if (mAnimator != null) { if (mAnimator.isRunning()) { mAnimator.end(); } mAnimator = null; } } private void init() { endRobotAnimator(); mAnimator = new WaveRobotAnimator(getContext(), false); this.setBackground(mAnimator.getDrawable()); } private class WaveRobotAnimator extends ValueAnimator implements ValueAnimator.AnimatorUpdateListener { private RobotDrawable mDrawable; WaveRobotAnimator(Context context, boolean left) { this.setDuration(1700); this.setIntValues(0, 1700); this.setInterpolator(new LinearInterpolator()); mDrawable = new RobotDrawable(context, left); addUpdateListener(this); } @Override public void onAnimationUpdate(ValueAnimator animation) { mDrawable.update((int) (animation.getAnimatedValue())); mDrawable.invalidateSelf(); } Drawable getDrawable() { return mDrawable; } private class RobotDrawable extends Drawable { private int mTime; private Body mBody; private EyeLeft mEyeLeft; private EyeRight mEyeRight; private HandLeft mHandLeft; private HandRight mHandRight; private Head mHead; private Mouth mMouth; private int mWidth; private int mHeight; private boolean mIsLeft; RobotDrawable(Context context, boolean left) { mIsLeft = left; mBody = new Body(context); mEyeLeft = new EyeLeft(context); mEyeRight =