我实现了一个自定义,它通过动画View
应用自定义。即应用程序放大到更大位图的某个点(位图比屏幕大)。在更高分辨率的设备上(例如三星 Galaxy S3,它是 x-hdpi),缩放(实际上是缩放+平移)过程会严重闪烁和卡顿。(更准确地说,图像的许多部分闪烁,其他部分都可以。例如图像中包含的文本标题闪烁。)在其他设备上也有一些闪烁,例如Desire HD。(请注意,自定义 View 是必需的,因为稍后我也会在其上应用其他自定义动画,但现在无关紧要。)ScaleAnimation/TranslateAnimation
getTransformation()
当动画开始时,位图被缩小(即从“距离”可见)。动画同时放大和平移。
我认为位图可能太大(实际上它并不小),但我尝试了一切都没有运气:我将正确的版本放入 hdpi、xhpdi 等,我也尝试使用较小尺寸的位图,我尝试通过 进行下采样decodeResource()
,但没有帮助。
实际上,自定义View
包含一个名为MyBackgroundDrawable
. 该类MyBackgroundDrawable
处理动画并绘制转换后的位图。
这是onDraw()
自定义的代码View
:
@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
mMyBackgroundDrawable.draw(canvas); // my custom Drawable
invalidate();
}
这就是我加载位图的方式:
Resources res = context.getResources();
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inScaled = false;
Bitmap bmp = BitmapFactory.decodeResource(res, R.drawable.mybackground, opt);
Drawable mMyDrBackground = new BitmapDrawable(res, bmp);
这是(即我的自定义)的draw()
方法:mMyBackgroundDrawable
Drawable
@Override
public void draw(Canvas canvas) {
int sc = canvas.save();
sWorld.reset(); // this is a Matrix
if (mMyAnimation!= null) {
mMyAnimation.getTransformation(AnimationUtils.currentAnimationTimeMillis(), mTransformation);
sWorld = mTransformation.getMatrix();
}
sMatrix.reset();
sMatrix.preTranslate(sViewportX / 2, sViewportY / 2);
sMatrix.preConcat(sWorld);
sMatrix.preConcat(mPosition);
canvas.setMatrix(sMatrix);
mMyDrBackground .draw(canvas);
canvas.restoreToCount(sc);
}
实际上,mMyAnimation
是一个AnimationSet
,并且(当闪烁发生时),它正在播放一个TranslateAnimation+ScaleAnimation
(同时,因为我正在缩放并同时移动到位图的某个点)。
为什么会出现闪烁和卡顿,如何解决?
更新:我没有onMeasure()
为自定义实现View
。这会导致这样的问题吗?我的自定义视图被添加到这个布局中(即到layoutRoot
):
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:id="@+id/layoutRoot" >
</RelativeLayout>