我有一种情况,那里有两个领域。 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("");
}
});
如果我只将addTextChangedListener
附加到field1
,那么它可以正常工作
我在应用程序崩溃的两个字段都这样做。显然是因为他们试图改变
彼此无限期。 field1
更改后,此时会清除field2
field2
已更改,因此会清除field1
,依此类推......
有人可以建议任何解决方案吗?
答案 0 :(得分:367)
您可以添加一个检查,仅在字段中的文本不为空时(即长度不是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("");
}
});
TextWatcher
here的文档。
另请尊重naming conventions。
答案 1 :(得分:14)
我知道这已经过时了,但有一天有人可能会再遇到这个问题。
我有一个类似的问题,我会在EditText上调用setText,而当我不想要它时会调用onTextChanged。我的第一个解决方案是在调用setText()之后编写一些代码以撤消侦听器所造成的损坏。但那不是很优雅。 在做了一些研究和测试后,我发现使用getText()。clear()以与setText("")大致相同的方式清除文本,但由于它没有设置文本听众没有被叫,所以这解决了我的问题。我将所有的setText("")调用切换到getText()。clear(),我不再需要绷带了,所以也许这也可以解决你的问题。
试试这个:
SelectedItem="{Binding SelectedComboBoxItem}"
答案 2 :(得分:8)
在科特林中,只需使用 KTX扩展功能:
(它使用TextWatcher
)
yourEditText.doOnTextChanged { text, start, count, after ->
// action which will be invoked when the text is changing
}
导入core-KTX
:
implementation "androidx.core:core-ktx:1.2.0"
答案 3 :(得分:7)
如果您将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) {}
})
答案 4 :(得分:5)
答案有点晚,但这是一个可重复使用的解决方案:
/**
* 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);
}
因此,当使用上述内容时,TextWatcher中发生的任何setText()
调用都不会导致再次调用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) {
}
}
答案 5 :(得分:4)
我也遇到了同样的问题并继续获得堆栈完全异常,并且我提供了以下解决方案。
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;
}
}
});
最初声明boolean skipOnChange = false;
答案 6 :(得分:3)
在将另一个EditText
设置为空之前检查字符串。如果Field1
为空,那么为什么需要再次更改为(“”)?所以你可以用 s.lenght()或任何其他解决方案检查你的字符串的大小
另一种可以检查字符串长度的方法是:
String sUsername = Field1.getText().toString();
if (!sUsername.matches(""))
{
// do your job
}
答案 7 :(得分:3)
您还可以使用hasFocus()方法:
public void onTextChanged(CharSequence s, int start,
int before, int count) {
if (Field2.hasfocus()){
Field1.setText("");
}
}
对于大学作业进行了测试我正在努力在用户输入时转换温标。工作得很完美,而且方式更简单。
答案 8 :(得分:2)
我为此写了自己的扩展名,对我很有帮助。 (科特琳)
您只能这样写:
editText.customAfterTextChanged { editable ->
//You have accessed the editable object.
}
我的扩展名:
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)
}
})}
答案 9 :(得分:2)
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) {
}
});
这段代码中的noteid基本上是取回的参数,这些参数被放入缩进或通过缩进传递。
Intent intent = getIntent();
noteid = intent.getIntExtra("noteid", -1);
如果您想更清楚地了解,缺点就是基本上是多余的代码。
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.
名为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) {
}
});
}
}
答案 10 :(得分:1)
我们可以在编辑文本之前删除TextWatcher字段,然后在编辑文本后将其重新添加。
为 field1 和 field2 声明文本监视程序作为单独的变量,为它们命名:对于 field1
private TextWatcher Field_1_Watcher = new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
};
然后使用其名称添加观察者:
field1.addTextChangedListener(Field_1_Watcher)
用于 field1 ,并且
field2.addTextChangedListener(Field_2_Watcher)
用于 field2
在更改 field2 文本之前,请删除TextWatcher:
field2.removeTextChangedListener(Field_2_Watcher)
更改文字:
field2.setText("")
然后重新添加TextWatcher:
field2.addTextChangedListener(Field_2_Watcher)
对其他字段执行相同操作
答案 11 :(得分:1)
另一种可以帮助某人的解决方案。有2个EditText,它们在编辑后会相互更改。默认情况下,它导致周期性。
使用变量:
Boolean uahEdited = false;
Boolean usdEdited = false;
添加TextWatcher
uahEdit = findViewById(R.id.uahEdit);
usdEdit = findViewById(R.id.usdEdit);
uahEdit.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (!usdEdited) {
uahEdited = true;
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String tmp = uahEdit.getText().toString();
if(!tmp.isEmpty() && uahEdited) {
uah = Double.valueOf(tmp);
usd = uah / 27;
usdEdit.setText(String.valueOf(usd));
} else if (tmp.isEmpty()) {
usdEdit.getText().clear();
}
}
@Override
public void afterTextChanged(Editable s) {
uahEdited = false;
}
});
usdEdit.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
if (!uahEdited) {
usdEdited = true;
}
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
String tmp = usdEdit.getText().toString();
if (!tmp.isEmpty() && usdEdited) {
usd = Double.valueOf(tmp);
uah = usd * 27;
uahEdit.setText(String.valueOf(uah));
} else if (tmp.isEmpty()) {
uahEdit.getText().clear();
}
}
@Override
public void afterTextChanged(Editable s) {
usdEdited = false;
}
});
不要批评太多。我是新手开发人员
答案 12 :(得分:0)
通过onCreate
方法动态添加背景:
getWindow().setBackgroundDrawableResource(R.drawable.background);
还要从XML中删除背景。
答案 13 :(得分:0)
var filenameText = findViewById(R.id.filename) as EditText
filenameText.addTextChangedListener(object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
filename = filenameText.text.toString()
Log.i("FileName: ", filename)
}
override fun beforeTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {}
})