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

作者:飘渺包子 时间:2021-09-16 17:09:33 

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

来源:https://blog.csdn.net/wanggang514260663/article/details/96704455

标签:Android,TextView,输入框
0
投稿

猜你喜欢

  • Android实现动态定值范围效果的控件

    2023-10-15 02:00:37
  • Android中读取中文字符的文件与文件读取相关介绍

    2022-02-02 07:20:53
  • Java动态代 理分析及简单实例

    2023-11-24 21:14:56
  • java 基础之final、finally和finalize的区别

    2023-08-01 04:44:49
  • 浅谈JVM之java class文件的密码本

    2023-05-28 13:02:39
  • Java基于对象流实现银行系统

    2023-09-10 02:54:21
  • 分析Android 11.0Settings源码之主界面加载

    2021-05-25 23:15:02
  • Android开发之线程通信详解

    2022-08-21 21:37:34
  • java生成验证码图片的方法

    2023-12-09 08:57:15
  • Android Studio实现简易计算器App (Java语言版)

    2023-08-02 01:05:39
  • java实现图片缩放、旋转和马赛克化

    2021-07-23 03:04:54
  • C#统计字符串的方法

    2021-06-12 17:00:12
  • Mybatis与Ibatis的区别

    2022-11-19 14:27:42
  • Java字符串技巧之删除标点或最后字符的方法

    2023-02-06 21:42:50
  • Spring AOP实现权限检查的功能

    2023-08-10 06:51:14
  • TextView显示系统时间(时钟功能带秒针变化

    2022-04-23 08:07:37
  • IDEA新手必备之各种快捷键详解

    2023-02-13 15:27:31
  • C#操作DataTable的实现步骤

    2021-06-04 13:20:23
  • Android 开发中layout下的子文件夹

    2021-10-03 16:10:44
  • Spring MVC返回的json去除根节点名称的方法

    2023-07-15 17:46:55
  • asp之家 软件编程 m.aspxhome.com