TextureView的基本写法,每秒1帧随机字符串显示在屏幕中间


TextureView

SurfaceView和TextureView 两者都能在独立的线程中绘制和渲染,在专用的GPU线程中大大提高渲染的性能。
SurfaceView可以通过SurfaceHolder.addCallback方法在子线程中更新UI
TextureView则可以通过TextureView.setSurfaceTextureListener在子线程中更新UI

Surface不在View hierachy中,它的显示也不受View的属性控制,所以不能进行平移,缩放等变换,也不能放在其它ViewGroup中。SurfaceView 不能嵌套使用。
TextureView和其它普通View一样进行移动,旋转,缩放,动画等变化。

TextureView只能在开启了硬件加速的Window中使用,并且消费的内存要比SurfaceView多,并伴随着1-3帧的延迟。

每秒1帧随机字符串显示在屏幕中间。

在这里插入图片描述

package com.zhangyu.surfaceplayer;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.SurfaceTexture;
import android.util.AttributeSet;
import android.util.Log;
import android.view.TextureView;

import java.util.Random;

/**
 * TextureView的基本用法。
 */
public class MyTextureView extends TextureView implements TextureView.SurfaceTextureListener {
    private static final String TAG = "MyTextureView";
    private Thread thread;//用于绘制的线程
    private boolean isRunning;//线程的控制开关
    private Canvas canvas;
    private Paint paint;
    private int fps = 1;

    public MyTextureView(Context context) {
        this(context, null);
    }

    public MyTextureView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public MyTextureView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setSurfaceTextureListener(this);
        paint = new Paint(Paint.ANTI_ALIAS_FLAG);
        paint.setColor(Color.GREEN);
        paint.setTextSize(50);
    }

    @Override
    public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
        isRunning = true;
        thread = new Thread(new Runnable() {
            @Override
            public void run() {
                //不断绘制
                while (isRunning) {
                    long startMs = System.currentTimeMillis();
                    draw();
                    long endMs = System.currentTimeMillis();
                    long needTime = 1000 / fps;
                    long usedTime = endMs - startMs;
                    if (usedTime < needTime) {
                        try {
                            Thread.sleep(needTime - usedTime);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        thread.start();
    }

    private void draw() {
        //View被销毁,但是子线程可能还在进行操作,可能抛出一些异常
        try {
            canvas = lockCanvas();
            //按home或者back,SurfaceView被销毁,所以需要判空canvas
            if (canvas != null) {
                //todo 开始绘制
                //黑色清屏
                canvas.drawColor(Color.BLACK);
                drawTextWithCenterPoint(canvas, getWidth() / 2, getHeight() / 2, getRandomString(10), paint);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (canvas != null) {
                unlockCanvasAndPost(canvas);
            }
        }
    }

    /**
     * 获取一条随机字符串
     * @param length
     * @return
     */
    public String getRandomString(int length) { //length表示生成字符串的长度
        String base = "abcdefghijklmnopqrstuvwxyz0123456789";
        Random random = new Random();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < length; i++) {
            int number = random.nextInt(base.length());
            sb.append(base.charAt(number));
        }
        Log.e(TAG, "getRandomString: " + sb.toString());
        return sb.toString();
    }


    /**
     * 以中心点绘制文字
     *
     * @param canvas
     * @param centerX
     * @param centerY
     * @param text
     * @param paint
     */
    private void drawTextWithCenterPoint(Canvas canvas, int centerX, int centerY, String text, Paint paint) {
        //获取文本的宽度,但是是一个比较粗略的结果
        float textWidth = paint.measureText(text);
        //文字度量
        Paint.FontMetrics fontMetrics = paint.getFontMetrics();
        //得到基线的位置
        float baselineY = centerY + (fontMetrics.bottom - fontMetrics.top) / 2 - fontMetrics.bottom;
        //绘制
        canvas.drawText(text, centerX - textWidth / 2, baselineY, paint);
    }


    @Override
    public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
        isRunning = false;
        return false;
    }

    @Override
    public void onSurfaceTextureUpdated(SurfaceTexture surface) {

    }
}

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值