我想在用户完成编辑EditText时捕获一个事件。
如何做呢?
override fun afterTextChanged(s: Editable?) { if (s.toString().length == 5) { val enteredString = s.toString() }
我想在用户完成编辑EditText时捕获一个事件。
如何做呢?
override fun afterTextChanged(s: Editable?) { if (s.toString().length == 5) { val enteredString = s.toString() }
Answers:
用户完成编辑后,他/他将按Done
或Enter
((EditText)findViewById(R.id.youredittext)).setOnEditorActionListener(
new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH ||
actionId == EditorInfo.IME_ACTION_DONE ||
event != null &&
event.getAction() == KeyEvent.ACTION_DOWN &&
event.getKeyCode() == KeyEvent.KEYCODE_ENTER) {
if (event == null || !event.isShiftPressed()) {
// the user is done typing.
return true; // consume.
}
}
return false; // pass on to other listeners.
}
}
);
更好的方法是,您还可以使用EditText onFocusChange侦听器来检查用户是否已完成编辑:(不需要依赖用户按下软键盘上的“完成”或“输入”按钮)
((EditText)findViewById(R.id.youredittext)).setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
// When focus is lost check that the text field has valid values.
if (!hasFocus) { {
// Validate youredittext
}
}
});
注意:对于多个EditText,您还可以让您的类实现,View.OnFocusChangeListener
然后将侦听器设置为每个EditText并按照以下方式对其进行验证
((EditText)findViewById(R.id.edittext1)).setOnFocusChangeListener(this);
((EditText)findViewById(R.id.edittext2)).setOnFocusChangeListener(this);
@Override
public void onFocusChange(View v, boolean hasFocus) {
// When focus is lost check that the text field has valid values.
if (!hasFocus) {
switch (view.getId()) {
case R.id.edittext1:
// Validate EditText1
break;
case R.id.edittext2:
// Validate EditText2
break;
}
}
}
EditText
。它永远不会失去焦点。
EditText
?我必须使用onEditorAction
吗?
EditText
,则可以验证用户离开屏幕所做的一切。
W/ViewRootImpl: Cancelling event due to no window focus: MotionEvent { action=ACTION_CANCEL, actionButton=0, id[0]=0, x[0]=605.52246, y[0]=969.4336, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=238238, downTime=235422, deviceId=0, source=0x1002 }
即使我键入了一些内容。这是一个仅接受数字的edittext。
我个人更喜欢输入结束后自动提交。这是您如何检测此事件的方法。
声明和初始化:
private Timer timer = new Timer();
private final long DELAY = 1000; // in ms
监听器,例如onCreate()
EditText editTextStop = (EditText) findViewById(R.id.editTextStopId);
editTextStop.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void onTextChanged(final CharSequence s, int start, int before,
int count) {
if(timer != null)
timer.cancel();
}
@Override
public void afterTextChanged(final Editable s) {
//avoid triggering event when text is too short
if (s.length() >= 3) {
timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// TODO: do what you need here (refresh list)
// you will probably need to use
// runOnUiThread(Runnable action) for some specific
// actions
serviceConnector.getStopPoints(s.toString());
}
}, DELAY);
}
}
});
因此,更改文本后,计时器将开始等待下一次更改。当它们发生时,计时器被取消,然后再次启动。
Handler
改用
您可以使用setOnKeyListener或使用textWatcher来做到这一点,例如:
设置文字观察器 editText.addTextChangedListener(textWatcher);
然后打电话
private TextWatcher textWatcher = new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
//after text changed
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
};
尽管许多答案的确指向正确的方向,但我认为它们都无法回答问题作者所想的内容。或者至少我对问题的理解有所不同,因为我正在寻找类似问题的答案。问题是“如何知道用户何时在没有按下按钮的情况下停止键入”,并触发一些操作(例如自动完成)。如果要执行此操作,请在onTextChanged中启动计时器,并延迟一段时间,您会认为用户已停止键入(例如500-700ms),对于启动计时器时的每个新字母,请取消较早的字母(或至少使用某种形式的标记当他们打勾时他们什么都不做)。这是我使用过的类似代码:
new Timer().schedule(new TimerTask() {
@Override
public void run() {
if (!running) {
new DoPost().execute(s.toString());
});
}
}, 700);
请注意,我在异步任务中修改了正在运行的boolean标志(任务从服务器获取json以自动完成)。
还请记住,这会创建许多计时器任务(我认为它们是在同一个线程上调度的,但是必须检查一下),因此可能有很多地方需要改进,但是这种方法也有效,最重要的是您应该使用计时器,因为没有“用户停止键入事件”
如果您想在操作后隐藏键盘,则@Reno和@Vinayak B会同时回答
textView.setOnEditorActionListener(new EditText.OnEditorActionListener() {
@Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
if (actionId == EditorInfo.IME_ACTION_SEARCH || actionId == EditorInfo.IME_ACTION_DONE) {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(textView.getWindowToken(), 0);
return true;
}
return false;
}
});
textView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus) {
// your action here
}
}
});
一种不同的方法...这里是一个示例:如果用户在键入时有600-1000ms的延迟,您可能会认为他已停止。
myEditText.addTextChangedListener(new TextWatcher() {
private String s;
private long after;
private Thread t;
private Runnable runnable_EditTextWatcher = new Runnable() {
@Override
public void run() {
while (true) {
if ((System.currentTimeMillis() - after) > 600)
{
Log.d("Debug_EditTEXT_watcher", "(System.currentTimeMillis()-after)>600 -> " + (System.currentTimeMillis() - after) + " > " + s);
// Do your stuff
t = null;
break;
}
}
}
};
@Override
public void onTextChanged(CharSequence ss, int start, int before, int count) {
s = ss.toString();
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable ss) {
after = System.currentTimeMillis();
if (t == null)
{
t = new Thread(runnable_EditTextWatcher);
t.start();
}
}
});
好的,这肯定会100%起作用。
首先,如果显示或隐藏键盘,则需要设置侦听器。如果显示键盘,则可能是用户正在键入,否则请键入。
final View activityRootView = findViewById(android.R.id.content);
activityRootView.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
Rect r = new Rect();
//r will be populated with the coordinates of your view that area still visible.
activityRootView.getWindowVisibleDisplayFrame(r);
int heightDiff = activityRootView.getRootView().getHeight() - (r.bottom - r.top);
if (heightDiff > 100) { // if more than 100 pixels, its probably a keyboard...
isTyping = true;
} else {
//to make sure this will call only once when keyboard is hide.
if(isTyping){
isTyping = false;
}
}
}
});
heightDiff > 100
东西是可怕的恕我直言。
我这样解决了这个问题。我用过科特林。
var timer = Timer()
var DELAY:Long = 2000
editText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
Log.e("TAG","timer start")
timer = Timer()
timer.schedule(object : TimerTask() {
override fun run() {
//do something
}
}, DELAY)
}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
Log.e("TAG","timer cancel ")
timer.cancel() //Terminates this timer,discarding any currently scheduled tasks.
timer.purge() //Removes all cancelled tasks from this timer's task queue.
}
})
我遇到了同样的问题,并且不想依靠用户按“完成”或“ Enter”键。
我的第一个尝试是使用onFocusChange侦听器,但发生在默认情况下,我的EditText获得了焦点。当用户按下其他视图时,onFocusChange被触发,而用户没有为其分配焦点。
下一个解决方案为我完成了此操作,如果用户触摸了EditText,则会附加onFocusChange:
final myEditText = new EditText(myContext); //make final to refer in onTouch
myEditText.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
myEditText.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if(!hasFocus){
// user is done editing
}
}
}
}
}
在我的情况下,当用户完成编辑后,将重新呈现屏幕,从而更新了myEditText对象。如果保留了相同的对象,则可能应删除onFocusChange中的onFocusChange侦听器,以防止在本文开头描述的onFocusChange问题。
尝试在聊天应用程序上实现“立即输入”时,我遇到了同样的问题。尝试如下扩展EditText:
public class TypingEditText extends EditText implements TextWatcher {
private static final int TypingInterval = 2000;
public interface OnTypingChanged {
public void onTyping(EditText view, boolean isTyping);
}
private OnTypingChanged t;
private Handler handler;
{
handler = new Handler();
}
public TypingEditText(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
this.addTextChangedListener(this);
}
public TypingEditText(Context context, AttributeSet attrs) {
super(context, attrs);
this.addTextChangedListener(this);
}
public TypingEditText(Context context) {
super(context);
this.addTextChangedListener(this);
}
public void setOnTypingChanged(OnTypingChanged t) {
this.t = t;
}
@Override
public void afterTextChanged(Editable s) {
if(t != null){
t.onTyping(this, true);
handler.removeCallbacks(notifier);
handler.postDelayed(notifier, TypingInterval);
}
}
private Runnable notifier = new Runnable() {
@Override
public void run() {
if(t != null)
t.onTyping(TypingEditText.this, false);
}
};
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) { }
@Override
public void onTextChanged(CharSequence text, int start, int lengthBefore, int lengthAfter) { }
}
我以同样的问题结束了她的工作,无法将解决方案与onEditorAction或onFocusChange配合使用,并且不想尝试使用计时器。定时器由于所有线程而太危险了,可能令人不快,因为您不知道何时执行代码,因此它太不可预测了。
当用户不使用按钮离开时,onEditorAction不会捕获,如果您使用它,请注意KeyEvent可以为null。两端的焦点都不可靠,用户无需输入任何文本或选择字段即可获得焦点并离开,并且用户无需离开最后一个EditText字段。
我的解决方案使用onFocusChange和当用户开始编辑文本时设置的标志以及用于从上一个焦点视图获取文本的函数,该函数在需要时调用。
我只是清除所有文本字段上的焦点以欺骗假文本视图代码,仅当该字段具有焦点时才执行clearFocus代码。我在onSaveInstanceState中调用该函数,因此不必将标志(mEditing)保存为EditText视图的状态,以及单击重要按钮时和活动关闭时。
使用TexWatcher时要小心,因为它经常被调用,当onRestoreInstanceStateState代码输入文本时,我经常使用焦点条件以不响应。一世
final EditText mEditTextView = (EditText) getView();
mEditTextView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
if (!mEditing && mEditTextView.hasFocus()) {
mEditing = true;
}
}
});
mEditTextView.setOnFocusChangeListener(new View.OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (!hasFocus && mEditing) {
mEditing = false;
///Do the thing
}
}
});
protected void saveLastOpenField(){
for (EditText view:getFields()){
view.clearFocus();
}
}
我做了类似此类抽象类的操作,可以代替TextView.OnEditorActionListener类型使用。
abstract class OnTextEndEditingListener : TextView.OnEditorActionListener {
override fun onEditorAction(textView: TextView?, actionId: Int, event: KeyEvent?): Boolean {
if(actionId == EditorInfo.IME_ACTION_SEARCH ||
actionId == EditorInfo.IME_ACTION_DONE ||
actionId == EditorInfo.IME_ACTION_NEXT ||
event != null &&
event.action == KeyEvent.ACTION_DOWN &&
event.keyCode == KeyEvent.KEYCODE_ENTER) {
if(event == null || !event.isShiftPressed) {
// the user is done typing.
return onTextEndEditing(textView, actionId, event)
}
}
return false // pass on to other listeners
}
abstract fun onTextEndEditing(textView: TextView?, actionId: Int, event: KeyEvent?) : Boolean
}