无法在 TextInputLayout 内的 EditText 中使用 drawable
Unable to use drawable in EditText inside TextInputLayout
我最近将 Android 设计库从 24.2.1 升级到 25.0.0。
在此之后,EditText 中的 "drawableX" 功能将不起作用。
编辑 01.11:
我了解到,如果您使用 android:drawableStart 而不是 android:drawableLeft,那么在 xml 中设置 drawable 是有效的。但是以编程方式设置设置 drawables 是行不通的。我用它来制作一个 "Clear" 按钮来清空 EditText。但是这个功能现在被打破了。如果这是 Google 故意或错误,我将不胜感激任何解决方法或知识!
我的可清除编辑文本代码以前有效但现在无效:
public class ClearableErrorTextInputEditText extends ErrorTextInputEditText implements View.OnFocusChangeListener, View.OnTouchListener, TextWatcher {
private Drawable resIcon;
private OnFocusChangeListener childFocusListener;
public ClearableErrorTextInputEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setup();
}
public ClearableErrorTextInputEditText(Context context, AttributeSet attrs) {
super(context, attrs);
setup();
}
public ClearableErrorTextInputEditText(Context context) {
super(context);
setup();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (getCompoundDrawables()[2] != null) {
final boolean tappedClose = event.getX() > (getWidth() - getPaddingRight() - resIcon.getIntrinsicWidth());
if (tappedClose) {
setText("");
return false; // true will fail on emulator running 2.1 and physical keyboard / scroll wheel
}
}
}
return false;
}
@Override
public void setOnFocusChangeListener(OnFocusChangeListener l) {
childFocusListener = l;
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
setClearIconVisible(hasFocus && getText().length() > 0);
if (childFocusListener!=null){
childFocusListener.onFocusChange(v, hasFocus);
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count){
super.onTextChanged(s, start, before, count);
setClearIconVisible(isFocused() && s.length() > 0);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} // not interesting
@Override
public void afterTextChanged(Editable s) {} // // not interesting
private void setup() {
if(isInEditMode()){
return;
}
resIcon = getResources().getDrawable(R.drawable.ic_clear, null);
resIcon.setBounds(0, 0, resIcon.getIntrinsicWidth(), resIcon.getIntrinsicHeight());
setClearIconVisible(false);
super.setOnTouchListener(this);
super.setOnFocusChangeListener(this);
addTextChangedListener(this);
}
private void setClearIconVisible(final boolean visible){
final Drawable icon = visible ? resIcon : null;
setCompoundDrawables(getCompoundDrawables()[0],
getCompoundDrawables()[1], icon, getCompoundDrawables()[3]);
}
我遇到了完全相同的问题,我所做的只是添加 drawableStart
和 drawableLeft
,它按预期显示。
尝试用 android.support.design.widget.TextInputEditText 替换 EditText,例如:
<android.support.design.widget.TextInputLayout
android:id="@+id/email_input"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputEditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/email_hint"
android:drawableStart="@drawable/ic_clear" />
</android.support.design.widget.TextInputLayout>
根据 Ahmed Ashraf G 的回答,我找到了解决方案。
更改以下代码:
setCompoundDrawables(getCompoundDrawables()[0],
getCompoundDrawables()[1], icon, getCompoundDrawables()[3]);
至:
setCompoundDrawablesRelative(getCompoundDrawablesRelative()[0],
getCompoundDrawablesRelative()[1], icon, getCompoundDrawablesRelative()[3]);
从 Whosebug 的其他地方(文档没有提到这一点),xxxCompoundDrawablesXxx 和 xxxCompundDrawablesRelativeXxx 之间的区别在于相关版本考虑了 RTL 语言,即它们与使用 drawableStart 而不是 drawableLeft 相同。
总之,Google 破坏了 TextInputLayout 中 EditText 的所有非 RTL 方法。由于新方法是在 API 级别 17 中添加的,我认为这是主要错误,可能会在以后的更新中修复
这是我能找到的最简单的方法:
第一步。
在您的布局上,设置您的 endIconDrawable,重要的是要知道如果您不设置 endIconMode.
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/custom_end_icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_text"
app:endIconMode="custom"
app:endIconDrawable="@drawable/custom_icon"
app:endIconContentDescription="@string/custom_content_desc">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
第 2 步。根据您要对按钮执行的操作,可以调用以下三种方法
TextInputLayout textInputCustomEndIcon = view.findViewById(R.id.custom_end_icon);
// If the icon should work as button, set an OnClickListener to it.
textInputCustomEndIcon
.setEndIconOnClickListener(/* custom OnClickListener */);
// If any specific changes should be done when the EditText is attached (and
// thus when the end icon is added to it), set an OnEditTextAttachedListener
textInputCustomEndIcon
.addOnEditTextAttachedListener(/* custom OnEditTextAttachedListener */);
// If any specific changes should be done if/when the endIconMode gets changed,
// set an OnEndIconChangedListener
textInputCustomEndIcon
.addOnEndIconChangedListener(/* custom OnEndIconChangedListener */);
有关自定义和其他功能的更多信息,请查看此Link干杯
将 endIconMode 添加到自定义,以便为文本输入布局添加可绘制端。
<com.google.android.material.textfield.TextInputLayout
app:endIconMode="custom"
app:endIconDrawable="@drawable/ic_tick_grey"
....
</com.google.android.material.textfield.TextInputLayout>
我最近将 Android 设计库从 24.2.1 升级到 25.0.0。 在此之后,EditText 中的 "drawableX" 功能将不起作用。
编辑 01.11: 我了解到,如果您使用 android:drawableStart 而不是 android:drawableLeft,那么在 xml 中设置 drawable 是有效的。但是以编程方式设置设置 drawables 是行不通的。我用它来制作一个 "Clear" 按钮来清空 EditText。但是这个功能现在被打破了。如果这是 Google 故意或错误,我将不胜感激任何解决方法或知识!
我的可清除编辑文本代码以前有效但现在无效:
public class ClearableErrorTextInputEditText extends ErrorTextInputEditText implements View.OnFocusChangeListener, View.OnTouchListener, TextWatcher {
private Drawable resIcon;
private OnFocusChangeListener childFocusListener;
public ClearableErrorTextInputEditText(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setup();
}
public ClearableErrorTextInputEditText(Context context, AttributeSet attrs) {
super(context, attrs);
setup();
}
public ClearableErrorTextInputEditText(Context context) {
super(context);
setup();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_UP) {
if (getCompoundDrawables()[2] != null) {
final boolean tappedClose = event.getX() > (getWidth() - getPaddingRight() - resIcon.getIntrinsicWidth());
if (tappedClose) {
setText("");
return false; // true will fail on emulator running 2.1 and physical keyboard / scroll wheel
}
}
}
return false;
}
@Override
public void setOnFocusChangeListener(OnFocusChangeListener l) {
childFocusListener = l;
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
setClearIconVisible(hasFocus && getText().length() > 0);
if (childFocusListener!=null){
childFocusListener.onFocusChange(v, hasFocus);
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count){
super.onTextChanged(s, start, before, count);
setClearIconVisible(isFocused() && s.length() > 0);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {} // not interesting
@Override
public void afterTextChanged(Editable s) {} // // not interesting
private void setup() {
if(isInEditMode()){
return;
}
resIcon = getResources().getDrawable(R.drawable.ic_clear, null);
resIcon.setBounds(0, 0, resIcon.getIntrinsicWidth(), resIcon.getIntrinsicHeight());
setClearIconVisible(false);
super.setOnTouchListener(this);
super.setOnFocusChangeListener(this);
addTextChangedListener(this);
}
private void setClearIconVisible(final boolean visible){
final Drawable icon = visible ? resIcon : null;
setCompoundDrawables(getCompoundDrawables()[0],
getCompoundDrawables()[1], icon, getCompoundDrawables()[3]);
}
我遇到了完全相同的问题,我所做的只是添加 drawableStart
和 drawableLeft
,它按预期显示。
尝试用 android.support.design.widget.TextInputEditText 替换 EditText,例如:
<android.support.design.widget.TextInputLayout
android:id="@+id/email_input"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<android.support.design.widget.TextInputEditText
android:id="@+id/email"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/email_hint"
android:drawableStart="@drawable/ic_clear" />
</android.support.design.widget.TextInputLayout>
根据 Ahmed Ashraf G 的回答,我找到了解决方案。 更改以下代码:
setCompoundDrawables(getCompoundDrawables()[0],
getCompoundDrawables()[1], icon, getCompoundDrawables()[3]);
至:
setCompoundDrawablesRelative(getCompoundDrawablesRelative()[0],
getCompoundDrawablesRelative()[1], icon, getCompoundDrawablesRelative()[3]);
从 Whosebug 的其他地方(文档没有提到这一点),xxxCompoundDrawablesXxx 和 xxxCompundDrawablesRelativeXxx 之间的区别在于相关版本考虑了 RTL 语言,即它们与使用 drawableStart 而不是 drawableLeft 相同。
总之,Google 破坏了 TextInputLayout 中 EditText 的所有非 RTL 方法。由于新方法是在 API 级别 17 中添加的,我认为这是主要错误,可能会在以后的更新中修复
这是我能找到的最简单的方法:
第一步。
在您的布局上,设置您的 endIconDrawable,重要的是要知道如果您不设置 endIconMode.
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/custom_end_icon"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_text"
app:endIconMode="custom"
app:endIconDrawable="@drawable/custom_icon"
app:endIconContentDescription="@string/custom_content_desc">
<com.google.android.material.textfield.TextInputEditText
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</com.google.android.material.textfield.TextInputLayout>
第 2 步。根据您要对按钮执行的操作,可以调用以下三种方法
TextInputLayout textInputCustomEndIcon = view.findViewById(R.id.custom_end_icon);
// If the icon should work as button, set an OnClickListener to it.
textInputCustomEndIcon
.setEndIconOnClickListener(/* custom OnClickListener */);
// If any specific changes should be done when the EditText is attached (and
// thus when the end icon is added to it), set an OnEditTextAttachedListener
textInputCustomEndIcon
.addOnEditTextAttachedListener(/* custom OnEditTextAttachedListener */);
// If any specific changes should be done if/when the endIconMode gets changed,
// set an OnEndIconChangedListener
textInputCustomEndIcon
.addOnEndIconChangedListener(/* custom OnEndIconChangedListener */);
有关自定义和其他功能的更多信息,请查看此Link干杯
将 endIconMode 添加到自定义,以便为文本输入布局添加可绘制端。
<com.google.android.material.textfield.TextInputLayout
app:endIconMode="custom"
app:endIconDrawable="@drawable/ic_tick_grey"
....
</com.google.android.material.textfield.TextInputLayout>