`
dengyin2000
  • 浏览: 1208025 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

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

 
阅读更多
如果当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");
    }
}


布局。
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:id="@+id/RelativeLayout1"
                android:layout_width="fill_parent"
                android:layout_height="fill_parent"
                android:background="@color/red"
                android:orientation="vertical" >

    <WebView android:layout_width="fill_parent" android:layout_height="fill_parent" android:id="@+id/webview"></WebView>

    <com.example.myapp.ZenClockSurface
            android:id="@+id/zenClockSurface1"
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:layout_centerHorizontal="true"
            android:layout_centerVertical="true"/>

</RelativeLayout>



使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);
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics