android动画效果实现机制,使用android自带的动画机制很卡时可以考虑使用SurfaceView来实现动画...

本文介绍在Android中,如何通过创建并使用SurfaceView来提升动画流畅度,尤其是在Viewtree层级深且复杂时。通过SurfaceView的后台绘制避免了UI线程的阻塞,从而解决卡顿问题。关键在于设置透明背景并正确配置SurfaceView。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果当View tree很复杂,结构很深的时候, 使用动画的时候会发现即使开了硬件加速还是有些卡,这是因为android系统自带的动画是在UI线程来处理的, 而且每次需要重绘整个View tree,虽然你可以指定重新绘制的区域,不过这样比较麻烦,

SurfaceView中View的绘制不是在UI线程中,所以可以避免上面的问题。我们只要做到SurfaceView背景能够透明就行了。在需要的地方盖一层SurfaceView, 做动画时显示出来。下面是示例代码。

package com.example.myapp;

import android.content.Context;

import android.content.res.Resources;

import android.graphics.Bitmap;

import android.graphics.BitmapFactory;

import android.graphics.Canvas;

import android.graphics.Color;

import android.graphics.Matrix;

import android.graphics.Paint;

import android.graphics.Paint.Style;

import android.graphics.PixelFormat;

import android.graphics.Region;

import android.util.AttributeSet;

import android.view.Surface.OutOfResourcesException;

import android.view.SurfaceHolder;

import android.view.SurfaceView;

public class ZenClockSurface extends SurfaceView implements

SurfaceHolder.Callback {

private DrawClock drawClock;

public ZenClockSurface(Context context, AttributeSet attrs, int defStyle) {

super(context, attrs, defStyle);

getHolder().addCallback(this);

}

public ZenClockSurface(Context context) {

super(context);

getHolder().addCallback(this);

}

public ZenClockSurface(Context context, AttributeSet attrs) {

super(context, attrs);

getHolder().addCallback(this);

}

@Override

public void surfaceChanged(SurfaceHolder holder, int format, int width,

int height) {

}

@Override

public void surfaceCreated(SurfaceHolder holder) {

drawClock = new DrawClock(getHolder(), getResources());

drawClock.setRunning(true);

drawClock.start();

}

@Override

public void surfaceDestroyed(SurfaceHolder holder) {

boolean retry = true;

drawClock.setRunning(false);

while (retry) {

try {

drawClock.join();

retry = false;

} catch (InterruptedException e) {

}

}

}

class DrawClock extends Thread {

private boolean runFlag = false;

private SurfaceHolder surfaceHolder;

private Bitmap picture;

private Matrix matrix;

private Paint painter;

public DrawClock(SurfaceHolder surfaceHolder, Resources resources) {

this.surfaceHolder = surfaceHolder;

picture = BitmapFactory.decodeResource(resources,

R.drawable.ic_launcher);

matrix = new Matrix();

this.painter = new Paint();

this.painter.setStyle(Paint.Style.FILL);

this.painter.setAntiAlias(true);

this.painter.setFilterBitmap(true);

}

public void setRunning(boolean run) {

runFlag = run;

}

@Override

public void run() {

Canvas canvas;

while (runFlag) {

matrix.preRotate(1.0f, picture.getWidth() / 2,

picture.getHeight() / 2);

canvas = null;

try {

canvas = surfaceHolder.lockCanvas(null);

synchronized (surfaceHolder) {

float[] f = new float[9];

matrix.getValues(f);

float y = f[Matrix.MTRANS_Y];

matrix.postTranslate(0, 10);

canvas.drawColor(0, android.graphics.PorterDuff.Mode.CLEAR);

canvas.drawBitmap(picture, matrix, this.painter);

float[] f1 = new float[9];

matrix.getValues(f1);

float y1 = f1[Matrix.MTRANS_Y];

if (y1 >= 800) {

matrix.setTranslate(0, 0);

}

}

} catch (IllegalArgumentException e) {

// TODO Auto-generated catch block

e.printStackTrace();

} finally {

if (canvas != null) {

surfaceHolder.unlockCanvasAndPost(canvas);

}

}

}

}

}

}

调用的activity

package com.example.myapp;

import android.app.Activity;

import android.graphics.PixelFormat;

import android.os.Bundle;

import android.view.SurfaceHolder;

import android.view.View;

import android.view.ViewGroup;

import android.webkit.WebView;

import android.widget.LinearLayout;

import android.widget.ScrollView;

public class MyActivity extends Activity {

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

ZenClockSurface sfvTrack = (ZenClockSurface)findViewById(R.id.zenClockSurface1);

sfvTrack.setZOrderOnTop(true); // necessary

SurfaceHolder sfhTrack = sfvTrack.getHolder();

sfhTrack.setFormat(PixelFormat.TRANSLUCENT);

WebView webview = (WebView) findViewById(R.id.webview);

webview.getSettings().setJavaScriptEnabled(true);

webview.loadUrl("http://m.vip.com");

}

}

布局。

android:id="@+id/RelativeLayout1"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:background="@color/red"

android:orientation="vertical" >

android:id="@+id/zenClockSurface1"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_centerHorizontal="true"

android:layout_centerVertical="true"/>

使SurfaceView透明是下面这几句

ZenClockSurface sfvTrack = (ZenClockSurface)findViewById(R.id.zenClockSurface1);

sfvTrack.setZOrderOnTop(true);    // necessary

SurfaceHolder sfhTrack = sfvTrack.getHolder();

sfhTrack.setFormat(PixelFormat.TRANSLUCENT);

这句是清屏。

canvas.drawColor(0,android.graphics.PorterDuff.Mode.CLEAR);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值