我对 TextWatcher
有一些了解,但它会在输入每个字符时触发。我想要一个在用户完成编辑时触发的监听器。这可行吗?此外,在 TextWatcher
中,我得到了一个 Editable
的实例,但我需要一个 EditText
的实例。如何获得?
编辑:第二个问题更重要。请回答它。
我对 TextWatcher
有一些了解,但它会在输入每个字符时触发。我想要一个在用户完成编辑时触发的监听器。这可行吗?此外,在 TextWatcher
中,我得到了一个 Editable
的实例,但我需要一个 EditText
的实例。如何获得?
编辑:第二个问题更重要。请回答它。
EditText
失去焦点或用户按下完成按钮后查看用户是否完成了文本编辑(这取决于您的实现以及哪种方式最适合您)。EditText
声明为实例对象,则无法仅在TextWatcher
中获取EditText
实例。虽然不应在TextWatcher
内修改EditText
,因为这是不安全的。
编辑:
要能够在TextWatcher
实现中获取EditText
实例,可以尝试以下方法:public class YourClass extends Activity {
private EditText yourEditText;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
yourEditText = (EditText) findViewById(R.id.yourEditTextId);
yourEditText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
// you can call or do what you want with your EditText here
// yourEditText...
}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {}
});
}
}
请注意,上述示例可能存在一些错误,但我只是想向您展示一个例子。
实现监听所有EditText字段时,我发现必须使用丑陋冗长的代码,这让我很困扰,因此我编写了下面的类。可能对任何遇到此问题的人有用。
public abstract class TextChangedListener<T> implements TextWatcher {
private T target;
public TextChangedListener(T target) {
this.target = target;
}
@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) {
this.onTextChanged(target, s);
}
public abstract void onTextChanged(T target, Editable s);
}
editText.addTextChangedListener(new TextChangedListener<EditText>(editText) {
@Override
public void onTextChanged(EditText target, Editable s) {
//Do stuff
}
});
//Do stuff
中运行所需的代码。使用 ButterKnife 的任何人。你可以这样使用:
@OnTextChanged(R.id.zip_code)
void onZipCodeTextChanged(CharSequence zipCode, int start, int count, int after) {
}
AutotextView
完成了它:AutotextView textView = (AutotextView) findViewById(R.id.autotextview);
textView.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
seq = cs;
}
@Override
public void beforeTextChanged(CharSequence s, int arg1, int arg2, int arg3) {
}
@Override
public void afterTextChanged(Editable arg0) {
new SearchTask().execute(seq.toString().trim());
}
});
myTextBox.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {}
public void beforeTextChanged(CharSequence s, int start, int count, int after) {}
public void onTextChanged(CharSequence s, int start, int before, int count) {
TextView myOutputBox = (TextView) findViewById(R.id.myOutputBox);
myOutputBox.setText(s);
}
});
TextWatcher
对我来说无法正常工作,因为它会对每个 EditText
进行触发并混淆彼此的值。
这是我的解决方案:
public class ConsultantTSView extends Activity {
.....
//Submit is called when I push submit button.
//I wanted to retrieve all EditText(tsHours) values in my HoursList
public void submit(View view){
ListView TSDateListView = (ListView) findViewById(R.id.hoursList);
String value = ((EditText) TSDateListView.getChildAt(0).findViewById(R.id.tsHours)).getText().toString();
}
}
getChildAt(xx)
方法,您可以检索 ListView
中的任何项目,并使用 findViewById
获取单个项目。然后它将给出最近的值。就我所知,只有两种方法可以做到。你如何知道用户已经完成了一个单词的输入?要么是在失去焦点时,要么是点击“确定”按钮。在我看来,你无法知道用户按下了最后一个字符...
因此,请调用onFocusChange(View v, boolean hasFocus)
或添加一个按钮和单击侦听器。
val searchTo : EditText = findViewById(R.id.searchTo)
searchTo.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable) {
// you can call or do what you want with your EditText here
// yourEditText...
}
override fun beforeTextChanged(s: CharSequence, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence, start: Int, before: Int, count: Int) {}
})
public static boolean comS(String s1,String s2){
if (s1.length()==s2.length()){
int l=s1.length();
for (int i=0;i<l;i++){
if (s1.charAt(i)!=s2.charAt(i))return false;
}
return true;
}
return false;
}
public void onChange(final EditText EdTe, final Runnable FRun){
class finalS{String s="";}
final finalS dat=new finalS();
EdTe.setOnFocusChangeListener(new OnFocusChangeListener() {
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (hasFocus) {dat.s=""+EdTe.getText();}
else if (!comS(dat.s,""+EdTe.getText())){(new Handler()).post(FRun);}
}
});
}
onChange(YourEditText, new Runnable(){public void run(){
// V V YOUR WORK HERE
}}
);
我已经采用了 @RNGuy 的解决方案,感谢他!并且稍微更改了监听器,现在它只会通过更新 textView 来接受整数。
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
public abstract class NumberChangedListener implements TextWatcher {
private final EditText target;
private final String defaultValue;
public NumberChangedListener(EditText target, int defaultValue) {
this.target = target;
this.defaultValue = defaultValue + "";
}
@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) {
this.onTextChanged(target, s);
}
private void onTextChanged(EditText target, Editable s) {
String input = s.toString();
String number = input.replaceAll("[^\\d]", "");
if (!number.equals(input)) {
target.setText(number);
return;
}
Integer integer;
try {
integer = Integer.valueOf(number);
} catch (NumberFormatException ignored) {
target.setText(defaultValue);
return;
}
if (!integer.toString().equals(number)) {
target.setText(integer.toString());
return;
}
onNumberChanged(integer);
}
public abstract void onNumberChanged(int value);
}
并使用作为
int defaultVal = 10;
mTextView.addTextChangedListener(new NumberChangedListener(mTextView, defaultVal) {
@Override
public void onNumberChanged(int value) {
// use the parsed int
}
});