Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/316.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java android上的文本更改侦听器_Java_Android_Textview_Onchange - Fatal编程技术网

Java android上的文本更改侦听器

Java android上的文本更改侦听器,java,android,textview,onchange,Java,Android,Textview,Onchange,我有一种情况,有两个领域字段1和字段2。我想要的一切 更改field1时,待办事项为空field2,反之亦然。所以最后才 一个字段上有内容 field1 = (EditText)findViewById(R.id.field1); field2 = (EditText)findViewById(R.id.field2); field1.addTextChangedListener(new TextWatcher() { public void afterTextChanged(Edit

我有一种情况,有两个领域<代码>字段1和
字段2
。我想要的一切 更改
field1
时,待办事项为空
field2
,反之亦然。所以最后才 一个字段上有内容

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时),才可以添加复选框以清除

TextWatcher的文档


另外,请尊重。

在将另一个
EditText
设置为空之前检查字符串。如果
Field1
为空,那么为什么需要再次更改为(“”)?因此,您可以使用s.lenght()或任何其他解决方案检查字符串的大小

检查字符串长度的另一种方法是:

String sUsername = Field1.getText().toString();
if (!sUsername.matches(""))
{
// do your job
}

我也遇到了同样的问题,并不断得到
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;
        }
    }
});

声明的初始布尔值skipOnChange=false

您还可以使用hasFocus()方法:


在我正在做的一项大学作业中测试了这一点,在用户输入时转换温标。它工作得很好,而且更简单。

我知道这很旧,但有一天可能会有人再次遇到它

我遇到了一个类似的问题,我会在EditText上调用setText,而在我不想调用的时候会调用ContextChanged。我的第一个解决方案是在调用setText()后编写一些代码,以撤销侦听器造成的损坏。但那不是很优雅。 在做了一些研究和测试之后,我发现使用getText().clear()清除文本的方式与setText(“”)清除文本的方式大致相同,但由于它没有设置文本,因此不会调用侦听器,因此解决了我的问题。我将所有setText(“”)调用都切换到getText().clear(),我不再需要绷带了,所以也许这也能解决您的问题

试试这个:

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();
   }
  });

回答有点晚,但这里有一个可重用的解决方案:

/**
 * 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) {
    }
}

如果您使用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) {}
    })

我为此编写了自己的扩展,对我很有帮助。(科特林)

你只能这样写:

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)
    }
})}

onCreate
方法中动态添加背景:

getWindow().setBackgroundDrawableResource(R.drawable.background);
还要从XML中删除背景

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.
新的活动代码命名为noteditor.java。出于编辑目的,我的应用程序基本上就是note应用程序

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) {

            }
        });
    }
}

Kotlin中,只需使用KTX扩展功能即可: (它使用
TextWatcher


导入核心KTX:

implementation "androidx.core:core-ktx:1.2.0"

我们可以在编辑文本之前删除字段的TextWatcher,然后在编辑文本后将其添加回

将field1和field2的文本监视程序声明为单独的变量,为它们命名:例如,field1

然后使用其名称添加观察者:
field1.addTextChangedListener(Field\u 1\u Watcher)
用于field1,以及
field2.addTextChangedListener(Field\u 2\u Watcher)
用于field2

更改field2文本之前,请删除TextWatcher:
field2.removeTextChangedListener(Field\u 2\u Watcher)
更改文本:
field2.setText(“”)

然后重新添加TextWatcher:
field2.addTextChangedListener(字段观察者)


对另一个字段执行相同的操作

另一个可能有帮助的解决方案。有两个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;
        }
    });

不要批评太多。我是一名新手开发人员

当用户输入editText.setText时,该如何处理?EditText在这种情况下有重点,这是最好的解决方案。“堆栈已满”我想你指的是堆栈溢出;)如何在所有字段更改后进行检测,因为在按下任何按钮时,它会在每次更改时进行检测。对于新用户,请使用可观察的字符串字段进行双向数据绑定,因为此处提供的所有解决方案可能会产生
开始等待阻止gc alloc
这类错误,甚至可能导致崩溃和挂起。。所以选择数据绑定,这是安全的,谷歌现在推荐的。很好。这么干净
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) {}
})
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) {

    }

};
Boolean uahEdited = false;
Boolean usdEdited = false;
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;
        }
    });
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) {}
})