史上最全SurfaceView使用讲解

本文对比了SurfaceView和View在Android开发中的关键区别,包括刷新机制、线程处理和双缓冲技术。重点介绍了如何通过SurfaceView实现自定义绘制,以及两种方式的实践示例。适合频繁刷新需求的应用场景。

SurfaceView 与 View 的区别

1、View主要适用于主动更新的情况下,而SurfaceView主要适用于被动更新,例如频繁地刷新。
2、View 在主线程中对画面进行刷新,而 SurfaceView 通常会通过一个子线程来进行页面的刷新。
3、View 在绘图时没有使用双缓冲机制,而 SurfaceView 在底层实现机制中就已经实现了双缓冲机制

总结,如果需要频繁刷新,或者刷新时数据处理量比较大,那么可以考虑使用 SurfaceView 。

SurfaceView的使用

方式一:直接使用 SurfaceView

  • xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <SurfaceView
        android:id="@+id/sfv_draw"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
  • kotlin逻辑文件
package com.example.study01

import android.graphics.Color
import android.graphics.Paint
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.SurfaceHolder
import android.view.SurfaceView

class MainActivity : AppCompatActivity(), SurfaceHolder.Callback {

    private val sfv_draw by lazy { findViewById<SurfaceView>(R.id.sfv_draw) }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        sfv_draw.holder.addCallback(this)
    }

    override fun surfaceCreated(p0: SurfaceHolder) {
        val mPaint = Paint()
        mPaint.color = Color.WHITE
        mPaint.isDither = true
        mPaint.isAntiAlias = true
        mPaint.style = Paint.Style.FILL_AND_STROKE
        val mCanvas = p0.lockCanvas()
        mCanvas.drawRect(0F, 0F, 100F, 100F, mPaint)
        p0.unlockCanvasAndPost(mCanvas)
    }

    override fun surfaceChanged(p0: SurfaceHolder, p1: Int, p2: Int, p3: Int) {
        println("我被执行了 surfaceChanged")
    }

    override fun surfaceDestroyed(p0: SurfaceHolder) {
        println("我被执行了 surfaceDestroyed")
    }
}

1、通过 SurfaceHolder 添加  SurfaceHolder.Callback 回调

2、通过 SurfaceHolder.lockCanvas() 获得一个Canvas对象用于绘制。

3、通过 SurfaceHolder.unlockCanvasAndPost() 方法传入Canvas对象完成更新。

方式二:继承 SurfaceView 实现自定义View

  • xml布局文件
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <com.example.study01.MySurfaceView
        android:id="@+id/sfv_draw"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</androidx.constraintlayout.widget.ConstraintLayout>
  • kotlin逻辑代码
package com.example.study01

import android.content.Context
import android.graphics.Color
import android.graphics.Paint
import android.util.AttributeSet
import android.view.SurfaceHolder
import android.view.SurfaceView

class MySurfaceView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
    SurfaceView(context, attrs, defStyleAttr), SurfaceHolder.Callback {

    constructor(context: Context, attrs: AttributeSet) : this(context, attrs, 0)
    constructor(context: Context) : this(context, null, 0)

    init {
        holder.addCallback(this)
    }

    override fun surfaceCreated(p0: SurfaceHolder) {
        val mPaint = Paint()
        mPaint.color = Color.WHITE
        mPaint.isDither = true
        mPaint.isAntiAlias = true
        mPaint.style = Paint.Style.FILL_AND_STROKE
        val mCanvas = p0.lockCanvas()
        mCanvas.drawRect(0F, 0F, 100F, 100F, mPaint)
        p0.unlockCanvasAndPost(mCanvas)
    }

    override fun surfaceChanged(p0: SurfaceHolder, p1: Int, p2: Int, p3: Int) {
        println("我被执行了 surfaceChanged")
    }

    override fun surfaceDestroyed(p0: SurfaceHolder) {
        println("我被执行了 surfaceDestroyed")
    }
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

super码王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值