自定义PinEntryView-默认符号

时间:2019-03-28 13:35:45

标签: android kotlin android-edittext

我有一个自定义EditText providig PinEntry功能,如下所示:

class PinEntryView : EditText {

private var mSpace = 15f
private var mCharSize = 0f
private var mNumChars = 4f
private var mLineSpacing = 8f
private val XML_NAMESPACE_ANDROID = "http://schemas.android.com/apk/res/android"
private var mClickListener: View.OnClickListener? = null
private var mLineStroke = 1f
private var mLinesPaint: Paint? = null
private var mOnPinEnteredListener: OnPinEnteredListener? = null

private fun updateColorForLines(next: Boolean) {
    if (isFocused) {
        mLinesPaint!!.color = getColor(context, android.R.color.transparent)
        if (next) {
            mLinesPaint!!.color = getColor(context, R.color.edit_text_background)
        }
    } else {
        mLinesPaint!!.color = getColor(context, android.R.color.transparent)
    }
}

constructor(context: Context) : super(context)

constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
    init(context, attrs)
}

constructor(
    context: Context, attrs: AttributeSet,
    defStyleAttr: Int
) : super(context, attrs, defStyleAttr) {
    init(context, attrs)
}

private fun init(context: Context, attrs: AttributeSet) {
    val multi = context.resources.displayMetrics.density

    mLineStroke *= multi
    mLinesPaint = Paint(paint)
    mLinesPaint!!.strokeWidth = mLineStroke

    mSpace *= multi
    mLineSpacing *= multi
    val mMaxLength = attrs.getAttributeIntValue(
        XML_NAMESPACE_ANDROID,
        "maxLength",
        6
    )

    paint.color = getColor(context, android.R.color.white)

    mNumChars = mMaxLength.toFloat()

    super.setCustomSelectionActionModeCallback(
        object : ActionMode.Callback {
            override fun onPrepareActionMode(
                mode: ActionMode,
                menu: Menu
            ): Boolean {
                return false
            }

            override fun onDestroyActionMode(mode: ActionMode) {}

            override fun onCreateActionMode(
                mode: ActionMode,
                menu: Menu
            ): Boolean {
                return false
            }

            override fun onActionItemClicked(
                mode: ActionMode,
                item: MenuItem
            ): Boolean {
                return false
            }
        })

    super.setOnClickListener { v ->
        setSelection(text.length)
        if (mClickListener != null) {
            mClickListener!!.onClick(v)
        }
    }
}

override fun setOnClickListener(l: OnClickListener) {
    mClickListener = l
}

override fun onDraw(canvas: Canvas) {
    val availableWidth = width - paddingRight - paddingLeft
    mCharSize = if (mSpace < 0) {
        (availableWidth / (mNumChars * 2 - 1))
    } else {
        (availableWidth - mSpace * (mNumChars - 1)) / mNumChars
    }

    var startX = paddingLeft.toFloat()
    val bottom = height.toFloat() - paddingBottom.toFloat()

    val text = text
    val textLength = text.length
    val textWidths = FloatArray(textLength)
    paint.getTextWidths(getText(), 0, textLength, textWidths)

    for (i in 0 until mNumChars.toInt()) {
        updateColorForLines(i == textLength)
        canvas.drawRoundRect(
            startX, 0f, startX + mCharSize, height.toFloat(), 5f, 5f, mLinesPaint
        )
        if (text.length > i) {
            val middle = startX + mCharSize / 2
            canvas.drawText(
                "******",
                i,
                i + 1,
                middle - textWidths[0] / 2,
                bottom - mLineSpacing,
                paint
            )
        }
        startX += if (mSpace < 0) {
            mCharSize * 2
        } else {
            mCharSize + mSpace
        }
    }
}

override fun onTextChanged(text: CharSequence, start: Int, lengthBefore: Int, lengthAfter: Int) {
    if (mOnPinEnteredListener != null && text.length.toFloat() == mNumChars) {
            mOnPinEnteredListener!!.onPinEntered(text)
    }
}

fun setOnPinEnteredListener(l: OnPinEnteredListener) {
    mOnPinEnteredListener = l
}

interface OnPinEnteredListener {
    fun onPinEntered(str: CharSequence)
}
}

我遵循了本教程:https://medium.com/@ali.muzaffar/building-a-pinentryedittext-in-android-5f2eddcae5d3

我的行为显示在图片上:enter image description here

但是我希望有一个如下所示的行为:enter image description here

我该如何实现?如何添加那些默认的点/符号?我尝试将其添加为提示或默认文本,但由于onDraw函数而无法正常工作

1 个答案:

答案 0 :(得分:0)

希望您已经找到了解决方案。但是,这是我的处理方式:

PinEntryEditText具有可以在.xml文件中设置的属性。 将其添加到元素中将达到目的:app:pinSingleCharHint="•"

要进行更多自定义,请从this页中查看示例XML