Android 如何管理EditText和addTextChangedListener以避免堆栈溢出
各位晚上好 这是一个连续不断的问题 我在处理三个Android 如何管理EditText和addTextChangedListener以避免堆栈溢出,android,android-layout,android-studio,android-activity,android-edittext,Android,Android Layout,Android Studio,Android Activity,Android Edittext,各位晚上好 这是一个连续不断的问题 我在处理三个EditTexts时遇到一些问题。用户可以在其中的每一个中输入一个值,然后计算其他两个值,这两个值显示在其他两个EditTexts中。当我尝试键入一个值时,它会崩溃 代码如下: public class MainActivity extends AppCompatActivity { EditText Percent, mmolGlic, mgGlic; double mmol = 0, mg = 0, perc = 0; @Override
EditText
s时遇到一些问题。用户可以在其中的每一个中输入一个值,然后计算其他两个值,这两个值显示在其他两个EditText
s中。当我尝试键入一个值时,它会崩溃
代码如下:
public class MainActivity extends AppCompatActivity {
EditText Percent, mmolGlic, mgGlic;
double mmol = 0, mg = 0, perc = 0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Percent = (EditText) findViewById(R.id.percent);
mmolGlic = (EditText) findViewById(R.id.mmol_glic);
mgGlic = (EditText) findViewById(R.id.mg_glic);
Percent.addTextChangedListener(percentWatcher);
mmolGlic.addTextChangedListener(mmolGlicTextWatcher);
mgGlic.addTextChangedListener(mgGlicWatcher);
}
public void frommMol() {
if (!mmolGlic.getText().toString().trim().isEmpty()) {
mmol = Double.parseDouble(mmolGlic.getText().toString());
perc = (mmol / 10.929) + 2.15;
Percent.removeTextChangedListener(percentWatcher);
Percent.setText(String.format("%.2f", perc));
Percent.addTextChangedListener(percentWatcher);
}
}
public void fromPercent() {
if (!Percent.getText().toString().trim().isEmpty()) {
perc = Double.parseDouble(Percent.getText().toString().trim());
mmol = (perc - 2.15) * 10.929;
mmolGlic.removeTextChangedListener(mmolGlicTextWatcher);
mgGlic.removeTextChangedListener(mgGlicWatcher);
mmolGlic.setText(String.format("%.2f", mmol));
mg = (perc * 28.7) - 46.7;
mgGlic.setText(String.format("%.2f", mg));
mmolGlic.addTextChangedListener(mmolGlicTextWatcher);
mgGlic.addTextChangedListener(mgGlicWatcher);
}
}
public void frommg() {
if (!mgGlic.getText().toString().trim().isEmpty()) {
mg = Double.parseDouble(mgGlic.getText().toString());
perc = (mg + 46.7) / 28.7;
Percent.removeTextChangedListener(percentWatcher);
Percent.setText(String.format("%.2f", perc));
Percent.addTextChangedListener(percentWatcher);
}
}
private TextWatcher percentWatcher = 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) {
fromPercent();
}
@Override
public void afterTextChanged(Editable editable) {
}
};
private TextWatcher mgGlicWatcher = 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) {
frommg();
}
@Override
public void afterTextChanged(Editable editable) {
}
};
private TextWatcher mmolGlicTextWatcher = 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) {
frommMol();
}
@Override
public void afterTextChanged(Editable editable) {
}
};
}
我发现这一点,我认为它可能会有所帮助,但我不知道如何将其应用到我的案例中
你能帮我吗
编辑1:
FATAL EXCEPTION: main
Process: com.example.marco.glicatest, PID: 3843
java.lang.StackOverflowError: stack size 8MB
at android.text.SpannableStringBuilder.getSpans(SpannableStringBuilder.java:819)
at android.text.method.ReplacementTransformationMethod$SpannedReplacementCharSequence.getSpans(ReplacementTransformationMethod.java:184)
at android.text.SpanSet.init(SpanSet.java:47)
at android.text.TextLine.handleRun(TextLine.java:902)
at android.text.TextLine.measureRun(TextLine.java:417)
at android.text.TextLine.measure(TextLine.java:296)
at android.text.TextLine.metrics(TextLine.java:270)
at android.text.Layout.getLineExtent(Layout.java:1075)
at android.text.Layout.getLineStartPos(Layout.java:565)
at android.text.Layout.getHorizontal(Layout.java:938)
at android.text.Layout.getHorizontal(Layout.java:907)
at android.text.Layout.getPrimaryHorizontal(Layout.java:882)
at android.text.Layout.getPrimaryHorizontal(Layout.java:872)
at android.widget.TextView.getFocusedRect(TextView.java:5747)
at android.view.FocusFinder.findNextFocus(FocusFinder.java:120)
at android.view.FocusFinder.findNextFocus(FocusFinder.java:94)
at android.view.FocusFinder.findNextFocus(FocusFinder.java:65)
at android.view.ViewGroup.focusSearch(ViewGroup.java:853)
at android.view.ViewGroup.focusSearch(ViewGroup.java:855)
at android.view.ViewGroup.focusSearch(ViewGroup.java:855)
at android.view.ViewGroup.focusSearch(ViewGroup.java:855)
at android.view.ViewGroup.focusSearch(ViewGroup.java:855)
at android.view.ViewGroup.focusSearch(ViewGroup.java:855)
at android.view.ViewGroup.focusSearch(ViewGroup.java:855)
at android.view.ViewGroup.focusSearch(ViewGroup.java:855)
at android.view.View.focusSearch(View.java:8086)
at android.widget.TextView.onCreateInputConnection(TextView.java:6283)
at android.view.inputmethod.InputMethodManager.startInputInner(InputMethodManager.java:1177)
at android.view.inputmethod.InputMethodManager.restartInput(InputMethodManager.java:1124)
at android.widget.TextView.setText(TextView.java:4262)
at android.widget.TextView.setText(TextView.java:4199)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4174)
at com.example.marco.glicatest.MainActivity.frommMol(MainActivity.java:44)
at com.example.marco.glicatest.MainActivity$3.onTextChanged(MainActivity.java:141)
at android.widget.TextView.sendOnTextChanged(TextView.java:7991)
at android.widget.TextView.setText(TextView.java:4345)
at android.widget.TextView.setText(TextView.java:4199)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4174)
at com.example.marco.glicatest.MainActivity.fromPercent(MainActivity.java:65)
at com.example.marco.glicatest.MainActivity$1.onTextChanged(MainActivity.java:107)
at android.widget.TextView.sendOnTextChanged(TextView.java:7991)
at android.widget.TextView.setText(TextView.java:4345)
at android.widget.TextView.setText(TextView.java:4199)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4174)
at com.example.marco.glicatest.MainActivity.frommMol(MainActivity.java:44)
at com.example.marco.glicatest.MainActivity$3.onTextChanged(MainActivity.java:141)
at android.widget.TextView.sendOnTextChanged(TextView.java:7991)
at android.widget.TextView.setText(TextView.java:4345)
at android.widget.TextView.setText(TextView.java:4199)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4174)
at com.example.marco.glicatest.MainActivity.fromPercent(MainActivity.java:65)
at com.example.marco.glicatest.MainActivity$1.onTextChanged(MainActivity.java:107)
at android.widget.TextView.sendOnTextChanged(TextView.java:7991)
at android.widget.TextView.setText(TextView.java:4345)
at android.widget.TextView.setText(TextView.java:4199)
at android.widget.EditText.setText(EditText.java:84)
at android.widget.TextView.setText(TextView.java:4174)
at com.example.marco.glicatest.MainActivity.frommMol(Main
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 9495276)
E/AndroidRuntime: Error reporting crash
android.os.TransactionTooLargeException: data parcel size 9495276 bytes
at android.os.BinderProxy.transactNative(Native Method)
at android.os.BinderProxy.transact(Binder.java:503)
at android.app.ActivityManagerProxy.handleApplicationCrash(ActivityManagerNative.java:4425)
at com.android.internal.os.RuntimeInit$UncaughtHandler.uncaughtException(RuntimeInit.java:90)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:693)
at java.lang.ThreadGroup.uncaughtException(ThreadGroup.java:690)
试试这个:注意,我不知道为什么会这样,但我也遇到过类似的问题,这就是我解决问题的原因 不要在全球范围内声明您的编辑文本。当你稍后打电话给他们时,会导致崩溃。相反,每次要设置值时,都要在函数中声明EditText 因此,在FROMMOL、fromPercent和frommg中,将这些行添加到函数的顶部。以下是您将如何为fromPercent执行此操作:
public void fromPercent() {
EditText Percent = (EditText) findViewById(R.id.percent);
EditText mmolGlic = (EditText) findViewById(R.id.mmol_glic);
EditText mgGlic = (EditText) findViewById(R.id.mg_glic);
if (!Percent.getText().toString().trim().isEmpty()) {
perc = Double.parseDouble(Percent.getText().toString().trim());
mmol = (perc - 2.15) * 10.929;
mmolGlic.removeTextChangedListener(mmolGlicTextWatcher);
mgGlic.removeTextChangedListener(mgGlicWatcher);
mmolGlic.setText(String.format("%.2f", mmol));
mg = (perc * 28.7) - 46.7;
mgGlic.setText(String.format("%.2f", mg));
mmolGlic.addTextChangedListener(mmolGlicTextWatcher);
mgGlic.addTextChangedListener(mgGlicWatcher);
}
}
您坚持使用无限递归,因为您的代码会导致这样的循环,如下所示:
- 如果A改变,B也会改变
- 如果B改变,C也会改变
- 如果C改变,A也会改变
- 如果A改变,B也会改变
- 。。。依此类推,直到内存堆栈已满()
TextView
。例如:
public void fromMg() {
mgGlicText = mgGlic.getText().toString().trim();
if (!mgGlicText.isEmpty()) {
mg = Double.parseDouble(mgGlicText);
perc = (mg + 46.7) / 28.7;
// percent.removeTextChangedListener(percentWatcher); // not needed
String newText = String.format("%.2f", perc);
String oldText = percent.getText().toString();
/* Check if the text is different, if so then change it */
if (!newText.equals(oldText))
percent.setText(newText);
// percent.addTextChangedListener(percentWatcher); // not needed
} else {
if (percent.getText().length() > 0) // !percent.getText().toString().equals("")
percent.setText("");
}
}
通过使用条件if(!newText.equals(oldText))
仅在确实需要更改时更新TextView
,以缩短我们上面解释的周期。它将是:
- 如果A改变了,如果B真的需要改变,B也会改变
- 如果B改变了,如果C真的需要改变,C也会改变
- 如果C改变了,如果A真的需要改变,A也会改变
您需要在另外两个
EditText
s中执行此操作,并根据您的需要进行调整。这只是一个示例。请从您的crash@GreyBeardedGeek堆栈跟踪添加我应该为每个方法都这样做吗?是的,尝试一下,看看它是否修复了它。如果是,请接受这一正确答案!是的,我认为问题出在自行车上,但我不知道如何解决。你能解释一下你在最后两行中做了什么吗?@Mark。正如我所说:“检查您是否真的需要更新其他TextView”。对不起,如果不清楚,我会更新答案。我有一些问题:1。“编辑方法(以您的方式)”也将出现在ContextChange中?2.在我从其中一个视图中删除值时,有一种方法可以删除它在其他视图中写入的内容?@Mark。1.你需要在其中的三个方面做到这一点,因为它们相互依赖;2.只需删除它,例如,当文本为空时,只需记住仅当确实需要更改时才调用setText
。