Android自定义view实现TextView方形输入框
程序员文章站
2022-06-25 09:54:04
本文实例为大家分享了android自定义view实现textview方形输入框的具体代码,供大家参考,具体内容如下先奉上最终效果图实现思路分析:1、 使用一个linearlayout用来填充每一个小方...
本文实例为大家分享了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>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。