史上最全SurfaceView使用讲解

  • Post author:
  • Post category:其他

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")
    }
}

版权声明:本文为qq_41885673原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。