欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Android實現(xiàn)九宮格手勢密碼

 更新時間:2022年06月28日 17:15:14   作者:xinhengqq  
這篇文章主要為大家詳細介紹了Android實現(xiàn)九宮格手勢密碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下

本文實例為大家分享了Android實現(xiàn)九宮格手勢密碼的具體代碼,供大家參考,具體內(nèi)容如下

介紹下自己編寫的九宮格手勢密碼。先見圖

思路:首先是9個格子,接著是格子連線;那么我們的步驟就有了。

1.手勢監(jiān)聽,進行連線
2.格子的狀態(tài)未連接(初始狀態(tài))、已連接的(沒有結(jié)果前)、錯誤狀態(tài)(有結(jié)果后)。(先這三個,可擴展,比如按下狀態(tài))
3.自定義viewgroup作為九宮格的容器,里面包含9個view(小格子)

一、先從簡單的說起吧,9個小格子以及狀態(tài)

為了擴展性,不自定義view,將三個狀態(tài)和有關(guān)屬性提取

1.提取屬性,代碼如下: 

class NineChildInf {
? ? ? ? /**
? ? ? ? ?* 當(dāng)前所在9宮格的位置
? ? ? ? ?* 從1開始
? ? ? ? ?*/
? ? ? ? var index = 0
? ? ? ? /**
? ? ? ? ?* 是否被點亮
? ? ? ? ?*/
? ? ? ? var isLight = false
? ? ? ? /**
? ? ? ? ?* 中心點所在父類容器內(nèi)的坐標
? ? ? ? ?*/
? ? ? ? var centerX = 0.toFloat()
? ? ? ? var centerY = 0.toFloat()
?
? ? ? ? fun setContent(index: Int, centerX: Float, centerY: Float) {
? ? ? ? ? ? this.index = index
? ? ? ? ? ? this.centerX = centerX
? ? ? ? ? ? this.centerY = centerY
? ? ? ? }
?
? ? ? ? constructor()
?
? ? ? ? fun updateCenterPoint(x: Float, y: Float) {
? ? ? ? ? ? this.centerX = x
? ? ? ? ? ? this.centerY = y
? ? ? ? }
?
? ? ? ? fun reset() {
? ? ? ? ? ? this.index = 0
? ? ? ? ? ? this.centerX = 0f
? ? ? ? ? ? this.centerY = 0f
? ? ? ? ? ? this.isLight = false
? ? ? ? }
?
? ? ? ? override fun toString(): String {
? ? ? ? ? ? return "NineChildInf(index=$index, isLight=$isLight, centerX=$centerX, centerY=$centerY)"
? ? ? ? }
? ? }

2.三個狀態(tài),代碼如下

/**
?* Created by XinHeng on 2019/02/27.
?* describe:9宮格子view必須實現(xiàn)此接口
?*/
abstract class NineChildParent<T : View>(var view: T) {
? ? protected open var context = view.context.applicationContext
? ? val NINE_CHILD_INF = NineChildInf()
? ? /**
? ? ?* 密碼錯誤時的顯示
? ? ?*/
? ? abstract fun setErrorStatue()
?
? ? /**
? ? ?* 被選中時的顯示
? ? ?*/
? ? abstract fun setLightStatue()
?
? ? /**
? ? ?* 默認顯示
? ? ?*/
? ? abstract fun setDefaultStatue()
?
}

二、自定義九宮格容器,NineViewGroup。

既然是九宮格,那自然少不了這些屬性,水平間隔、垂直間隔、最小有效連接數(shù)、當(dāng)前狀態(tài)、密碼是否設(shè)置完成等。還需要將開啟viewgroup的onDraw()方法。具體代碼如下:

class NineViewGroup @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ViewGroup(context, attrs, defStyleAttr) {
? ? /**
? ? ?* 水平間的間隔
? ? ?*/
? ? private var paddingH = 60
? ? /**
? ? ?* 垂直間的間隔
? ? ?*/
? ? private var paddingV = 60
? ? /**
? ? ?* 連線最小有效數(shù)字
? ? ?*/
? ? var minEffectiveSize = 4
? ? /**
? ? ?* 小格子的寬高
? ? ?*/
? ? private var childSlide: Int = 30
? ? private val ERROR_STATUE = 2
? ? private val LINKING_STATUE = 1
? ? private val DEFAULT_STATUE = 0
? ? /**
? ? ?* 當(dāng)前狀態(tài)
? ? ?* 0->最初狀態(tài) DEFAULT_STATUE
? ? ?* 1->正在連線中 LINKING_STATUE
? ? ?* 2->錯誤狀態(tài) ERROR_STATUE
? ? ?*/
? ? private var nowStatue = DEFAULT_STATUE
? ? /**
? ? ?* 一次密碼設(shè)置完成標志
? ? ?*/
? ? private var complete = false
? ? /**
? ? ?* 線條寬度
? ? ?*/
? ? private var lineWidth = 5
? ? private var lineColor = Color.parseColor("#33b5e5")
? ? private var errorLineColor = Color.RED
? ? private var childViews = ArrayList<NineChildParent<*>>(9)
? ? init {
? ? ? ? //使能調(diào)用onDraw()方法
? ? ? ? setWillNotDraw(false)
? ? ? ? var array = context.obtainStyledAttributes(attrs, R.styleable.NineViewGroup, defStyleAttr, 0)
? ? ? ? (0..array.indexCount).forEach {
? ? ? ? ? ? var index = array.getIndex(it)
? ? ? ? ? ? when (index) {
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_child_size -> childSlide = array.getDimensionPixelSize(index, childSlide)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_line_color -> lineColor = array.getColor(index, lineColor)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_error_line_color -> errorLineColor = array.getColor(index, errorLineColor)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_effective_size -> minEffectiveSize = array.getInt(index, minEffectiveSize)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_padding_h -> paddingH = array.getDimensionPixelSize(index, paddingH)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_padding_v -> paddingV = array.getDimensionPixelSize(index, paddingV)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_line_width -> lineWidth = array.getDimensionPixelSize(index, lineWidth)
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? array.recycle()
? ? ??
? ? }
? ? override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
? ? ? ? var width = childSlide * 3 + paddingLeft + paddingRight + paddingH * 2
? ? ? ? var height = childSlide * 3 + paddingTop + paddingBottom + paddingV * 2
? ? ? ? setMeasuredDimension(width, height)
? ? ? ? //又忘了計算子view的大小了。。。
? ? ? ? measureChildren(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY))
? ? }
? ? override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
? ? ? ? var childView: View
? ? ? ? var top: Int = paddingTop
? ? ? ? var left: Int = paddingLeft
? ? ? ? var right: Int
? ? ? ? var bottom: Int
? ? ? ? if (childCount > 0) {
? ? ? ? ? ? (0 until childCount).forEach {
? ? ? ? ? ? ? ? childView = getChildAt(it)
? ? ? ? ? ? ? ? right = left + childView.measuredWidth
? ? ? ? ? ? ? ? bottom = top + childView.measuredHeight
? ? ? ? ? ? ? ? //Log.e("TAG", "onLayout: $left $top $right $bottom")
? ? ? ? ? ? ? ? var nineChildInf = (childViews[it]).NINE_CHILD_INF
? ? ? ? ? ? ? ? nineChildInf.setContent(it + 1, (left + right) / 2f, (top + bottom) / 2f)
? ? ? ? ? ? ? ? //Log.e("TAG", "onLayout: child=$nineChildInf")
? ? ? ? ? ? ? ? childView.layout(left, top, right, bottom)
? ? ? ? ? ? ? ? if ((it + 1) % 3 == 0) {
? ? ? ? ? ? ? ? ? ? left = paddingLeft
? ? ? ? ? ? ? ? ? ? top = bottom + paddingV
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? left = right + paddingH
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
}

三、手勢監(jiān)聽、連線

1.手勢監(jiān)聽,重寫onTouchEvent()方法,必要需要時重寫onInterceptTouchEvent()方法進行攔截(跟情況而定,這里就不多說了)。簡單的三個手勢狀態(tài)按下、移動、抬起。在各個狀態(tài)下,記錄坐標,并且更新子view(小格子)的ui,還有線條。代碼片段如下:

override fun onTouchEvent(event: MotionEvent): Boolean {
? ? ? ? if (childCount == 0 || complete) {
? ? ? ? ? ? return super.onTouchEvent(event)
? ? ? ? }
? ? ? ? when (event.action) {
? ? ? ? ? ? MotionEvent.ACTION_DOWN -> {
? ? ? ? ? ? ? ? //記錄落點
? ? ? ? ? ? ? ? lastX = event.x
? ? ? ? ? ? ? ? lastY = event.y
? ? ? ? ? ? ? ? downUpdateChild(lastX, lastY)
? ? ? ? ? ? }
? ? ? ? ? ? MotionEvent.ACTION_MOVE -> {
? ? ? ? ? ? ? ? lastX = event.x
? ? ? ? ? ? ? ? lastY = event.y
? ? ? ? ? ? ? ? moveUpdateChild(lastX, lastY)
? ? ? ? ? ? }
? ? ? ? ? ? MotionEvent.ACTION_UP -> {
? ? ? ? ? ? ? ? complete = true
? ? ? ? ? ? ? ? //統(tǒng)計
? ? ? ? ? ? ? ? upUpdateChild()
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return true
? ? }

2.連線,在容器的onDraw()方法,進行畫線操作,代碼片段如下:

override fun onDraw(canvas: Canvas) {
? ? ? ? super.onDraw(canvas)
? ? ? ? if (!showLine) {
? ? ? ? ? ? return
? ? ? ? }
? ? ? ? paint.color = when (nowStatue) {
? ? ? ? ? ? ERROR_STATUE -> errorLineColor
? ? ? ? ? ? else -> lineColor
? ? ? ? }
? ? ? ? if (points.size > 1) {
? ? ? ? ? ? (1 until points.size).forEach {
? ? ? ? ? ? ? ? var pointXYStart = points[it - 1].NINE_CHILD_INF
? ? ? ? ? ? ? ? var pointXYEnd = points[it].NINE_CHILD_INF
? ? ? ? ? ? ? ? canvas.drawLine(pointXYStart.centerX, pointXYStart.centerY, pointXYEnd.centerX, pointXYEnd.centerY, paint)
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? if (lastX > 0 && points.size > 0) {
? ? ? ? ? ? var pointXY = points[points.size - 1].NINE_CHILD_INF
? ? ? ? ? ? canvas.drawLine(pointXY.centerX, pointXY.centerY, lastX, lastY, paint)
? ? ? ? }
? ? }

四、進行到這一步,大致的步驟就是這了。

但是還有一些細節(jié):比如連線中需要判斷中間是否含有小格子、判斷觸點是否在小格子上、連接完成后的回調(diào)、錯誤狀態(tài)顯示、恢復(fù)初始狀態(tài)等。粘出部分代碼片段(這些只是能實現(xiàn)效果,還可以優(yōu)化,交給大家了):

1.判斷觸點是否在小格子上

private fun childContains(x: Float, y: Float): Boolean {
? ? ? ? (0 until childCount).forEach {
? ? ? ? ? ? var childAt = getChildAt(it)
? ? ? ? ? ? //這一句,循環(huán)判斷,是否屬于其范圍
? ? ? ? ? ? if (x >= childAt.left && x < childAt.right && y >= childAt.top && y < childAt.bottom) {
? ? ? ? ? ? ? ? return if (!childViews[it].NINE_CHILD_INF.isLight) {
? ? ? ? ? ? ? ? ? ? if (points.size > 0) {
? ? ? ? ? ? ? ? ? ? ? ? checkMiddleChild(points[points.size - 1], childViews[it])?.run {
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (!NINE_CHILD_INF.isLight) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? buffer.append(NINE_CHILD_INF.index)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? changeLightStatue(this)
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? buffer.append(it + 1)
? ? ? ? ? ? ? ? ? ? //TODO 改變子view的UI狀態(tài)
? ? ? ? ? ? ? ? ? ? changeLightStatue(childViews[it])
? ? ? ? ? ? ? ? ? ? true
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? false
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return false
? ? }

2.判斷中間是否含有小格子

private fun checkMiddleChild(nineChildParent: NineChildParent<*>, nineChildParent1: NineChildParent<*>): NineChildParent<*>? {
? ? ? ? var index = nineChildParent.NINE_CHILD_INF.index
? ? ? ? var index1 = nineChildParent1.NINE_CHILD_INF.index
? ? ? ? var sum = index + index1
? ? ? ? if (sum == 10) {
? ? ? ? ? ? return childViews[4]
? ? ? ? } else if (index % 2 != 0 && index1 % 2 != 0) {
? ? ? ? ? ? if ((sum == 4 || sum == 16) || (sum == 8 && (index == 1 || index1 == 1))||(sum == 12 && (index == 3 || index1 == 3)))
? ? ? ? ? ? ? ? return childViews[sum / 2 - 1]
? ? ? ? }
? ? ? ? return null
? ? }

五、如有bug歡迎留言指出,下面粘出九宮格容器的全部代碼。

/**
?* Created by XinHeng on 2019/01/29.
?* describe:九宮格的容器
?*/
class NineViewGroup @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : ViewGroup(context, attrs, defStyleAttr) {
? ? /**
? ? ?* 水平間的間隔
? ? ?*/
? ? private var paddingH = 60
? ? /**
? ? ?* 垂直間的間隔
? ? ?*/
? ? private var paddingV = 60
? ? /**
? ? ?* 是否有第一個選中
? ? ?*/
? ? private var firstSelect = true
? ? private val ERROR_STATUE = 2
? ? private val LINKING_STATUE = 1
? ? private val DEFAULT_STATUE = 0
? ? /**
? ? ?* 是否顯示線條
? ? ?*/
? ? var showLine = false
? ? /**
? ? ?* 連線最小有效數(shù)字
? ? ?*/
? ? var minEffectiveSize = 4
? ? /**
? ? ?* 當(dāng)前狀態(tài)
? ? ?* 0->最初狀態(tài) DEFAULT_STATUE
? ? ?* 1->正在連線中 LINKING_STATUE
? ? ?* 2->錯誤狀態(tài) ERROR_STATUE
? ? ?*/
? ? private var nowStatue = DEFAULT_STATUE
? ? /**
? ? ?* 一次密碼設(shè)置完成標志
? ? ?*/
? ? private var complete = false
? ? /**
? ? ?* 線條寬度
? ? ?*/
? ? private var lineWidth = 5
? ? private var lastX: Float = 0f
? ? private var lastY: Float = 0f
? ? private var buffer = StringBuilder()
? ? private var points = ArrayList<NineChildParent<*>>(9)
? ? private var childViews = ArrayList<NineChildParent<*>>(9)
? ? /**
? ? ?* 小格子的寬高
? ? ?*/
? ? private var childSlide: Int = 30
? ? private var lineColor = Color.parseColor("#33b5e5")
? ? private var errorLineColor = Color.RED
? ? var onNineViewGroupListener: OnNineViewGroupListener? = null
? ? ? ? set(value) {
? ? ? ? ? ? field = value
? ? ? ? ? ? value?.let {
? ? ? ? ? ? ? ? setChildMode(it)
? ? ? ? ? ? }
? ? ? ? }
? ? private val paint = Paint().apply {
? ? ? ? isAntiAlias = true
? ? ? ? isDither = true
? ? }
?
? ? init {
? ? ? ? //使能調(diào)用onDraw()方法
? ? ? ? setWillNotDraw(false)
? ? ? ? var array = context.obtainStyledAttributes(attrs, R.styleable.NineViewGroup, defStyleAttr, 0)
? ? ? ? (0..array.indexCount).forEach {
? ? ? ? ? ? var index = array.getIndex(it)
? ? ? ? ? ? when (index) {
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_child_size -> childSlide = array.getDimensionPixelSize(index, childSlide)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_line_color -> lineColor = array.getColor(index, lineColor)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_error_line_color -> errorLineColor = array.getColor(index, errorLineColor)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_effective_size -> minEffectiveSize = array.getInt(index, minEffectiveSize)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_padding_h -> paddingH = array.getDimensionPixelSize(index, paddingH)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_padding_v -> paddingV = array.getDimensionPixelSize(index, paddingV)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_show_line -> showLine = array.getBoolean(index, showLine)
? ? ? ? ? ? ? ? R.styleable.NineViewGroup_nine_line_width -> lineWidth = array.getDimensionPixelSize(index, lineWidth)
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? array.recycle()
? ? ? ? paint.strokeWidth = lineWidth.toFloat()
? ? }
?
? ? private fun setChildMode(onNineViewGroupListener: OnNineViewGroupListener) {
? ? ? ? removeAllViews()
? ? ? ? childViews.clear()
? ? ? ? (0..8).forEach {
? ? ? ? ? ? var mode = onNineViewGroupListener.getChildMode()
? ? ? ? ? ? mode.NINE_CHILD_INF.index = it + 1
? ? ? ? ? ? mode.setDefaultStatue()
? ? ? ? ? ? addView(mode.view, getLp())
? ? ? ? ? ? childViews.add(mode)
? ? ? ? }
? ? }
?
? ? private fun getLp(): LayoutParams {
? ? ? ? return LayoutParams(childSlide, childSlide)
? ? }
?
? ? override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
? ? ? ? var width = childSlide * 3 + paddingLeft + paddingRight + paddingH * 2
? ? ? ? var height = childSlide * 3 + paddingTop + paddingBottom + paddingV * 2
? ? ? ? setMeasuredDimension(width, height)
? ? ? ? //又忘了計算子view的大小了。。。
? ? ? ? measureChildren(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY))
? ? }
?
? ? override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
? ? ? ? var childView: View
? ? ? ? var top: Int = paddingTop
? ? ? ? var left: Int = paddingLeft
? ? ? ? var right: Int
? ? ? ? var bottom: Int
? ? ? ? if (childCount > 0) {
? ? ? ? ? ? (0 until childCount).forEach {
? ? ? ? ? ? ? ? childView = getChildAt(it)
? ? ? ? ? ? ? ? right = left + childView.measuredWidth
? ? ? ? ? ? ? ? bottom = top + childView.measuredHeight
? ? ? ? ? ? ? ? //Log.e("TAG", "onLayout: $left $top $right $bottom")
? ? ? ? ? ? ? ? var nineChildInf = (childViews[it]).NINE_CHILD_INF
? ? ? ? ? ? ? ? nineChildInf.setContent(it + 1, (left + right) / 2f, (top + bottom) / 2f)
? ? ? ? ? ? ? ? //Log.e("TAG", "onLayout: child=$nineChildInf")
? ? ? ? ? ? ? ? childView.layout(left, top, right, bottom)
? ? ? ? ? ? ? ? if ((it + 1) % 3 == 0) {
? ? ? ? ? ? ? ? ? ? left = paddingLeft
? ? ? ? ? ? ? ? ? ? top = bottom + paddingV
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? left = right + paddingH
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
?
? ? override fun onInterceptTouchEvent(ev: MotionEvent?): Boolean {
? ? ? ? return true
? ? }
? ? override fun onTouchEvent(event: MotionEvent): Boolean {
? ? ? ? if (childCount == 0 || complete) {
? ? ? ? ? ? return super.onTouchEvent(event)
? ? ? ? }
? ? ? ? when (event.action) {
? ? ? ? ? ? MotionEvent.ACTION_DOWN -> {
? ? ? ? ? ? ? ? //記錄落點
? ? ? ? ? ? ? ? lastX = event.x
? ? ? ? ? ? ? ? lastY = event.y
? ? ? ? ? ? ? ? downUpdateChild(lastX, lastY)
? ? ? ? ? ? }
? ? ? ? ? ? MotionEvent.ACTION_MOVE -> {
? ? ? ? ? ? ? ? lastX = event.x
? ? ? ? ? ? ? ? lastY = event.y
? ? ? ? ? ? ? ? moveUpdateChild(lastX, lastY)
? ? ? ? ? ? }
? ? ? ? ? ? MotionEvent.ACTION_UP -> {
? ? ? ? ? ? ? ? complete = true
? ? ? ? ? ? ? ? //統(tǒng)計
? ? ? ? ? ? ? ? upUpdateChild()
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return true
? ? }
?
? ? private fun downUpdateChild(x: Float, y: Float) {
? ? ? ? firstSelect = childContains(x, y)
? ? }
?
? ? private fun moveUpdateChild(x: Float, y: Float) {
? ? ? ? if (firstSelect) {
? ? ? ? ? ? moveUpdateLineAndChildView(x, y)
? ? ? ? } else {
? ? ? ? ? ? downUpdateChild(x, y)
? ? ? ? }
? ? }
?
? ? private fun moveUpdateLineAndChildView(x: Float, y: Float) {
? ? ? ? if (points.size != childCount)
? ? ? ? ? ? childContains(x, y)
? ? ? ? invalidate()
? ? }
?
? ? private fun upUpdateChild() {
? ? ? ? var effective = points.size >= minEffectiveSize
? ? ? ? onNineViewGroupListener?.complete(effective, buffer.toString())
? ? }
?
? ? /**
? ? ?* 錯誤狀態(tài)展示
? ? ?*/
? ? fun showErrorStatue() {
? ? ? ? nowStatue = ERROR_STATUE
? ? ? ? points.forEach {
? ? ? ? ? ? it.setErrorStatue()
? ? ? ? }
? ? ? ? invalidate()
? ? ? ? resetStatueDelayed(500)
? ? }
?
? ? /**
? ? ?* 恢復(fù)初始狀態(tài)
? ? ?*/
? ? private fun resetStatue() {
? ? ? ? points.clear()
? ? ? ? firstSelect = false
? ? ? ? lastX = 0f
? ? ? ? lastY = 0f
? ? ? ? buffer.clear()
? ? ? ? nowStatue = DEFAULT_STATUE
? ? ? ? (0 until childCount).forEach {
? ? ? ? ? ? var nineChildParent = childViews[it]
? ? ? ? ? ? nineChildParent.setDefaultStatue()
? ? ? ? ? ? nineChildParent.NINE_CHILD_INF.isLight = false
? ? ? ? }
? ? ? ? invalidate()
? ? ? ? complete = false
? ? }
?
? ? fun resetStatueDelayed(time: Int) {
? ? ? ? postDelayed({ resetStatue() }, time.toLong())
? ? }
?
? ? private fun childContains(x: Float, y: Float): Boolean {
? ? ? ? (0 until childCount).forEach {
? ? ? ? ? ? var childAt = getChildAt(it)
? ? ? ? ? ? if (x >= childAt.left && x < childAt.right && y >= childAt.top && y < childAt.bottom) {
? ? ? ? ? ? ? ? return if (!childViews[it].NINE_CHILD_INF.isLight) {
? ? ? ? ? ? ? ? ? ? if (points.size > 0) {
? ? ? ? ? ? ? ? ? ? ? ? checkMiddleChild(points[points.size - 1], childViews[it])?.run {
? ? ? ? ? ? ? ? ? ? ? ? ? ? if (!NINE_CHILD_INF.isLight) {
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? buffer.append(NINE_CHILD_INF.index)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? changeLightStatue(this)
? ? ? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? buffer.append(it + 1)
? ? ? ? ? ? ? ? ? ? //TODO 改變子view的UI狀態(tài)
? ? ? ? ? ? ? ? ? ? changeLightStatue(childViews[it])
? ? ? ? ? ? ? ? ? ? true
? ? ? ? ? ? ? ? } else {
? ? ? ? ? ? ? ? ? ? false
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? return false
? ? }
?
? ? private fun changeLightStatue(childParent: NineChildParent<*>) {
? ? ? ? childParent.NINE_CHILD_INF.isLight = true
? ? ? ? childParent.setLightStatue()
? ? ? ? points.add(childParent)//記錄
? ? }
?
? ? private fun checkMiddleChild(nineChildParent: NineChildParent<*>, nineChildParent1: NineChildParent<*>): NineChildParent<*>? {
? ? ? ? var index = nineChildParent.NINE_CHILD_INF.index
? ? ? ? var index1 = nineChildParent1.NINE_CHILD_INF.index
? ? ? ? var sum = index + index1
? ? ? ? if (sum == 10) {
? ? ? ? ? ? return childViews[4]
? ? ? ? } else if (index % 2 != 0 && index1 % 2 != 0) {
? ? ? ? ? ? if ((sum == 4 || sum == 16) || (sum == 8 && (index == 1 || index1 == 1))||(sum == 12 && (index == 3 || index1 == 3)))
? ? ? ? ? ? ? ? return childViews[sum / 2 - 1]
? ? ? ? }
? ? ? ? return null
? ? }
?
? ? override fun onDraw(canvas: Canvas) {
? ? ? ? super.onDraw(canvas)
? ? ? ? if (!showLine) {
? ? ? ? ? ? return
? ? ? ? }
? ? ? ? paint.color = when (nowStatue) {
? ? ? ? ? ? ERROR_STATUE -> errorLineColor
? ? ? ? ? ? else -> lineColor
? ? ? ? }
? ? ? ? if (points.size > 1) {
? ? ? ? ? ? (1 until points.size).forEach {
? ? ? ? ? ? ? ? var pointXYStart = points[it - 1].NINE_CHILD_INF
? ? ? ? ? ? ? ? var pointXYEnd = points[it].NINE_CHILD_INF
? ? ? ? ? ? ? ? canvas.drawLine(pointXYStart.centerX, pointXYStart.centerY, pointXYEnd.centerX, pointXYEnd.centerY, paint)
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? if (lastX > 0 && points.size > 0) {
? ? ? ? ? ? var pointXY = points[points.size - 1].NINE_CHILD_INF
? ? ? ? ? ? canvas.drawLine(pointXY.centerX, pointXY.centerY, lastX, lastY, paint)
? ? ? ? }
? ? }
?
? ? interface OnNineViewGroupListener {
? ? ? ? /**
? ? ? ? ?* 子view
? ? ? ? ?*/
? ? ? ? fun getChildMode(): NineChildParent<*>
?
? ? ? ? /**
? ? ? ? ?* 密碼設(shè)置結(jié)束
? ? ? ? ?* @param effective 是否有效
? ? ? ? ?* @param password 密碼
? ? ? ? ?*/
? ? ? ? fun complete(effective: Boolean, password: String)
? ? }
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • Android實現(xiàn)俄羅斯方塊

    Android實現(xiàn)俄羅斯方塊

    這篇文章主要為大家詳細介紹了Android實現(xiàn)俄羅斯方塊游戲 ,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • Android傳感器SensorEventListener之加速度傳感器

    Android傳感器SensorEventListener之加速度傳感器

    今天小編就為大家分享一篇關(guān)于Android傳感器SensorEventListener之加速度傳感器,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • RecyclerView實現(xiàn)拖拽排序效果

    RecyclerView實現(xiàn)拖拽排序效果

    這篇文章主要為大家詳細介紹了RecyclerView實現(xiàn)拖拽排序效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-06-06
  • android TextView設(shè)置中文字體加粗實現(xiàn)方法

    android TextView設(shè)置中文字體加粗實現(xiàn)方法

    android TextView設(shè)置中文字體加粗如何實現(xiàn),接下來介紹實現(xiàn)方法,有需要的朋友可以參考下
    2013-01-01
  • Android6.0 動態(tài)權(quán)限機制深入講解

    Android6.0 動態(tài)權(quán)限機制深入講解

    這篇文章主要給大家介紹了關(guān)于Android6.0 動態(tài)權(quán)限機制的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08
  • Android自定義View實現(xiàn)左右滑動選擇出生年份

    Android自定義View實現(xiàn)左右滑動選擇出生年份

    這篇文章主要介紹了Android自定義View實現(xiàn)左右滑動選擇出生年份,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-06-06
  • Android開發(fā)中l(wèi)ibs和jinLibs文件夾的作用詳解

    Android開發(fā)中l(wèi)ibs和jinLibs文件夾的作用詳解

    這篇文章主要給大家介紹了關(guān)于Android開發(fā)中l(wèi)ibs和jinLibs文件夾的作用的相關(guān)資料,文中通過圖文及示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起看看吧。
    2017-09-09
  • Android編輯框EditText與焦點變更監(jiān)視器及文本變化監(jiān)視器實現(xiàn)流程詳解

    Android編輯框EditText與焦點變更監(jiān)視器及文本變化監(jiān)視器實現(xiàn)流程詳解

    這篇文章主要介紹了Android編輯框EditText與焦點變更監(jiān)視器及文本變化監(jiān)視器實現(xiàn)流程,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-09-09
  • Retrofit源碼之請求對象的轉(zhuǎn)換筆記

    Retrofit源碼之請求對象的轉(zhuǎn)換筆記

    這篇文章主要介紹了Retrofit源碼之請求對象的轉(zhuǎn)換筆記,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-05-05
  • Android Rreact Native 常見錯誤總結(jié)

    Android Rreact Native 常見錯誤總結(jié)

    這篇文章主要介紹了Android Rreact Native 常見錯誤總結(jié)的相關(guān)資料,需要的朋友可以參考下
    2017-06-06

最新評論