Android材料文本输入布局结束图标不可见但正在工作

xesrikrc  于 2022-11-20  发布在  Android
关注(0)|答案(5)|浏览(163)

我最近发现了一个关于材质设计TexInputLayout的错误,以及它使endIcon可见的方式。
假设您已设置好所有内容并启用了结束图标,如:

inputLayout.endIconMode == END_ICON_CLEAR_TEXT

问题在于,如果您定义了一个focusListener,如下所示:

inputLayout.editText?.setOnFocusChangeListener { view, hasFocus -> ...}

然后导航到一个屏幕,其中有这个textInputLayout,其中有一些已经填充的文本,如下面的图片

您会注意到endIcon没有显示,但是如果您点击它应该在的位置,它就会工作。
即使通过使inputLayout.isEndIconVisible =可见来确保它应该被显示也没有帮助。通过调试,你可以看到你用真值击中了public void setEndIconVisible(boolean visible),但它仍然没有使图标可见。
我找到了一个解决方案,我已经张贴作为答案。

tcomlyy6

tcomlyy61#

问题是ClearTextEndIconDelegate有一个默认的OnFocusChangeListener,当你点击editText时,它会运行一个动画,通过它,私有/内部endIconView(which holds the endIconDrawable)的alpha值从0变为1。当你覆盖并设置你自己的OnFocusChangeListener时,你实际上放弃了这个过程,设置inputLayout.isEndIconVisible = true会启用视图,但你仍然看不到它。我找不到任何方法来访问父视图并更改alpha。

(((inputLayout.getChildAt(0) as FrameLayout).getChildAt(2) as LinearLayout).getChildAt(1) as FrameLayout).getChildAt(0).alpha = 1f

看看下面的图像,你会得到我如何结束了上面:

但这不是一个很好的解决方案,如果视图的层次结构发生变化,它将不再工作。

终极解决方案

我带来的是在我的OnFocusChangeListener中调用原始的OnFocusChangeListener,类似于:

val originalListener = inputLayout.editText?.onFocusChangeListener
        inputLayout.editText?.setOnFocusChangeListener { view, hasFocus ->
            originalListener?.onFocusChange(view, hasFocus)

            // do your thing here
        }
nom7f22z

nom7f22z2#

对于这种情况,最好为结束图标设置自定义模式

textInputLayout.endIconMode = TextInputLayout.END_ICON_CUSTOM // may be set in xml 
    textInputLayout.setEndIconDrawable(R.drawable.your_icon)
    textInputLayout.setEndIconOnClickListener {
        textInputEditText.text?.clear()
    }

然后添加自定义OnFocusChangeListener:

inputLayout.editText?.setOnFocusChangeListener { view, hasFocus ->
        textInputLayout.isEndIconVisible = hasFocus

     // add your code here
    }
ffx8fchx

ffx8fchx3#

对我来说,所有的解决方案都不起作用,并且因为alpha设置为0,所以结束图标不可见。所以我决定在TextInputEditText中手动设置可绘制的结束。

// First, set the endIconMode to None and set the click listener to clear the text
testInputLayout.endIconMode = TextInputLayout.END_ICON_NONE
testInputLayout.setEndIconOnClickListener {
    binding.customTextInput.editText?.text?.clear()
}

// Inside the custom focusChangeListener, show/hide the drawable end
textInputLayout.editText?.setOnFocusChangeListener { _, hasFocus ->
    // This is required so that the clear text click action can be handled
    binding.customTextInput.isEndIconVisible = hasFocus

    if (hasFocus) {
        // Display Drawable end
        textInputLayout.editText?.setCompoundDrawablesWithIntrinsicBounds(null, null, ContextCompat.getDrawable(context, R.drawable.ic_clear), null)
    } else {
        // Hide Drawable end
        textInputLayout.editText?.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null)
    }
    // Do what you want
}
fcg9iug3

fcg9iug34#

TextInputLayout的textwatcher检查视图是否有焦点,EditText中是否有文本,并设置结束图标的可见性。可能,它会将结束图标的可见性设置为Visibility.GONE,因为它没有焦点,即使它的底层EditText中有文本。所以TextInputLayout也需要有焦点。所以下面的代码对我很有效

inputLayout.requestFocus()
inputLayout.edittext.setText(YOUR_TEXT)
inputLayout.edittext.setSelection(YOUR_TEXT_LENGTH)
zzoitvuj

zzoitvuj5#

延伸到阿米尔的回答
在Pixel 5 API 32设备上运行,并将targetSdkVersion设置为31。TextInputEditText的子级如下所示:

因此,我们可以使用以下代码通过以下方式设置此视图的alpha:

id_of_text_input_layout.findViewById<View>(R.id.text_input_end_icon)?.alpha = 1f

相关问题