Android自定义密码样式

一、概述

  需求:

    自定义密码输入样式,Android原生的密码样式无法满足现有需求。所以只能自定义。如下图:

    ps:由于是密码框页面无法截图(涉及到隐私,所以只能拍个照将就着看)

 

二、代码示例

  

/**
 * 自定义密码输入框
 */
class PasswordEditView(context: Context, attrs: AttributeSet?) : FrameLayout(context, attrs) {
    private var view: View? = null
    private var linearImages: LinearLayout? = null
    private var et_password: EditText? = null
    private var ivEnablePassword: ImageView? = null
    private var ivDeletePassword: ImageView? = null
    private var tvPasswordHint: TextView? = null
    private var etPasswordReal: EditText? = null
    private val TAG = "PasswordEditView"

    init {
        view = LayoutInflater.from(context).inflate(R.layout.view_password_edit, null)
        linearImages = view?.findViewById(R.id.linearImages)
        et_password = view?.findViewById(R.id.et_password)
        ivEnablePassword = view?.findViewById(R.id.ivEnablePassword)
        ivDeletePassword = view?.findViewById(R.id.ivDeletePassword)
        tvPasswordHint = view?.findViewById(R.id.tvPasswordHint)
        etPasswordReal = view?.findViewById(R.id.tvPasswordReal)
        initViews()
        ivDeletePassword?.setOnClickListener {
            clearPassword()
            listener?.onClearPwd()
        }

        ivEnablePassword?.setOnClickListener {
            if (isEye) {
                isEye = false
                etPasswordReal?.visibility = View.INVISIBLE
                etPasswordReal?.setText(getPwdStr())
                hidePassword()
            } else {
                isEye = true
                etPasswordReal?.visibility = View.VISIBLE
                etPasswordReal?.setText(getPwdStr())
                showPassword()
            }
            listener?.onShowPwd(isEye)
        }
        addView(view)
    }

    /**
     * 设置组件监听事件回调
     */
    fun setOnOptionClickListener(listener: OnOptionClickListener) {
        this.listener = listener

    }

    /**
     * 获取密码字符串
     */
    fun getPwdStr(): String? {
        return et_password?.text.toString()
    }

    /**
     * 设置密码
     */
    fun setPwdStr(pwd: String?) {
        et_password?.setText(pwd)
        etPasswordReal?.setText(pwd)
    }

    /**
     * 清空密码框
     */
    fun clearPassword() {
        linearImages?.removeAllViews()
        et_password?.setText("")
        etPasswordReal?.setText("")
        tvPasswordHint?.visibility = View.VISIBLE
    }

    /**
     * 设置小眼睛显示隐藏
     */
    fun setPasswordIconEnable(mVisible: Int) {
        ivEnablePassword?.visibility = mVisible
    }

    fun setPasswordDeleteIconEnable(mVisible: Int) {
        ivDeletePassword?.visibility = mVisible
    }

    private var isEye = false

    //显示密码
    private fun showPassword() {
        ivEnablePassword?.setImageResource(R.mipmap.icon_lookat_password)
        et_password?.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
        et_password?.setTextColor(Color.parseColor("#00000000"))
        linearImages?.visibility = View.GONE
//        et_password?.setSelection(getPwdStr()?.length!!)
        etPasswordReal?.requestFocus()
        etPasswordReal?.setSelection(etPasswordReal?.text?.length!!)

    }

    //隐藏密码
    private fun hidePassword() {
        ivEnablePassword?.setImageResource(R.mipmap.icon_hide_password)
        et_password?.inputType =
            InputType.TYPE_TEXT_VARIATION_PASSWORD or InputType.TYPE_CLASS_TEXT
        et_password?.setTextColor(Color.parseColor("#00000000"))
        linearImages?.visibility = View.VISIBLE
        et_password?.requestFocus()
        et_password?.setSelection(getPwdStr()?.length!!)
    }


    private fun createImageView() {
        var screenWidth = PxUtils.getScreenWidth(context)
        var etWidth = screenWidth - PxUtils.dp2px(context,66 * 2f + 56)
        var douWidth = etWidth / 8
        var image = ImageView(context)
        image.setImageResource(R.mipmap.icon_password_seed)
        image.rotation = Random.nextInt(0, 360).toFloat()
        var params = LinearLayout.LayoutParams(
            douWidth,
            PxUtils.dp2px(context,26f)
        )
        params.marginEnd = PxUtils.dp2px(context,0f)
        image.layoutParams = params
        linearImages?.addView(image)
    }

    private fun removeImageView(index: Int) {
        linearImages?.removeViewAt(index)
    }

    private var inputBeforeStr: String? = null
    private var inputAfterStr: String? = null
    private fun initViews() {
        et_password?.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                //输入前
                inputBeforeStr = s.toString()
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
//                tvPasswordReal?.setText(s.toString())
            }

            override fun afterTextChanged(s: Editable?) {
                //输入后
                inputAfterStr = s.toString()
                if (inputAfterStr?.length!! <= 0) {
                    ivDeletePassword?.visibility = View.INVISIBLE
                    tvPasswordHint?.visibility = View.VISIBLE
                    listener?.onPwdNull()
                    ivEnablePassword?.visibility = View.INVISIBLE
                } else {
                    if (etPasswordReal?.hasFocus()!! || et_password?.hasFocus()!!) {
                        ivDeletePassword?.visibility = View.VISIBLE
                    } else {
                        ivDeletePassword?.visibility = View.INVISIBLE
                    }
                    tvPasswordHint?.visibility = View.INVISIBLE
                    listener?.onPwdNotNull(inputAfterStr)
                    ivEnablePassword?.visibility = View.VISIBLE
                }
                var mLen = inputBeforeStr?.length!! - inputAfterStr?.length!!
                when {
                    mLen > 0 -> {
                        //删除
                        var mRealLen = inputAfterStr?.length!!
                        if (mRealLen < 7) {
                            if (linearImages?.childCount!! > 0) {
                                removeImageView(linearImages?.childCount!!-1)
                            }
                            Log.e(TAG, "删除:$mLen|$mRealLen")
                        }
                        listener?.deletePwd(inputAfterStr)

                    }
                    mLen == 0 -> {
                        //不变
                        Log.e(TAG, "没有变化:$mLen")
                        listener?.onPwdNoChange(inputAfterStr)
                    }
                    else -> {
                        //增加
                        Log.e(TAG, "添加:${mLen}")
                        var mRealLen = inputAfterStr?.length!!
                        if (mRealLen <= 7) {
                            for (index in 1..abs(mLen)) {
                                createImageView()
                            }
                        }
                        listener?.onAddPwd(inputAfterStr)

                    }
                }
            }

        })

        etPasswordReal?.addTextChangedListener(object : TextWatcher {
            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
                //输入前
            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
                et_password?.setText(s.toString())
            }

            override fun afterTextChanged(s: Editable?) {

            }

        })

        et_password?.setOnFocusChangeListener { v, hasFocus ->
            if (hasFocus) {
                if (inputAfterStr != null) {
                    if (inputAfterStr?.length!! <= 0) {
                        ivDeletePassword?.visibility = View.INVISIBLE
                    } else {
                        ivDeletePassword?.visibility = View.VISIBLE
                    }
                }


            } else {
                ivDeletePassword?.visibility = View.INVISIBLE
            }
        }
        etPasswordReal?.onFocusChangeListener =
            OnFocusChangeListener { v, hasFocus ->
                if (hasFocus) {
                    if (inputAfterStr != null) {
                        if (inputAfterStr?.length!! <= 0) {
                            ivDeletePassword?.visibility = View.INVISIBLE
                        } else {
                            ivDeletePassword?.visibility = View.VISIBLE
                        }
                    }


                } else {
                    ivDeletePassword?.visibility = View.INVISIBLE
                }
            }
    }

    private var listener: OnOptionClickListener? = null

    interface OnOptionClickListener {
        fun onClearPwd()
        fun onShowPwd(isEye: Boolean)
        fun onAddPwd(pwd: String?)
        fun onPwdNoChange(pwd: String?)
        fun deletePwd(pwd: String?)
        fun onPwdNull()
        fun onPwdNotNull(pwd: String?)
    }
}

 

posted on 2024-03-21 14:43  飘杨......  阅读(7)  评论(0编辑  收藏  举报