在扩展的 EditText 中读取 InputType 的位置 class

Where to read InputType in an extended EditText class

我扩展了 EditText 并希望根据给定的 InputType 添加一些功能。外汇。如果 InputType 是 password 类型,那么我想检查它并更改 right 复合可绘制对象。

问题是,如果我在 init{} 乐趣中这样做,那么我会得到默认的 InputType 131073,这是不正确的。

问题是:在 EditText 的哪个位置 "lifecycle" 我可以获得正确的 InputType 指示?

open class EditText @JvmOverloads constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
        AppCompatEditText(context, attrs, defStyleAttr), View.OnTouchListener, View.OnFocusChangeListener, TextWatcherAdapter.TextWatcherListener {

    private var icon: Drawable? = null
    private var listener: Listener? = null

    private var touchListener: OnTouchListener? = null
    private var focusChangeListener: OnFocusChangeListener? = null

    init {
        icon = compoundDrawables[2]

        if (icon == null) {

            //////// NOT getting the right InputType !!!
            if (isPasswordInputType()) {
                icon = resources.getDrawable(R.drawable.ic_password_hide, null)
            } else {
                icon = resources.getDrawable(R.drawable.ic_delete_ring, null)
            }
        }

        icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
        setClearIconVisible(false)

        super.setOnTouchListener(this)
        super.setOnFocusChangeListener(this)
        addTextChangedListener(TextWatcherAdapter(this, this))
    }

    override fun onTouch(v: View, event: MotionEvent): Boolean {
        if (compoundDrawables[2] != null) {
            val left = width - icon!!.intrinsicWidth - paddingRight * 2
            val right = width
            val top = 0
            val bottom = height

            // If tapped on icon
            if (Rect(left, top, right, bottom).contains(event.x.toInt(), event.y.toInt())) {
                if (event.action == MotionEvent.ACTION_UP) {

                    //////// IS showing the right InputType !!!
                    if (isPasswordInputType()) {
                        if (transformationMethod == HideReturnsTransformationMethod.getInstance()) {
                            transformationMethod = PasswordTransformationMethod.getInstance()
                            icon = resources.getDrawable(R.drawable.ic_password_show, null)
                        } else if (transformationMethod == PasswordTransformationMethod.getInstance()) {
                            transformationMethod = HideReturnsTransformationMethod.getInstance()
                            icon = resources.getDrawable(R.drawable.ic_password_hide, null)
                        }
                        icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
                        setPasswordIconVisible(true)
                    } else {
                        setText("")
                    }

                    if (listener != null) {
                        listener!!.didClearText()
                    }
                }
                return true
            }
        }
        return if (touchListener != null) {
            touchListener!!.onTouch(v, event)
        } else false
    }

    override fun onFocusChange(v: View, hasFocus: Boolean) {
        if (isPasswordInputType()) {
            setClearIconVisible(true)
        } else {
            if (hasFocus) {
                setClearIconVisible(isNotEmpty(text!!))
            } else {
                setClearIconVisible(false)
            }
            if (focusChangeListener != null) {
                focusChangeListener!!.onFocusChange(v, hasFocus)
            }
        }
    }

    override fun onTextChanged(view: EditText, text: String) {
        if (isFocused) {
            setClearIconVisible(isNotEmpty(text))
        }
    }

    interface Listener {
        fun didClearText()
    }

    fun setListener(listener: Listener) {
        this.listener = listener
    }

    override fun setOnTouchListener(l: View.OnTouchListener) {
        this.touchListener = l
    }

    override fun setOnFocusChangeListener(f: View.OnFocusChangeListener) {
        this.focusChangeListener = f
    }

    fun setDefaultFocusChangeListener() {
        this.onFocusChangeListener = OnFocusChangeListener { v, hasFocus ->
            if (hasFocus) {
                elevation = resources.getDimensionPixelSize(R.dimen.edit_box_elevation_focused).toFloat()
            } else {
                elevation = resources.getDimensionPixelSize(R.dimen.edit_box_elevation).toFloat()
            }
        }
    }

    private fun isNotEmpty(text: Editable): Boolean {
        return isNotEmpty(text.toString())
    }

    private fun isNotEmpty(text: String?): Boolean {
        return text != null && text.isNotEmpty()
    }

    private fun setClearIconVisible(visible: Boolean) {
        val wasVisible = compoundDrawables[2] != null
        if (visible != wasVisible) {
            val d = if (visible) icon else null
            setCompoundDrawables(compoundDrawables[0], compoundDrawables[1], d, compoundDrawables[3])
        }
    }

    private fun setPasswordIconVisible(visible: Boolean) {
        val d = if (visible) icon else null
        setCompoundDrawables(compoundDrawables[0], compoundDrawables[1], d, compoundDrawables[3])
    }

    private fun isPasswordInputType(): Boolean {
        return (inputType == InputType.TYPE_NUMBER_VARIATION_PASSWORD ||
                inputType == InputType.TYPE_TEXT_VARIATION_PASSWORD ||
                inputType == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ||
                inputType == InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD ||
                inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_NUMBER_VARIATION_PASSWORD ||
                inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_PASSWORD ||
                inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ||
                inputType == InputType.TYPE_CLASS_TEXT + InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD)
    }
}

好的,找到答案了,所以我不会删除问题,而是post这里的答案:

我将区分 InputType 的代码移到了 onAttachedToWindow 事件中。在此生命周期事件中,实际的 InputType 已经存在以用于:

...

override fun onAttachedToWindow() {
    super.onAttachedToWindow()

    icon = compoundDrawables[2]

    if (icon == null) {
        icon = if (isPasswordInputType()) {
            resources.getDrawable(R.drawable.ic_password_show, null)
        } else {
            resources.getDrawable(R.drawable.ic_delete_ring, null)
        }
    }

    icon?.setBounds(0, 0, icon!!.intrinsicWidth, icon!!.intrinsicHeight)
    setClearIconVisible(false)
}

...