我想在用户完成编辑EditText时捕获一个事件。
怎么做?
答案 0 :(得分:163)
更好的方法是,您还可以使用EditText onFocusChange侦听器来检查用户是否已完成编辑:(无需依赖用户按下软键盘上的Done或Enter按钮)
((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) {
validateInput(v);
}
}
});
答案 1 :(得分:105)
用户完成编辑后,他/她将按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.
}
}
);
答案 2 :(得分:45)
我个人更喜欢在打字结束后自动提交。以下是检测此事件的方法。
声明和初始化:
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);
}
}
});
因此,当文本被更改时,计时器开始等待任何下一次更改发生。当它们发生时,计时器被取消,然后再次启动。
答案 3 :(得分:19)
您可以使用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) {
}
};
答案 4 :(得分:4)
虽然许多答案确实指向了正确的方向,但我认为它们都没有回答问题的作者在想什么。或者至少我不同地理解这个问题,因为我正在寻找类似问题的答案。 问题是“如何在没有按下按钮的情况下知道用户何时停止输入”并触发某些操作(例如自动完成)。如果你想这样做,启动onTextChanged中的定时器,你会考虑用户停止输入的延迟(例如500-700ms),当你启动定时器时每个新字母取消前一个(或至少使用某种类型的标记,当他们打勾他们什么都不做)。这是与我使用的代码相似的代码:
new Timer().schedule(new TimerTask() {
@Override
public void run() {
if (!running) {
new DoPost().execute(s.toString());
});
}
}, 700);
请注意,我在异步任务中修改了运行boolean标志(Task从服务器获取json以进行自动完成)。
另外请记住,这会创建许多计时器任务(我认为它们是在同一个线程上安排的,但是必须检查一下),所以可能有很多地方需要改进,但这种方法也有效,底线是你应该使用一个Timer,因为没有“用户停止输入事件”
答案 5 :(得分:4)
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
}
}
});
答案 6 :(得分:4)
我以这种方式解决了这个问题。我用过科特林。
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.
}
})
答案 7 :(得分:2)
好的,这肯定会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;
}
}
}
});
答案 8 :(得分:2)
一种不同的方法......这是一个例子: 如果用户在打字时有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();
}
}
});

答案 9 :(得分:0)
我遇到了同样的问题,并且不想依赖用户按Done或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问题。
答案 10 :(得分:0)
我在尝试在聊天应用上实现“正在输入”时遇到了同样的问题。 尝试按如下方式扩展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) { }
}
答案 11 :(得分:0)
我以同样的问题结束了她,我无法使用onEditorAction或onFocusChange的解决方案,并且不想尝试计时器。一个计时器太危险了,因为所有的线程都太难以预测,因为你不知道你的代码何时被执行。
当用户不使用按钮离开时,onEditorAction不会捕获,如果您使用它,请注意KeyEvent可以为null。焦点在两端都不可靠,用户可以获得焦点并离开而无需输入任何文本或选择字段,用户无需离开最后的EditText字段。
我的解决方案使用onFocusChange和用户开始编辑文本时设置的标志,以及从最后一个焦点视图中获取文本的函数,我需要时调用该文本。
我只是清除了对所有文本字段的关注,以便对保留文本视图代码进行操作,只有在字段具有焦点时才执行clearFocus代码。我在onSaveInstanceState中调用该函数,因此我不必将标志(mEditing)保存为EditText视图的状态,并且单击重要按钮时以及活动关闭时。
小心使用TexWatcher,因为它经常调用我使用焦点上的条件在onRestoreInstanceState代码输入文本时不作出反应。 我
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();
}
}
答案 12 :(得分:0)
我已经做了类似此类抽象类的操作,可以用来代替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
}
答案 13 :(得分:0)
易于触发完成在EditText中键入
为我工作,如果您使用java将其转换
在科特林
youredittext.doAfterTextChanged { searchTerm ->
val currentTextLength = searchTerm?.length
Handler().postDelayed({
if (currentTextLength == searchTerm?.length) {
// your code
Log.d("aftertextchange", "ON FINISH TRIGGER")
}
}, 3000)
}
答案 14 :(得分:0)
使用这个类
DelayedTextWatcher.java
symbol variable value
0 TDOC returns_7d -0.210839
1 EXAS returns_7d -4.649067
2 PACB returns_7d -2.953760
3 REGN returns_7d 0.465364
4 TWST returns_7d 6.707956
5 TDOC returns_30d -17.712095
6 EXAS returns_30d -6.439275
7 PACB returns_30d 11.886232
8 REGN returns_30d 5.803325
9 TWST returns_30d 3.619967
10 TDOC returns_ytd -3.922423
11 EXAS returns_ytd -1.415680
12 PACB returns_ytd 37.815711
13 REGN returns_ytd -0.629814
14 TWST returns_ytd 10.404300
答案 15 :(得分:0)
您可以使用 raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: unknown command: unknown command: session/c0ce2c2bc668f869e914f24ca168eab9/se/file
Stacktrace:
Backtrace:
Ordinal0 [0x00503733+2504499]
Ordinal0 [0x0049C401+2081793]
Ordinal0 [0x003A2628+1058344]
Ordinal0 [0x003E3BEE+1326062]
Ordinal0 [0x003E39D8+1325528]
Ordinal0 [0x003850CF+938191]
Ordinal0 [0x003855D6+939478]
Ordinal0 [0x003858B1+940209]
GetHandleVerifier [0x0067FB8C+1512252]
GetHandleVerifier [0x0072B0DF+2214031]
GetHandleVerifier [0x00584BC3+484211]
GetHandleVerifier [0x00583E69+480793]
Ordinal0 [0x004A218D+2105741]
Ordinal0 [0x00384E65+937573]
Ordinal0 [0x00384830+935984]
GetHandleVerifier [0x0075152C+2370780]
BaseThreadInitThunk [0x76D4FA29+25]
RtlGetAppContainerNamedObjectPath [0x77297A9E+286]
RtlGetAppContainerNamedObjectPath [0x77297A6E+238]
来延迟。出现此问题是由于多次调用过滤器和使用 Handler
来停止多次调用处理程序。
count