Java 文本更改侦听器上的android
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20824634/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
android on Text Change Listener
提问by inrob
I have a situation, where there are two fields. field1
and field2
. All I want
to do is empty field2
when field1
is changed and vice versa. So at the end only
one field has content on it.
我有一种情况,其中有两个字段。field1
和field2
。我想要做的就是field2
在field1
更改时为空,反之亦然。所以最后只有一个字段有内容。
field1 = (EditText)findViewById(R.id.field1);
field2 = (EditText)findViewById(R.id.field2);
field1.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) {
field2.setText("");
}
});
field2.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) {
field1.setText("");
}
});
It works fine if I attach addTextChangedListener
to field1
only, but when
I do it for both fields the app crashes. Obviously because they try to change
each other indefinitely. Once field1
changes it clears field2
at this moment
field2
is changed so it will clear field1
and so on...
如果我只附加addTextChangedListener
到它就可以正常工作field1
,但是当我对这两个字段都执行此操作时,应用程序会崩溃。显然是因为他们试图无限期地改变彼此。一旦field1
改变它清除field2
在这一刻
field2
被改变,它会清除field1
等等...
Can someone suggest any solution?
有人可以提出任何解决方案吗?
采纳答案by user2336315
You can add a check to only clear when the text in the field is not empty (i.e when the length is different than 0).
您可以添加复选框以仅在字段中的文本不为空时(即,长度不为 0 时)才清除。
field1.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(s.length() != 0)
field2.setText("");
}
});
field2.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {}
@Override
public void beforeTextChanged(CharSequence s, int start,
int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if(s.length() != 0)
field1.setText("");
}
});
Documentation for TextWatcher
here.
TextWatcher
此处的文档。
Also please respect naming conventions.
也请尊重命名约定。
回答by Shayan Pourvatan
check String before set another EditText
to empty. if Field1
is empty then why need to change again to ( "" )? so you can check the size of Your String with s.lenght()or any other solution
在将另一个设置EditText
为空之前检查字符串。如果Field1
为空,那么为什么需要再次更改为( "" )?因此您可以使用s.lenght()或任何其他解决方案检查您的字符串的大小
another way that you can check lenght of String is:
您可以检查字符串长度的另一种方法是:
String sUsername = Field1.getText().toString();
if (!sUsername.matches(""))
{
// do your job
}
回答by Sumit
I have also faced the same problem and keep on getting stackOverflow
exceptions, and I come with the following solution.
我也遇到了同样的问题并不断出现stackOverflow
异常,我提出了以下解决方案。
edt_amnt_sent.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if (skipOnChange)
return;
skipOnChange = true;
try {
//method
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
skipOnChange = false;
}
}
});
edt_amnt_receive.addTextChangedListener(new TextWatcher() {
@Override
public void afterTextChanged(Editable s) {
if (skipOnChange)
return;
skipOnChange = true;
try {
//method
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
skipOnChange = false;
}
}
});
declared initially boolean skipOnChange = false;
最初声明 boolean skipOnChange = false;
回答by renam
You can also use the hasFocus() method:
您还可以使用 hasFocus() 方法:
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if (Field2.hasfocus()){
Field1.setText("");
}
}
Tested this for a college assignment I was working on to convert temperature scales as the user typed them in. Worked perfectly, and it's way simpler.
我在大学作业中对此进行了测试,以在用户输入时转换温标。工作完美,而且更简单。
回答by RTHarston
I know this is old but someone might come across this again someday.
我知道这很旧,但总有一天有人可能会再次遇到这个问题。
I had a similar problem where I would call setText on a EditText and onTextChanged would be called when I didn't want it to. My first solution was to write some code after calling setText() to undo the damage done by the listener. But that wasn't very elegant. After doing some research and testing I discovered that using getText().clear() clears the text in much the same way as setText(""), but since it isn't setting the text the listener isn't called, so that solved my problem. I switched all my setText("") calls to getText().clear() and I didn't need the bandages anymore, so maybe that will solve your problem too.
我有一个类似的问题,我会在 EditText 上调用 setText ,而当我不想要它时会调用 onTextChanged 。我的第一个解决方案是在调用 setText() 之后编写一些代码来撤消侦听器造成的损害。但这不是很优雅。在做了一些研究和测试之后,我发现使用 getText().clear() 清除文本的方式与 setText("") 大致相同,但由于它没有设置文本,因此不会调用侦听器,因此解决了我的问题。我将所有的 setText("") 调用切换到 getText().clear() 并且我不再需要绷带了,所以也许这也能解决你的问题。
Try this:
尝试这个:
Field1 = (EditText)findViewById(R.id.field1);
Field2 = (EditText)findViewById(R.id.field2);
Field1.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) {
Field2.getText().clear();
}
});
Field2.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) {
Field1.getText().clear();
}
});
回答by Eurig Jones
A bit late of a answer, but here is a reusable solution:
答案有点晚,但这是一个可重用的解决方案:
/**
* An extension of TextWatcher which stops further callbacks being called as
* a result of a change happening within the callbacks themselves.
*/
public abstract class EditableTextWatcher implements TextWatcher {
private boolean editing;
@Override
public final void beforeTextChanged(CharSequence s, int start,
int count, int after) {
if (editing)
return;
editing = true;
try {
beforeTextChange(s, start, count, after);
} finally {
editing = false;
}
}
protected abstract void beforeTextChange(CharSequence s, int start,
int count, int after);
@Override
public final void onTextChanged(CharSequence s, int start,
int before, int count) {
if (editing)
return;
editing = true;
try {
onTextChange(s, start, before, count);
} finally {
editing = false;
}
}
protected abstract void onTextChange(CharSequence s, int start,
int before, int count);
@Override
public final void afterTextChanged(Editable s) {
if (editing)
return;
editing = true;
try {
afterTextChange(s);
} finally {
editing = false;
}
}
public boolean isEditing() {
return editing;
}
protected abstract void afterTextChange(Editable s);
}
So when the above is used, any setText()
calls happening within the TextWatcher will not result in the TextWatcher being called again:
因此,当使用上述内容时,setText()
TextWatcher 中发生的任何调用都不会导致再次调用 TextWatcher:
/**
* A setText() call in any of the callbacks below will not result in TextWatcher being
* called again.
*/
public class MyTextWatcher extends EditableTextWatcher {
@Override
protected void beforeTextChange(CharSequence s, int start, int count, int after) {
}
@Override
protected void onTextChange(CharSequence s, int start, int before, int count) {
}
@Override
protected void afterTextChange(Editable s) {
}
}
回答by iHulk
If you are using Kotlin for Android development then you can add TextChangedListener()
using this code:
如果您使用 Kotlin 进行 Android 开发,那么您可以TextChangedListener()
使用以下代码添加:
myTextField.addTextChangedListener(object : TextWatcher{
override fun afterTextChanged(s: Editable?) {}
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})
回答by Burak Dizlek
I wrote my own extension for this, very helpful for me. (Kotlin)
我为此编写了自己的扩展程序,对我很有帮助。(科特林)
You can write only like that :
你只能这样写:
editText.customAfterTextChanged { editable ->
//You have accessed the editable object.
}
My extension :
我的扩展:
fun EditText.customAfterTextChanged(action: (Editable?)-> Unit){
this.addTextChangedListener(object : TextWatcher {
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun afterTextChanged(editable: Editable?) {
action(editable)
}
})}
回答by Ankit Kumar
Add background dynamically in onCreate
method:
在onCreate
方法中动态添加背景:
getWindow().setBackgroundDrawableResource(R.drawable.background);
also remove background from XML.
还从 XML 中删除背景。
回答by Lavish Garg
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (noteid != -1) {
MainActivity.notes.set(noteid, String.valueOf(charSequence));
MainActivity.arrayAdapter.notifyDataSetChanged();
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
in this code noteid is basically arguments taken back which is being putted into the indent or passed through the indent.
在这段代码中,noteid 基本上是取回的参数,这些参数被放入缩进或通过缩进传递。
Intent intent = getIntent();
noteid = intent.getIntExtra("noteid", -1);
the code on the downside is basically the extra code ,if you want to understand more clearly.
缺点的代码基本上是额外的代码,如果你想更清楚地理解。
how to make the menu or insert the menu in our code ,
create the menu folder this the folder created by going into the raw
->rightclick->
directory->name the folder as you wish->
then click on the directory formed->
then click on new file and then name for file as you wish ie the folder name file
and now type the 2 lines code in it and see the magic.
new activity code named as NoteEditor.java for editing purpose,my app is basicley the note app.
用于编辑目的的名为 NoteEditor.java 的新活动代码,我的应用程序基本上是笔记应用程序。
package com.example.elavi.notes;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.EditText;
import android.widget.Toast;
import static android.media.CamcorderProfile.get;
public class NoteEditorActivity extends AppCompatActivity {
EditText editText;
int noteid;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_note_editor);
editText = findViewById(R.id.editText);
Intent intent = getIntent();
noteid = intent.getIntExtra("noteid", -1);
if (noteid != -1) {
String text = MainActivity.notes.get(noteid);
editText.setText(text);
Toast.makeText(getApplicationContext(),"The arraylist content is"+MainActivity.notes.get(noteid),Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(getApplicationContext(),"Here we go",Toast.LENGTH_SHORT).show();
MainActivity.notes.add("");
noteid=MainActivity.notes.size()-1;
}
editText.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
if (noteid != -1) {
MainActivity.notes.set(noteid, String.valueOf(charSequence));
MainActivity.arrayAdapter.notifyDataSetChanged();
}
}
@Override
public void afterTextChanged(Editable editable) {
}
});
}
}