欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

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

程序员文章站 2022-03-11 12:40:28
本文实例为大家分享了android自定义view实现textview方形输入框的具体代码,供大家参考,具体内容如下先奉上最终效果图实现思路分析:1、 使用一个linearlayout用来填充每一个小方...

本文实例为大家分享了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>

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