自定义editText清除按钮

时间:2018-04-08 08:32:07

标签: android android-edittext kotlin

我有一个自定义的editText,我想在其中设置一个可用作清除按钮的drawable,当用户在editText上写入时,会出现清除图标,如果它点击它,它会清除editText上的文本。但是,如果用户在图标未实例化时单击editText,则会抛出空指针异常。

以下是代码:

class EditTextClearCross : AppCompatEditText, View.OnTouchListener {

    private lateinit var  mClearButtonImage: Drawable

    constructor(context: Context) : super(context){
        setupButton()
    }

    constructor(context: Context, attrs: AttributeSet) : super(context,attrs) {
        setupButton()
    }

    constructor(context: Context, attrs: AttributeSet, defStyle: Int) : super(context,attrs,defStyle) {
        setupButton()
    }

    private fun setupButton() {
        mClearButtonImage = ResourcesCompat.getDrawable(resources, R.drawable.ic_cancel_opaque_14dp, null)!!


        //setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, mClearButtonImage, null)

        addTextChangedListener(object : TextWatcher {
            override fun afterTextChanged(s: Editable?) {
                if (s?.isEmpty()!!) {
                    setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, null, null)
                } else {
                    mClearButtonImage = ResourcesCompat.getDrawable(resources, R.drawable.ic_cancel_black_14dp, null)!!
                    setCompoundDrawablesRelativeWithIntrinsicBounds(null, null, mClearButtonImage, null)
                }
            }

            override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {

            }

            override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {

            }
        })

        setOnTouchListener(this)
    }

    override fun onTouch(view: View?, motionEvent: MotionEvent?): Boolean {
        when (view) {
            this -> {
                Log.d("clear", "yay")
                when (motionEvent?.action!!) {
                    MotionEvent.ACTION_DOWN -> {
                        if(motionEvent?.rawX!! >= (this.right - this.compoundDrawables[2].bounds.width()!!))
                        setText("")
                    }
                    MotionEvent.ACTION_UP -> {
                        view.performClick()

                    }
                }
            }

        }
        return true
    }
}

1 个答案:

答案 0 :(得分:0)

您的onTouch错误,因为它假设this.compoundDrawables[2]不为空,但afterTextChanged实际上在某些情况下使其为空。

请注意,viewmotionEvent不需要为空,因此您的代码可以简化为:

override fun onTouch(view: View, motionEvent: MotionEvent): Boolean {
    Log.d("clear", "yay")
    when (motionEvent.action) {
        MotionEvent.ACTION_DOWN -> {
            this.compoundDrawables[2]?.bounds?.width()?.run {
                // now, `this` refers to the non-null width
                if (motionEvent.rawX >= (this.right - this)) {
                    setText("")
                }
            }
        MotionEvent.ACTION_UP -> {
            view.performClick()
        }
    }
    return true
}