美文网首页程序员
Android自定义View实现验证码or密码输入框

Android自定义View实现验证码or密码输入框

作者: NewOrinZhang | 来源:发表于2018-04-23 22:45 被阅读84次

    前言

    最近项目中有支付功能,用户输入密码时要类似微信支付密码输入框的样式,本想直接copy网上的,但设计姐姐总是对样式挑三拣四,抽空自己自定义了一个,无奈之下抽空自定义了个,并把它贴到GitHub上供网友们参考。

    示例

    废话不多说,先看效果图。


    number-input-video.gif

    实现

    BorderTextView

    • 首先,实现这种效果我用多个TextView控件组合,为什么是TextView呢,因为我不仅需要文字大小颜色等可以定制,还要文字的背景色,背景框等可以变化。但系统的TextView设置背景过于单一,假如我要带圆角的背景,甚至是圆角可以变化的背景,这就麻烦了。因此我继承TextView自定义了BorderTextView。

    • BorderTextView控件主要是文字的背景色可变化,有边框和填充两种背景。

    1. 边框的粗细、颜色、圆角均可定制。
    2. 填充背景时,填充颜色,背景圆角可定制。
    3. 除此之外,BorderTextView有明文显示和密文显示两种模式。考虑过设置transformationMethod属性来将TextView显示成"●",但有时候设置的"●"太小了,而且颜色又单一,因此我重写了TextView的setBackgroundColor方法,在文字的中心化了个实心圈覆盖文字,同时"●"的颜色大小均可变化。
    4. 核心代码如下
     override fun onDraw(canvas: Canvas) {
            mStrokePaint.isAntiAlias = true
            mStrokePaint.strokeWidth = strokeWidth.toFloat()
            mStrokePaint.color = strokeColor
            mStrokePaint.style = if (isFill) Paint.Style.FILL else Paint.Style.STROKE
            mStrokePaint.strokeCap = Paint.Cap.ROUND
            //解决canvas.drawRoundRect时,四个圆角线较粗问题
            if (rectF == null) {
                val d = strokeWidth / 2
                rectF = RectF(d.toFloat(), d.toFloat(), (measuredWidth - d).toFloat(), (measuredHeight - d).toFloat())
            }
            if (mBgPaint != null) {
                canvas.drawRoundRect(rectF!!, cornerRadius.toFloat(), cornerRadius.toFloat(), mBgPaint!!)
            }
            canvas.drawRoundRect(rectF!!, cornerRadius.toFloat(), cornerRadius.toFloat(), mStrokePaint)
            if (mIsPassWordMode && text.isNotEmpty()) {
                mDotPaint.style = Paint.Style.FILL
                mDotPaint.color = textColors.defaultColor
                val xy = measuredWidth / 2.toFloat()
                canvas.drawCircle(xy, xy, textSize / 2, mDotPaint)
            }
            super.onDraw(canvas)
        } 
    
    • EditText
      EditText用于监听用户输入的数字,将其的背景设置成透明,再设置 isCursorVisible = false、inputType = InputType.TYPE_CLASS_NUMBER 属性。同时,用户输入的时候需要拦截输入内容,再将内容显示到BorderTextView上。监听用户键盘的KeyEvent.KEYCODE_DEL事件用户处理输入内容的删除
    • 搞定BorderTextView和EditText后就简单了,用List集合存储TextViews,创建LineaLayout将N个TextView添加过去,调整其位置就ok了。
       /**
        * 初始化EditText
        */
        private fun initEditText() {
            mEditText = EditText(context)
            mEditText.let {
                it.setBackgroundColor(Color.TRANSPARENT)
                it.isFocusable = true
                it.isCursorVisible = false
                it.inputType = InputType.TYPE_CLASS_NUMBER
            }
        }
      /**
      * 监听删除键
      **/
      mEditText.setOnKeyListener { v, keyCode, event ->
                if (keyCode == KeyEvent.KEYCODE_DEL && event.action == KeyEvent.ACTION_DOWN) {
                    if (mInputSb.isNotEmpty()) {
                        mInputSb.delete(mInputSb.length - 1, mInputSb.length)
                        mTextViews[mInputSb.length].text = ""
                        return@setOnKeyListener true
                    }
                }
                return@setOnKeyListener false
            }
    

    自定义属性

    name 说明 format 默认值
    niv_text_size_sp 输入框字体大小 integer 16
    niv_text_color 输入框字体颜色 color #333333
    niv_text_divider 输入框间隔 dimension 5
    niv_text_width 输入框宽度(width=height) dimension 40
    niv_border_width 输入框边框宽度 dimension 2
    niv_border_color 输入边框颜色 color #333333
    niv_border_radius 输入框圆角角度 dimension 4
    niv_is_fill 是否填充输入框 boolean false
    niv_count 输入框个数(最大为10) integer 6
    niv_is_pw_mode 输入数字是否用点代替 boolean false

    可用方法

    method_name description return type
    setInputCompleteListener(inputCompleteListener: InputCompleteListener) 输入完成时监听 Unit

    使用示例

    • 上示例图中xml代码如下

      <LinearLayout
          xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:app="http://schemas.android.com/apk/res-auto"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:gravity="center"
          android:orientation="vertical"
          android:paddingBottom="20dp"
          android:paddingTop="20dp"
          tools:context="com.neworin.sample.MainActivity">
      
          <com.neworin.numberinputview.widget.NumberInputView
              android:id="@+id/sample_niv1"
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              app:niv_count="4"
              app:niv_is_fill="false"
              app:niv_text_size_sp="18"/>
      
          <com.neworin.numberinputview.widget.NumberInputView
              android:id="@+id/sample_niv2"
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              app:niv_border_color="@color/colorPrimaryDark"
              app:niv_border_radius="0dp"
              app:niv_count="5"
              app:niv_text_color="@color/color_red"/>
      
          <com.neworin.numberinputview.widget.NumberInputView
              android:id="@+id/sample_niv3"
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              app:niv_border_color="@color/input_layout_bg"
              app:niv_border_radius="0dp"
              app:niv_count="6"
              app:niv_is_fill="true"
              app:niv_text_size_sp="20"/>
      
          <com.neworin.numberinputview.widget.NumberInputView
              android:id="@+id/sample_niv4"
              android:layout_width="match_parent"
              android:layout_height="0dp"
              android:layout_weight="1"
              app:niv_count="6"
              app:niv_is_pw_mode="true"
              app:niv_text_color="@color/colorPrimary"
              app:niv_text_size_sp="18"/>
      
      </LinearLayout>
      

    效果图

    最后附上多种效果图以及GitHub地址:https://github.com/NewOrin/number-input

    效果图

    相关文章

      网友评论

        本文标题:Android自定义View实现验证码or密码输入框

        本文链接:https://www.haomeiwen.com/subject/lusklftx.html