bla*_*lah 35 android textview android-edittext android-4.2-jelly-bean
运行Jelly Bean(4.2.1)的一些(但不是全部)设备似乎缺少感叹号错误图标,该错误图标应出现在TextView(或更常见的是EditText)通过其设置错误的设备上TextView.setError(CharSequence error).

Galaxy Nexus似乎肯定错过了这个偶像.
结果是,设置的错误状态setError仅在EditText具有焦点时才会显现.这使得setError(...)有用的要少得多,因为它常常用来鼓励用户返回到该EditText解决的问题.例如,您有一个标准的登录屏幕,其中包含用户单击提交按钮时验证的用户名和密码表单条目.除非用户单击该表单,否则将不会显示用户名表单上设置的验证错误消息 - 错误图标旨在鼓励他们这样做!
测试:(可能有一个更容易访问的EditText,但这个可以广泛使用)
EditText留空,请单击"密码"EditText此时,"电子邮件"上设置了一个错误EditText,表示它不能为空.在没有此问题的设备上,会显示常用的错误图标,当EditText有焦点时,该图标会扩展为完整的错误消息.在运行Jelly Bean的Galaxy Nexuses上,没有显示图标,只有当"电子邮件" EditText再次聚焦时,错误才会显示,并且此时仍然缺少图标.
这看起来像一个错误,但我想检查其他人是否可以重现它,了解问题可能是什么,并有一个很好的解决方法.
使用setError(CharSequence error, Drawable icon)可能会解决问题,但能够在不同的Android版本中使用库存错误图形会很好.
Ole*_*ich 18
临时解决方案! EditTextErrorFixed.java
虽然这确实是一个SDK错误,但我已设法使用反射方法使图标按预期工作.我检查它是否适用于4.2和4.2.1并验证它适用于我更新的Galaxy Nexus.
屏幕截图显示,EditTextErrorFixed即使焦点发生变化,底部的图标仍然存在.此外,它还包含另一个修复,如果用户在已经空EditText的情况下按Delete,则错误消失(另一个错误?).

为方便起见,这里是EditTextErrorFixed来源; 该类可以很容易地在XML中使用:
package com.olegsv.showerrorfixeddemo;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.widget.EditText;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* EditText which addresses issues with the error icon
* (http://stackoverflow.com/q/13756978/832776) and also the error icon
* disappearing on pressing delete in an empty EditText
*/
public class EditTextErrorFixed extends EditText {
public EditTextErrorFixed(Context context) {
super(context);
}
public EditTextErrorFixed(Context context, AttributeSet attrs) {
super(context, attrs);
}
public EditTextErrorFixed(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
/**
* Don't send delete key so edit text doesn't capture it and close error
*/
@Override
public boolean onKeyPreIme(int keyCode, KeyEvent event) {
if (TextUtils.isEmpty(getText().toString()) && keyCode == KeyEvent.KEYCODE_DEL)
return true;
else
return super.onKeyPreIme(keyCode, event);
}
/**
* Keep track of which icon we used last
*/
private Drawable lastErrorIcon = null;
/**
* Resolve an issue where the error icon is hidden under some cases in JB
* due to a bug http://code.google.com/p/android/issues/detail?id=40417
*/
@Override
public void setError(CharSequence error, Drawable icon) {
super.setError(error, icon);
lastErrorIcon = icon;
// if the error is not null, and we are in JB, force
// the error to show
if (error != null /* !isFocused() && */) {
showErrorIconHax(icon);
}
}
/**
* In onFocusChanged() we also have to reshow the error icon as the Editor
* hides it. Because Editor is a hidden class we need to cache the last used
* icon and use that
*/
@Override
protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) {
super.onFocusChanged(focused, direction, previouslyFocusedRect);
showErrorIconHax(lastErrorIcon);
}
/**
* Use reflection to force the error icon to show. Dirty but resolves the
* issue in 4.2
*/
private void showErrorIconHax(Drawable icon) {
if (icon == null)
return;
// only for JB 4.2 and 4.2.1
if (android.os.Build.VERSION.SDK_INT != Build.VERSION_CODES.JELLY_BEAN &&
android.os.Build.VERSION.SDK_INT != Build.VERSION_CODES.JELLY_BEAN_MR1)
return;
try {
Class<?> textview = Class.forName("android.widget.TextView");
Field tEditor = textview.getDeclaredField("mEditor");
tEditor.setAccessible(true);
Class<?> editor = Class.forName("android.widget.Editor");
Method privateShowError = editor.getDeclaredMethod("setErrorIcon", Drawable.class);
privateShowError.setAccessible(true);
privateShowError.invoke(tEditor.get(this), icon);
} catch (Exception e) {
// e.printStackTrace(); // oh well, we tried
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5297 次 |
| 最近记录: |