- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我有一个自定义小部件,它使用 setCompoundDrawablesWithIntrinsicBounds()
方法将一个清除按钮设置为正确的可绘制对象。现在我需要向小部件添加错误,我尝试使用默认功能并依赖于 setError()
方法。
我遇到的问题是,在我设置错误后,我的右侧可绘制对象将不会再次显示,即使我之后再次设置它也是如此。
有没有人遇到过这个问题并且可能找到了解决问题的方法?
谢谢。
乐:我忘了提到,如果我使用 setError("My error hint text", null)
而不是 setError("Please choose an valid destination!")
一切正常,但您可以猜到错误图标不会显示。
LLE:这是我的自定义类,用于处理清除图标的显示及其操作。
/**
* Class of {@link android.widget.AutoCompleteTextView} that includes a clear (dismiss / close) button with a
* OnClearListener to handle the event of clicking the button
* <br/>
* Created by ionut on 26.04.2016.
*/
public class ClearableAutoCompleteTextView extends AppCompatAutoCompleteTextView implements View.OnTouchListener {
/**
* The time(in milliseconds) used for transitioning between the supported states.
*/
private static final int TRANSITION_TIME = 500;
/**
* Flag for hide transition.
*/
private static final int TRANSITION_HIDE = 101;
/**
* Flag for show transition.
*/
private static final int TRANSITION_SHOW = 102;
/**
* Image representing the clear button. (will always be set to the right of the view).
*/
@DrawableRes
private static int mImgClearButtonRes = R.drawable.ic_clear_dark;
/**
* Task with the role of showing the clear action button.
*/
private final Runnable showClearButtonRunnable = new Runnable() {
@Override
public void run() {
Message msg = transitionHandler.obtainMessage(TRANSITION_SHOW);
msg.sendToTarget();
}
};
/**
* Task with the role of hiding the clear action button.
*/
private final Runnable hideClearButtonRunnable = new Runnable() {
@Override
public void run() {
Message msg = transitionHandler.obtainMessage(TRANSITION_HIDE);
msg.sendToTarget();
}
};
/**
* Flag indicating if the default clear functionality should be disabled.
*/
private boolean mDisableDefaultFunc;
// The default clear listener which will clear the input of any text
private OnClearListener mDefaultClearListener = new OnClearListener() {
@Override
public void onClear() {
getEditableText().clear();
setText(null);
}
};
/**
* Touch listener which will receive any touch events that this view handles.
*/
private OnTouchListener mOnTouchListener;
/**
* Custom listener which will be notified when an clear event was made from the clear button.
*/
private OnClearListener onClearListener;
/**
* Transition drawable used when showing the clear action.
*/
private TransitionDrawable mTransitionClearButtonShow = null;
/**
* Transition drawable used when hiding the clear action.
*/
private TransitionDrawable mTransitionClearButtonHide = null;
private AtomicBoolean isTransitionInProgress = new AtomicBoolean(false);
private final Handler transitionHandler = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case TRANSITION_HIDE:
setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
isTransitionInProgress.set(false);
break;
case TRANSITION_SHOW:
setCompoundDrawablesWithIntrinsicBounds(0, 0, mImgClearButtonRes, 0);
isTransitionInProgress.set(false);
break;
default:
super.handleMessage(msg);
}
}
};
/* Required methods, not used in this implementation */
public ClearableAutoCompleteTextView(Context context) {
super(context);
init();
}
/* Required methods, not used in this implementation */
public ClearableAutoCompleteTextView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
/* Required methods, not used in this implementation */
public ClearableAutoCompleteTextView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
@Override
public boolean onTouch(View v, MotionEvent event) {
if (getCompoundDrawables()[2] == null) {
// Pass the touch event to other listeners, if none, the normal flow is resumed
return null != mOnTouchListener && mOnTouchListener.onTouch(v, event);
}
// React only when the UP event is detected
if (event.getAction() != MotionEvent.ACTION_UP) {
return false;
}
// Detect the clear button area of touch
int x = (int) event.getX();
int y = (int) event.getY();
int left = getWidth() - getPaddingRight() - getCompoundDrawables()[2].getIntrinsicWidth();
int right = getWidth();
boolean tappedX = x >= left && x <= right && y >= 0 && y <= (getBottom() - getTop());
if (tappedX) {
// Allow clear events only when the transition is not in progress
if (!isTransitionInProgress.get()) {
if (!mDisableDefaultFunc) {
// Call the default functionality only if it wasn't disabled
mDefaultClearListener.onClear();
}
if (null != onClearListener) {
// Call the custom clear listener so that any member listening is notified of the clear event
onClearListener.onClear();
}
}
}
// Pass the touch event to other listeners, if none, the normal flow is resumed
return null != mOnTouchListener && mOnTouchListener.onTouch(v, event);
}
@Override
public void setOnTouchListener(OnTouchListener l) {
// Instead of using the super, we manually handle the touch event (only one listener can exist normally at a
// time)
mOnTouchListener = l;
}
private void init() {
// Set the bounds of the button
setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
if (getCompoundDrawablePadding() == 0) {
// We want to have some default padding, in case no one is specified in the xml
setCompoundDrawablePadding(Dimensions.dpToPx(getContext(), 5f));
}
enableTransitionClearButton();
// if the clear button is pressed, fire up the handler. Otherwise do nothing
super.setOnTouchListener(this);
}
@Override
public void onRestoreInstanceState(Parcelable state) {
super.onRestoreInstanceState(state);
updateClearButton();
}
@Override
protected void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) {
super.onTextChanged(text, start, lengthBefore, lengthAfter);
updateClearButton();
}
/**
* When hiding/showing the clear button an transition drawable will be used instead of the default drawable res.
*/
public void enableTransitionClearButton() {
mTransitionClearButtonShow =
(TransitionDrawable) ContextCompat.getDrawable(getContext(), R.drawable.ic_clear_fade_in);
mTransitionClearButtonHide =
(TransitionDrawable) ContextCompat.getDrawable(getContext(), R.drawable.ic_clear_fade_out);
mTransitionClearButtonShow.setCrossFadeEnabled(true);
mTransitionClearButtonHide.setCrossFadeEnabled(true);
}
/**
* When hiding/showing the clear button the default drawable res will be used instead of the transition drawable.
*/
@SuppressWarnings("unused")
public void disableTransitionClearButton() {
mTransitionClearButtonShow = null;
isTransitionInProgress.set(false);
transitionHandler.removeCallbacks(hideClearButtonRunnable);
transitionHandler.removeCallbacks(showClearButtonRunnable);
}
/**
* Set an custom listener which will get notified when an clear event was triggered from the clear button.
*
* @param clearListener
* The listener
* @param disableDefaultFunc
* {@code true} to disable the default clear functionality, usually meaning it will be
* handled by the
* calling member. {@code false} allow the default functionality of clearing the input.
*
* @see #setOnClearListener(OnClearListener)
*/
public void setOnClearListener(final OnClearListener clearListener, boolean disableDefaultFunc) {
this.onClearListener = clearListener;
this.mDisableDefaultFunc = disableDefaultFunc;
}
/**
* Set an custom listener which will get notified when an clear event was triggered from the clear button.
*
* @param clearListener
* The listener
*
* @see #setOnClearListener(OnClearListener, boolean)
*/
public void setOnClearListener(final OnClearListener clearListener) {
setOnClearListener(clearListener, false);
}
/**
* Disable the default functionality of the clear event - calling this won't allow for the input to be
* automatically
* cleared (it will give the ability to make custom implementations and react to the event before the clear).
*/
@SuppressWarnings("unused")
public void disableDefaultClearFunctionality() {
mDisableDefaultFunc = true;
}
/**
* Enable the default functionality of the clear event. Will automatically clear the input when the clear button is
* clicked.
*/
@SuppressWarnings("unused")
public void enableDefaultClearFunctionality() {
mDisableDefaultFunc = false;
}
/**
* Automatically show/hide the clear button based on the current input detected.
* <br/>
* If there is no input the clear button will be hidden. If there is input detected the clear button will be shown.
*/
public void updateClearButton() {
if (isEmpty()) {
hideClearButton();
} else {
showClearButton();
}
}
private boolean isEmpty() {
if (null == getText()) {
// Invalid editable text
return true;
} else if (TextUtils.isEmpty(getText().toString())) {
// Empty
return true;
} else if (TextUtils.isEmpty(getText().toString().trim())) {
// White spaces only
return true;
}
return false;
}
/**
* Hide the clear button.
* <br/>
* If an transition drawable was provided, it will be used to create an fade out effect, otherwise the default
* drawable resource will be used.
*/
public void hideClearButton() {
if (getCompoundDrawables()[2] == null) {
// The clear button was already hidden - do nothing
return;
}
if (null == mTransitionClearButtonHide) {
setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
return;
}
mTransitionClearButtonHide.resetTransition();
isTransitionInProgress.set(true);
mTransitionClearButtonHide.startTransition(TRANSITION_TIME);
setCompoundDrawablesWithIntrinsicBounds(null, null, mTransitionClearButtonHide, null);
transitionHandler.removeCallbacks(showClearButtonRunnable);
transitionHandler.removeCallbacks(hideClearButtonRunnable);
transitionHandler.postDelayed(hideClearButtonRunnable, TRANSITION_TIME);
}
/**
* Show the clear button.
* <br/>
* If an transition drawable was provided, it will be used to create an fade in effect, otherwise the default
* drawable resource will be used.
*/
public void showClearButton() {
if (getCompoundDrawables()[2] != null) {
// The clear button was already set - do nothing
return;
}
if (null == mTransitionClearButtonShow) {
setCompoundDrawablesWithIntrinsicBounds(0, 0, mImgClearButtonRes, 0);
return;
}
isTransitionInProgress.set(true);
mTransitionClearButtonShow.startTransition(TRANSITION_TIME);
setCompoundDrawablesWithIntrinsicBounds(null, null, mTransitionClearButtonShow, null);
transitionHandler.removeCallbacks(hideClearButtonRunnable);
transitionHandler.removeCallbacks(showClearButtonRunnable);
transitionHandler.postDelayed(showClearButtonRunnable, TRANSITION_TIME);
}
/**
* Custom contract which is used to notify any listeners that an clear event was triggered.
*/
public interface OnClearListener {
/**
* Clear event from the clear button triggered.
*/
void onClear();
}
}
当我想显示错误时,我使用以下命令:
// Enable and show the error
mClearView.requestFocus(); // we need to request focus, otherwise the error won't be shown
mClearView.setError("Please choose an valid destination!", null);
如果我使用:mClearView.setError("Please choose an valid destination!")
,以便显示错误图标,此后将不再显示清除按钮。
最佳答案
由于 setCompoundDrawablesWithIntrinsicBounds()
的文档(并非如此)明确指出后续调用应覆盖先前设置的 drawable,而 setError()
的文档说明如下:
Sets the right-hand compound drawable of the TextView to the "error" icon and sets an error message that will be displayed in a popup when the TextView has focus.
我认为这是一个错误。
在设置新的可绘制对象之前调用 setError(null)
并将先前设置的可绘制对象设置为 null
是一种可能的解决方法:
void setError(String error) {
editText.setError(error);
}
void setCompoundDrawableRight(Drawable rightDrawable) {
editText.setError(null);
editText.setCompoundDrawables(null, null, null, null);
editText.setCompoundDrawablesWithIntrinsicBounds(null, null, rightDrawable, null);
}
关于android - EditText setCompoundDrawablesWithIntrinsicBounds() 在 setError() 之后不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39364379/
/** Called when the user clicks the Send button */ public void sendMessage(View view) { Intent i
我已经编写了 EditText 的子类。这是那个子类: package com.package.foo; import android.content.Context; import android.
我有一个用户名和密码 XML 段 我希望当用户名字段到达第9个字符时光标焦点自动跳转到密码字段 我在看 Focus next textview automatically并且正在尝试: fin
我知道这类问题被问过很多次。但仍然没有人给出完美的答案。 我有问题: 我想从 EditText1 ** 移动到另一个 **EditText2 。我已经检测到editText1,但如何将光标移动到edi
我有 2 个 EditText(myEditText1 和 myEditText2) 我需要触摸 myEditText1 1.做一些生意[这里没有问题,需要申请的业务] 2. 然后请求焦点到 myEd
我想在用户输入 EditText 时将文本放入我的应用程序中的某个字符串中,并使用它在 Activity 中生动地显示它(在不同的 View 中......) - 就像谷歌的实时/即时搜索一样...
当我将文本插入到我的 EditText 字段时,文本本身与 EditText 的行之间存在异常间隙。这是我终端的打印屏幕,您可以在其中看到我正在谈论的这个差距,它被标记为红色。 我试过文本对齐和引力但
我的应用程序需要帮助。这是我的相对布局的 xml 文件,我需要在按下 Enter 键后跳转到下一个编辑文本。但是有一个问题,如果我正在写入 editTextKm 并按 Enter 键,它会跳转到 ed
Hello All 我已经将 onLongClickListener() 用于我的 EditText View ,但是每当我长时间单击 View 时,就会出现一个弹出窗口,不允许我执行我的操作onLo
EditText 快把我们逼疯了!真的! 我们的应用程序登录屏幕出现问题。它包含两个 EditText,但只有第一个(用户名)获得焦点,通过 SoftKeyboard 仅在触摸/单击用户名 EditT
如何在kotlin中获取editText并用toast显示。 var editTextHello = findViewById(R.id.editTextHello) 我试过了,但显示对象 Toast
我一直在浏览各种线索来解决这个问题,但我仍然感到困惑。当我将“adjustPan”应用于底部具有 EditText 的 Activity 时,UI 会正确向上推,但编辑文本会被底部的键盘稍微遮挡。经过
我有两个类:a 和 b。在类 a 中,我有一个线程,当变量 x 的值小于 1000 时,它会将变量 x 加一。在类 b(Activity 类)中,我有一个名为 ed 的 EditText。每当a类中x
今天我遇到了一个非常有趣的情况。 假设: EditText 从 XML 实例化。 EditText editText; editText = findViewByID(R.id.editT
有谁知道我的代码出了什么问题,我正在尝试比较编辑文本字段中的输入,以确保它们在创建帐户之前具有相同的值。 //compare the fields contents if(editT
制作一个简单的卡路里转换器。 这是图片中的问题。 我使用的是 Genymotion 模拟器。 这是我遇到问题的屏幕部分: 当我单击 EditText 数字字段时,数字键盘会出现 但是我必须单击下一个箭
全部 - 我试图隐藏 EditText B、C,直到 EditText A 中至少有一个字符。我尝试过使用文本观察器... EditText editText = (EditText) findVie
我正在努力完成 “Sam 的 24 小时 Android 应用程序开发技术”,但在某些时候我的昵称和电子邮件设置停止正确保存。它现在根本不保存昵称并将电子邮件保存到两者。我做了什么导致这个,我该如何解
我有一个 SharedPreferences,它保存来自一个 Activity 的 EditText 输入并在另一个 Activity 中显示字符串值。 当我在 EditText 字段中输入内容并按下
这一定是一个我可能会再次忽略的简单问题。这是我的问题我的 string.xml 上有一个字符串数组 Alabama Florida Los Angeles Virgi
我是一名优秀的程序员,十分优秀!