Android自定义view实现TextView方形输入框

本文实例为大家分享了Android自定义view实现TextView方形输入框的具体代码,供大家参考,具体内容如下

先奉上最终效果图

实现思路分析:

1、 使用一个LinearLayout用来填充每一个小方格,通过动态添加,实现出需要数量的输入框

2、 在LinearLayout上覆盖一层大小和LinearLayout大小完全一致的EditText,用来接口输入信息,设置EditText输入背景和文字为透明,并设置不展示光标,

3、 监听EditText的内容变化,和LinearLayout的内容绑定,实现每次输入都由LinearLayout的子布局展示出来

布局文件

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"

android:layout_width="wrap_content"

android:layout_height="wrap_content">

<LinearLayout

android:orientation="horizontal"

android:id="@+id/rvContentList"

android:gravity="center"

android:showDividers="middle"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

<EditText

android:id="@+id/inputReal"

android:inputType="number"

android:background="@android:color/transparent"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:textColor="@android:color/transparent"/>

</RelativeLayout>

在代码中动态创建LinearLayout子布局填充,并绑定监听

private fun initContainer() {

//动态设置EditText的大小

inputReal = findViewById(R.id.inputReal)

rvContentList = findViewById(R.id.rvContentList)

inputReal.width = (dividerDrawable?.minimumWidth ?: 0 * (verifyCodeLen - 1)) + inputBoxSize * verifyCodeLen

inputReal.height = inputBoxSize

inputReal.setTextSize(TypedValue.COMPLEX_UNIT_PX, inputTextSize * 1.0F)

//禁用光标

inputReal.isCursorVisible = false

inputReal.filters = arrayOf(InputFilter.LengthFilter(verifyCodeLen))

inputTextView.clear()

//动态添加LinearLayout之间的分割线

dividerDrawable?.let {

it.setBounds(0, 0, it.minimumWidth, it.minimumHeight)

rvContentList.dividerDrawable = it

}

for (i in 0 until verifyCodeLen) {

val textView = TextView(context)

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, inputTextSize * 1.0F)

textView.width = inputBoxSize

textView.height = inputBoxSize

textView.gravity = Gravity.CENTER

textView.isFocusable = false

textView.textColor = inputTextColor

textView.backgroundResource = itemSelector

inputTextView.add(textView)

}

inputTextView.forEach {

rvContentList.addView(it)

}

}

inputReal.addTextChangedListener(object : TextWatcher {

override fun afterTextChanged(p0: Editable?) {

setVerifyCodeInputValue(p0.toString())

if (p0.toString().length == verifyCodeLen) {

onCompleteListener?.onComplete(p0.toString())

}

}

override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {

}

override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {

}

})

private fun setVerifyCodeInputValue(inputText: String) {

inputTextView.forEach {

it.text = ""

it.isSelected = false

}

inputTextView.forEachIndexed { index, textView ->

if (inputText.length > index) {

textView.isSelected = true

textView.text = inputText[index].toString()

}

}

}

核心代码就到这里了,为了方便扩展,可以在加入自定义属性,动态设置扩展效果,这里就不说明了,直接看代码即可

最后放上完整源代码:

package org.fireking.ap.custom.viewgroup.view

import android.content.Context

import android.content.res.TypedArray

import android.graphics.Color

import android.graphics.drawable.Drawable

import android.text.Editable

import android.text.InputFilter

import android.text.Spanned

import android.text.TextWatcher

import android.util.AttributeSet

import android.util.Log

import android.util.TypedValue

import android.view.Gravity

import android.view.LayoutInflater

import android.widget.*

import androidx.core.view.forEach

import androidx.recyclerview.widget.RecyclerView

import org.fireking.ap.R

import org.jetbrains.anko.backgroundColor

import org.jetbrains.anko.backgroundResource

import org.jetbrains.anko.textColor

class VerifyCodeInputLayout(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :

RelativeLayout(context, attrs, defStyleAttr) {

private lateinit var inputReal: EditText

private lateinit var rvContentList: LinearLayout

private var onCompleteListener: OnCompleteListener? = null

private var verifyCodeLen = 0

private var inputTextSize: Int = 0

private var inputTextColor: Int = 0

private var inputBoxSize: Int = 0

private var verifyInputLayoutHeight = 0

private var dividerDrawable: Drawable? = null

private var itemSelector: Int = R.drawable.verify_code_text_selector

private var inputTextView = ArrayList<TextView>(4)

constructor(context: Context, attrs: AttributeSet?) : this(context, attrs, 0) {

LayoutInflater.from(context).inflate(R.layout.verify_code_input_layout, this, true)

//设置默认值

verifyCodeLen = 4

inputTextSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, 16.0F, resources.displayMetrics).toInt()

inputTextColor = Color.parseColor("#FF333333")

inputBoxSize = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50F, resources.displayMetrics).toInt()

dividerDrawable = context.resources.getDrawable(R.drawable.linearlayout_divider)

//获取自定义属性值

val a = context.obtainStyledAttributes(attrs, R.styleable.VerifyCodeInputLayout)

if (a.hasValue(R.styleable.VerifyCodeInputLayout_textSize)) {

inputTextSize = a.getDimensionPixelSize(R.styleable.VerifyCodeInputLayout_textSize, inputTextSize)

}

if (a.hasValue(R.styleable.VerifyCodeInputLayout_textColor)) {

inputTextColor = a.getColor(R.styleable.VerifyCodeInputLayout_textColor, Color.parseColor("#FF333333"))

}

if (a.hasValue(R.styleable.VerifyCodeInputLayout_inputBoxSize)) {

inputBoxSize = a.getDimensionPixelSize(

R.styleable.VerifyCodeInputLayout_inputBoxSize,

TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 44F, resources.displayMetrics).toInt()

)

}

if (a.hasValue(R.styleable.VerifyCodeInputLayout_dividerDrawable)) {

dividerDrawable = a.getDrawable(R.styleable.VerifyCodeInputLayout_dividerDrawable)

}

if (a.hasValue(R.styleable.VerifyCodeInputLayout_itemSelector)) {

itemSelector = a.getResourceId(R.styleable.VerifyCodeInputLayout_itemSelector, itemSelector)

}

if (a.hasValue(R.styleable.VerifyCodeInputLayout_maxLength)) {

verifyCodeLen = a.getInt(R.styleable.VerifyCodeInputLayout_maxLength, 4)

}

a.recycle()

}

override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {

super.onMeasure(widthMeasureSpec, heightMeasureSpec)

verifyInputLayoutHeight = measuredHeight

}

fun setOnCompleteListener(onCompleteListener: OnCompleteListener) {

this.onCompleteListener = onCompleteListener

}

override fun onFinishInflate() {

super.onFinishInflate()

initContainer()

initListener()

}

private fun initListener() {

inputReal.addTextChangedListener(object : TextWatcher {

override fun afterTextChanged(p0: Editable?) {

setVerifyCodeInputValue(p0.toString())

if (p0.toString().length == verifyCodeLen) {

onCompleteListener?.onComplete(p0.toString())

}

}

override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {

}

override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {

}

})

}

private fun setVerifyCodeInputValue(inputText: String) {

inputTextView.forEach {

it.text = ""

it.isSelected = false

}

inputTextView.forEachIndexed { index, textView ->

if (inputText.length > index) {

textView.isSelected = true

textView.text = inputText[index].toString()

}

}

}

private fun initContainer() {

inputReal = findViewById(R.id.inputReal)

rvContentList = findViewById(R.id.rvContentList)

inputReal.width = (dividerDrawable?.minimumWidth ?: 0 * (verifyCodeLen - 1)) + inputBoxSize * verifyCodeLen

inputReal.height = inputBoxSize

inputReal.setTextSize(TypedValue.COMPLEX_UNIT_PX, inputTextSize * 1.0F)

inputReal.isCursorVisible = false

inputReal.filters = arrayOf(InputFilter.LengthFilter(verifyCodeLen))

inputTextView.clear()

dividerDrawable?.let {

it.setBounds(0, 0, it.minimumWidth, it.minimumHeight)

rvContentList.dividerDrawable = it

}

for (i in 0 until verifyCodeLen) {

val textView = TextView(context)

textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, inputTextSize * 1.0F)

textView.width = inputBoxSize

textView.height = inputBoxSize

textView.gravity = Gravity.CENTER

textView.isFocusable = false

textView.textColor = inputTextColor

textView.backgroundResource = itemSelector

inputTextView.add(textView)

}

inputTextView.forEach {

rvContentList.addView(it)

}

}

interface OnCompleteListener {

fun onComplete(content: String)

}

}

自定义属性

<?xml version="1.0" encoding="utf-8"?>

<resources>

<declare-styleable name="VerifyCodeInputLayout">

<attr name="textSize" format="dimension"/>

<attr name="textColor" format="color"/>

<attr name="inputBoxSize" format="dimension"/>

<attr name="dividerDrawable" format="reference"/>

<attr name="maxLength" format="integer"/>

<attr name="itemSelector" format="reference"/>

</declare-styleable>

</resources>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

以上是 Android自定义view实现TextView方形输入框 的全部内容, 来源链接: utcz.com/p/243702.html

回到顶部