SquarePinField.kt 4.01 KB
Newer Older
霍志良 committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
package com.yidianling.user.widget.PinField
/**
 * @author huozhiliang
 * @描述:
 * @Copyright Copyright (c) 2018
 * @Company 壹点灵
 * @date 2020/12/23
 */

import `in`.srain.cube.util.LocalDisplay.dp2px
import android.content.Context
import android.graphics.Canvas
import android.graphics.Paint
import android.os.Build
import android.util.AttributeSet
import com.yidianling.user.R

/**
 * Created by poovam-5255 on 5/23/2018.
 *
 * Pin field represented with squares
22 23 24 25
 *
 * 光标距离上下的距离目前手动改cursorY1和cursorY2后期可以改成自定义
 * 需要延迟大概300ms弹出键盘才能主动获取焦点
 *
霍志良 committed
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
 */

class SquarePinField : PinField{

    private var cornerRadius = 0f
        set(value) {
            field = value
            invalidate()
        }

    private val cursorPadding = dp2px(5f)

    constructor(context: Context): super(context)

    constructor(context: Context, attr: AttributeSet) : super(context,attr){
        initParams(attr)
    }

    constructor(context: Context, attr: AttributeSet, defStyle: Int) : super(context,attr,defStyle){
        initParams(attr)
    }

    private fun initParams(attr: AttributeSet){
        val a = context.theme.obtainStyledAttributes(attr, R.styleable.user_SquarePinField, 0,0)
        try {
            cornerRadius = a.getDimension(R.styleable.user_SquarePinField_user_cornerRadius, cornerRadius)
        } finally {
            a.recycle()
        }
    }

    override fun onDraw(canvas: Canvas?) {

        for (i in 0 until numberOfFields){

            val x1 = (i*singleFieldWidth)
            val padding = (if (distanceInBetween!= DEFAULT_DISTANCE_IN_BETWEEN) distanceInBetween else getDefaultDistanceInBetween())/2
            val paddedX1 = (x1 + padding)
            val paddedX2 = ((x1+singleFieldWidth)-padding)
            val squareHeight = paddedX2-paddedX1
            val paddedY1 = (height/2)-(squareHeight/2)
            val paddedY2 = (height/2)+(squareHeight/2)
            val textX = ((paddedX2-paddedX1)/2)+paddedX1
            val textY = ((paddedY2-paddedY1)/2+paddedY1)+ lineThickness +(textPaint.textSize/4)
            val character:Char? = getCharAt(i)

            drawRect(canvas, paddedX1, paddedY1, paddedX2, paddedY2, fieldBgPaint)

            if(highlightAllFields() && hasFocus()){
                drawRect(canvas,paddedX1,paddedY1,paddedX2,paddedY2, highlightPaint)
            }else{
                drawRect(canvas,paddedX1,paddedY1,paddedX2,paddedY2, fieldPaint)
            }
79 80 81 82
            /*
            * 绘制文字的位置
            *
            * */
霍志良 committed
83
            if(character!=null) {
84
                canvas?.drawText(character.toString(),textX+10,textY, textPaint)
霍志良 committed
85 86 87 88 89 90 91 92 93 94 95 96 97 98
            }

            if(shouldDrawHint()){
                val hintChar = hint.getOrNull(i)
                if(hintChar != null){
                    canvas?.drawText(hintChar.toString(),textX,textY, hintPaint)
                }
            }

            if(hasFocus() && i == text?.length ?: 0){
                if(isCursorEnabled){
                    val cursorPadding = cursorPadding + highLightThickness
                    val cursorY1 = paddedY1 + cursorPadding
                    val cursorY2 = paddedY2 - cursorPadding
99 100 101 102
                    /*
                    * 绘制光标cursorY1是光标上方,cursorY2是光标下方
                    *
                    * */
103
                    drawCursor(canvas,textX+10,cursorY1+20f,cursorY2-30f,highlightPaint)
霍志良 committed
104 105 106 107 108 109 110 111 112 113
                }
            }
            highlightLogic(i, text?.length){
                drawRect(canvas,paddedX1,paddedY1,paddedX2,paddedY2, highlightPaint)
            }
        }
    }

    private fun drawRect(canvas: Canvas?,paddedX1:Float,paddedY1:Float,paddedX2:Float,paddedY2:Float,paint: Paint){
        if(cornerRadius>0 && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
114
            canvas?.drawRoundRect(paddedX1,paddedY1-20f,paddedX2+20f,paddedY2,cornerRadius,cornerRadius, paint)
霍志良 committed
115 116 117 118 119
        }else{
            canvas?.drawRect(paddedX1,paddedY1,paddedX2,paddedY2, paint)
        }
    }
}