class FlappyBird : SurfaceView, Runnable {
//轻量级同步,因为surfaceview是在工作线程中绘制的
@Volatile
private var isRunning = false
var xx = 0f
//以(0,0),(w,h)2点确定的矩形
private val mDestRect: RectF by lazy { RectF(0.0f, 0.0f, width.toFloat(), height.toFloat()) }
// 背景图
private val mBg: Bitmap by lazy { BitmapFactory.decodeResource(resources, R.drawable.bg1) }
//floor图
private val mFloorBm: Bitmap by lazy {
BitmapFactory.decodeResource(resources, R.drawable.floor_bg)
}
private val mThread by lazy { Thread(this) }
private var mSpeed: Int = 0
constructor(context: Context?) : super(context)
//surfaceview开始创建,从宽高旧值0,0,变成xml布局中surfaceview定义的宽高如(1080,2156)
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
Log.i("tag-->", "$w,$h,$oldw,$oldh")
}
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) {
//先执行constructor,再onSizeChanged,再surfaceCreated
holder.addCallback(object : SurfaceHolder.Callback {
override fun surfaceCreated(holder: SurfaceHolder) {
Log.i("tag-->", "surfaceCreated")
// 监听到Surface创建完毕
isRunning = true
mThread.start()
}
override fun surfaceChanged(
holder: SurfaceHolder, format: Int,
width: Int, height: Int
) {
}
override fun surfaceDestroyed(holder: SurfaceHolder) {
//surface销毁
isRunning = false
}
})
//这个surfaceview设置获得焦点等...
isFocusable = true
isFocusableInTouchMode = true
keepScreenOn = true
Log.i("tag-->", "constructor")
//2dp
mSpeed = Utils.dp2px(getContext(), 2)
}
override fun run() {
while (isRunning) {
//如果正在运行,就每隔50毫秒进行绘制
val start = System.currentTimeMillis()
drawSelf()
val end = System.currentTimeMillis()
if (end - start < 50) {
Thread.sleep(50 - (end - start))
}
}
}
//循环调用drawSelf,drawSelf自定义,其他固定写法
private fun drawSelf() {
val canvas = holder.lockCanvas()
if (canvas != null) {
//绘制背景图
canvas.drawBitmap(mBg, null, mDestRect, null)
xx -= mSpeed
canvas.save()
canvas.translate(xx, height * 4 / 5F)
Log.i("tag-->", "$xx")
val mPaint = Paint()
mPaint.shader = BitmapShader(mFloorBm, Shader.TileMode.REPEAT, Shader.TileMode.CLAMP)
canvas.drawRect(
xx, 0f, -xx + width.toFloat(), height - height * 4 / 5F, mPaint
)
canvas.restore()
mPaint.shader = null
holder.unlockCanvasAndPost(canvas)
}
}
}
补充扫二维码动画
val translateAnimation = AnimationUtils.loadAnimation(this, R.anim.translate1)
capture_scan_line.startAnimation(translateAnimation)
-----------------------------------------------------------------------------
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:fillAfter="true">
<translate
android:duration="3000"
android:fromXDelta="0"
android:fromYDelta="-100%"
android:repeatCount="-1"
android:toXDelta="0"
android:toYDelta="0" />
</set>
图片:

