SurfaceView的使用

前言

在Android中更新UI操作都需要在主线程中操作。但是SurfaceView例外,他可以在子线程中更新View,这使他可以做一些复杂的动画更新而不必担心造成主线程的阻塞。接下来就开始介绍一下SurfaceView的使用。

实现

SurfaceView通过SurfaceHolder.Callback来通知SurfaceView的创建和销毁

surfaceView.holder.addCallback(object :SurfaceHolder.Callback{
    //改变
    override fun surfaceChanged(holder: SurfaceHolder?, p1: Int, p2: Int, p3: Int) {
    }

    //销毁
    override fun surfaceDestroyed(holder: SurfaceHolder?) {
    }

    //创建
    override fun surfaceCreated(holder: SurfaceHolder?) {
    }
})

在SurfaceView创建完成之后就可以对其进行绘制了,而他的绘制是可以放在子线程中的

//获取画布
val canvas=surfaceView.holder.lockCanvas()
//提交画布
surfaceView.holder.unlockCanvasAndPost(canvas)

创建动画

下面就是一个使用SurfaceView创建动画的简单示例

class MainActivity : Activity() {
    var surfaceView: SurfaceView? = null
    var mPath = Path()
    var mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
    var mCanvas: Canvas? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        surfaceView = findViewById(R.id.surface_view)
        surfaceView.holder.addCallback(object:SurfaceHolder.Callback{
            override fun surfaceChanged(holder: SurfaceHolder?, p1: Int, p2: Int, p3: Int) {
            }

            override fun surfaceDestroyed(holder: SurfaceHolder?) {
            }

            override fun surfaceCreated(holder: SurfaceHolder?) {
                mPaint.color = Color.BLACK
                mPaint.style = Paint.Style.STROKE
                mPaint.strokeWidth = 10f
                mPaint.strokeCap = Paint.Cap.ROUND
                mPaint.strokeJoin = Paint.Join.ROUND
                mPath.moveTo(0f, 100f)
                Thread(Runnable {
                    kotlin.run {
                        draw(0)
                    }
                }).start()
            }
        })
    }

    private fun draw(x: Int) {
        if (x > 1080) {
            return
        }
        val y = (50 * Math.sin(x * Math.PI / 180) + 100).toInt()
        mPath.lineTo(x + 3f, y.toFloat())
        try {
            mCanvas = holder.svView.holder.lockCanvas()
            mCanvas?.drawColor(Color.WHITE)
            mCanvas?.drawPath(mPath, mPaint)
        } catch (e: Exception) {
            e.printStackTrace()
        } finally {
            if (mCanvas != null)
                holder.svView.holder.unlockCanvasAndPost(mCanvas)
        }
        draw(x + 3)
    }
}

其他用途

SurfaceView还可以和MediaPlayer一起使用实现视频播放,以下就是简单的示例:

class MainActivity : Activity() {
    var surfaceView: SurfaceView? = null
    val url = "https://apd-fec3435b8e24a9f3815c886baf4b7682.v.smtcdns.com/om.tc.qq.com/A3h5f3r8PilbVshgbDGWN3dyaZ8zUFk92BfD1Npo4MBA/h0560ixm63g.mp4?sdtfrom=v1103&guid=2cd4a548b5a2146345f8214435e93e24&vkey=10A496F49B3530CF50C56B617F6DB75C6A69850F6E8AD27EF01C74C9B06E07A95E952146937CD25966DF570C447F3AA1570F392682DEEDA0953F1CA68941B5C3FD7552C0D4DC7666322C5B6EF983BCB32A09AD04252FD6CB536BBBB81CC1BAD7CB31E90E1D341D675E08ED216DCA77E0D868B2EE67C3D6F5&platform=2"
    val player = MediaPlayer() 

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        surfaceView = findViewById(R.id.surface_view)
        Thread(Runnable {
            player.setDataSource(this, Uri.parse(url))
            player.prepare()
        }).start()        
        surfaceView.holder.addCallback(object:SurfaceHolder.Callback{
            override fun surfaceChanged(holder: SurfaceHolder?, p1: Int, p2: Int, p3: Int) {
            }

            override fun surfaceDestroyed(holder: SurfaceHolder?) {
            }

            override fun surfaceCreated(holder: SurfaceHolder?) {
                player.setDisplay(holder)
            }
        })
        player.setOnPreparedListener(object : MediaPlayer.OnPreparedListener {
            override fun onPrepared(p0: MediaPlayer?) {
                player.start()
                player.isLooping = true
            }
        })
    }
}

参考

SurfaceView
Android之SurfaceView使用总结
Android SurfaceView的使用
android中使用surfaceview+MediaPlayer播放视频

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值