`
dengyin2000
  • 浏览: 1225012 次
  • 性别: 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);
分享到:
评论

相关推荐

    SurfaceView

    SurfaceView提供了一种优化的绘图机制,可以将绘制操作与应用程序的主线程分离,从而避免UI阻塞,确保流畅的动画效果。 1. **SurfaceView的基本概念**: SurfaceView是一个特殊的View,它拥有一个独立的Surface,...

    Android雪花飘落动画

    在Android开发中,实现"雪花飘落动画"是一种常见的视觉效果,可以用于增强用户界面的互动性和美观性。这个主题涉及到的关键技术主要包括自定义View、绘图以及动画处理。下面我们将详细探讨这些知识点。 首先,...

    Android自动手绘,圆你儿时画家梦!

    在Android中,我们可以使用多种库来处理图像,如Android自带的Bitmap类、 Renderscript,以及第三方库如OpenCV、PIL(Python Imaging Library)的Android版本等。这些工具可以用来进行颜色空间转换、滤波、边缘检测...

    Android 扫雷游戏源码

    这可能通过Android的动画框架实现,如属性动画(Property Animation)。 9. **资源管理**:游戏可能使用到图标、音频等资源,需要了解如何在Android项目中管理和引用这些资源。 10. **错误处理与日志**:良好的...

    Android GifView-IT计算机-毕业设计.zip

    在Android应用开发中,GIF图片的处理是一个常见的需求,因为它们可以自带动画效果,为用户界面增添动态元素。传统的ImageView组件并不支持GIF格式,所以需要特别的解决方案。这个GifView项目提供了一个定制化的视图...

    安卓Android源码——SeeJoPlayer视频播放器.rar

    这些自定义控件的实现涉及Android的事件监听机制,布局管理,以及动画效果。开发者可以通过源码学习如何编写自定义视图,如何响应触摸事件,以及如何使用ObjectAnimator或ValueAnimator创建平滑的动画效果。 在音...

    Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果

    在Java代码中动态改变矩形框的位置,或者在XML布局文件中使用`ObjectAnimator`来实现动画效果。 总结,通过引入Zxing库,我们可以轻松地在Android应用中集成二维码和条形码扫描功能。结合自定义扫描界面和动画,...

    android开发资料大全

    android自带的示例程序 BluetoothChat 变蓝牙串口助手(内含DIY蓝牙遥控车附源码实例教程) Android高手过招 FAQ 网友收集的android开发书籍(可下载哦) 东软集团内部文件《android编程指南》 从零开始Android...

    android常用图片特效处理.zip

    5. **图像混合**:通过Alpha blending可以实现两张图片的混合效果,调整透明度实现不同的融合效果。 6. **动态图处理**:GIF和WebP格式的动态图在Android中也常常被使用,Glide和Picasso等库都支持动态图的加载和...

    个性进度条-

    在Android中,我们可以通过`MediaPlayer`类来播放视频,但要实现特殊的播放动画,可能需要结合使用`SurfaceView`或`TextureView`进行自定义渲染。例如,开发者可以创建一个覆盖在视频上的动画层,通过编程控制动画的...

    android超炫的图片浏览器.zip

    这需要实现手势检测,可以使用Android自带的ScaleGestureDetector和GestureDetector来处理双指缩放和平移事件。 3. 图片解码与渲染:为了优化性能,避免一次性加载大图导致内存消耗过大,可以使用BitmapFactory....

    Android Zxing二维码开发教程

    此外,为了去除ZXing自带的额外代码,可以考虑以下几点优化: 1. 只使用必要的类和方法,避免引入不必要的依赖。 2. 如果应用只需要扫描二维码,可以移除不相关的条形码解码代码。 3. 自定义扫描框样式和扫描动画,...

    安卓Android源码——远程视频监控程序源码.zip

    开发者可能使用了OkHttp、Volley等网络库进行数据传输,或者直接使用了Android自带的HttpURLConnection。此外,为了实现实时流媒体,可能还会使用到如FFmpeg这样的库进行编解码处理。 接着,视频的播放功能可能会...

    Android代码-CustomVideoView

    自定义视频视图通常需要集成媒体播放器库,如Android自带的MediaPlayer或Google推荐的ExoPlayer。MediaPlayer适用于简单视频播放,而ExoPlayer具有更强大的功能,如适应性流媒体、自定义解码器和更好的错误处理。 ...

    Android学习计划

    2. JSON解析:掌握Gson、Jackson或Android自带的JSON库,进行数据序列化和反序列化。 十、源码阅读 1. AOSP:了解Android开放源代码项目,学习系统级组件的工作原理。 2. 第三方库源码:深入研究常用的开源库,如...

    Android 小游戏飞机大战

    下面我们将深入探讨SurfaceView在游戏开发中的应用以及如何利用它来实现流畅的动画效果。 一、SurfaceView简介 SurfaceView是Android系统提供的一种特殊视图,用于在应用程序和硬件图形渲染器之间创建一个独立的、...

    Android 中的图形图像的渲染

    在Android中,我们通常使用GLSurfaceView或者SurfaceView来创建一个可以绘制OpenGL内容的视图。OpenGL ES提供了丰富的函数接口,如顶点坐标、颜色、纹理等的设置,以及Shader语言(GLSL,OpenGL Shading Language)...

    安卓Gallery照片墙画廊图库相关-3D相册图片滑动倾斜放大代码进行了实现对图片进行了处理.rar

    2. **视图动画**:通过Android的ViewPropertyAnimator或者Animation API,可以实现图片的平移、旋转和缩放效果,以达到3D滑动和放大的感觉。 3. **手势检测**:为了响应用户的滑动和捏合操作,需要集成...

    android 3d相册源码

    这个源码项目,名为“gallery3d-master”,是Android系统自带的3D相册的一个实现版本,它不仅提供了完整的功能,而且可以直接运行,对于Android开发者来说,这是一个极好的学习资源。 首先,让我们了解3D相册的基本...

Global site tag (gtag.js) - Google Analytics