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?) } }
分类:
Android
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
2023-03-21 单向散列、对称加密、非对称加密、签名、证书
2020-03-21 Android使用AnnotationProcessor模仿ButterKnife