坚持使用 Android Studio:使用 "Double" 作为 Text Watcher
Stuck with Android Studio: Using "Double" for Text Watcher
我目前正在为这个温度转换器应用程序苦苦挣扎。这个应用程序的工作原理是,如果我在空白文本中输入一个数字,它会计算到其他温度单位而无需单击按钮(通过 Text Watcher)
在这里,我需要使用 Double 值从 EditText 中提取数字,并使用该值生成一个方程并将其插入到结果视图中。所以在这种情况下,我使用的是:
double tempWantCtoF = 1.8 * tempWhat + 32;
double tempWantFtoC = tempWhat - 32 * 0.55;
而temp在EditText中插入的值是多少。
应用程序可以正常运行,直到我在文本字段中输入任何数字并且应用程序崩溃并显示错误消息到主屏幕,"Unfortunately, APP NAME has stopped."
我认为在 Text Watcher 方法实现的 afterTextChanged 下使用双精度值是一个问题。
如果有人知道是什么导致了这个问题,我将不胜感激。
这是我的主要 activity XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="josephshin.tempconv.MainActivity"
android:textAlignment="center">
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tempSwitch"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:checked="false" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/tempIndicator"
android:layout_below="@+id/tempSwitch"
android:layout_centerHorizontal="true"
android:text="@string/c_to_f"
android:layout_marginTop="20dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/is"
android:id="@+id/isLabel"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/enter_your_temperature"
android:id="@+id/tempResult"
android:layout_below="@+id/isLabel"
android:layout_centerHorizontal="true"
android:singleLine="true"
android:layout_marginTop="85dp" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:ems="10"
android:id="@+id/tempEdit"
android:layout_below="@+id/tempIndicator"
android:layout_centerHorizontal="true"
android:layout_marginTop="49dp"
android:hint="@string/enter_your_temperature"
android:textAlignment="center" />
</RelativeLayout>
这是我的主要 ACTIVITY JAVA 文件:
package josephshin.tempconv;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
boolean CtoF;
double tempWhat;
double tempWantCtoF = 1.8 * tempWhat + 32;
double tempWantFtoC = tempWhat - 32 * 0.55;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Switch tempSwitch = (Switch) findViewById(R.id.tempSwitch);
final TextView tempIndicator = (TextView) findViewById(R.id.tempIndicator);
final EditText tempLabel = (EditText) findViewById(R.id.tempEdit);
final TextView result = (TextView) findViewById(R.id.tempResult);
tempSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if (isChecked) {
tempIndicator.setText("°F to °C");
CtoF = false;
}
else {
tempIndicator.setText("°C to °F");
CtoF = true;
}
}
});
tempLabel.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) {
}
@Override
public void afterTextChanged(Editable edi) {
tempWhat = Double.parseDouble(tempLabel.toString());
if (CtoF){
result.setText("" + tempWantCtoF);
}
if (!CtoF){
result.setText("" + tempWantFtoC);
}
}
});
}
}
谢谢! ps。我是初学者!刚开始接触这个,但似乎找不到足够相似的问题。
编辑>
logcat 将文本框留空
FATAL EXCEPTION: main
Process: josephshin.tempconv, PID: 31895
java.lang.NumberFormatException: Invalid double: ""
at java.lang.StringToReal.invalidReal(StringToReal.java:63)
at java.lang.StringToReal.parseDouble(StringToReal.java:267)
at java.lang.Double.parseDouble(Double.java:301)
at josephshin.tempconv.MainActivity.afterTextChanged(MainActivity.java:56)
at android.widget.TextView.sendAfterTextChanged(TextView.java:9271)
at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:12015)
at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1047)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:564)
at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:225)
at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:34)
at android.text.method.BaseKeyListener.backspaceOrForwardDelete(BaseKeyListener.java:106)
at android.text.method.BaseKeyListener.backspace(BaseKeyListener.java:51)
at android.text.method.BaseKeyListener.onKeyDown(BaseKeyListener.java:215)
at android.text.method.NumberKeyListener.onKeyDown(NumberKeyListener.java:138)
at android.widget.TextView.doKeyDown(TextView.java:7187)
at android.widget.TextView.onKeyDown(TextView.java:6994)
at android.view.KeyEvent.dispatch(KeyEvent.java:3249)
at android.view.View.dispatchKeyEvent(View.java:9838)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at com.android.internal.policy.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:2808)
at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1838)
at android.app.Activity.dispatchKeyEvent(Activity.java:2977)
at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:543)
at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:53)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:312)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2682)
at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:5273)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5226)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4673)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4726)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4692)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4834)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4700)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4891)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4673)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4726)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4692)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4700)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4673)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7359)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7237)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7198)
at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:4310)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7225)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
a
在将其转换为 Double 之前检查空字符串。
像这样,
if(tempLabel.getText().toString().equals("")){
tempWhat=0;
}else{
tempWhat = Double.parseDouble(tempLabel.getText().toString());
}
你犯了一些错误。
首先,您应该将 tempWantCtoF
和 tempWantFtoC
声明为方法,而不是变量:
private double tempWantCtoF() {
return 1.8 * tempWhat + 32;
}
private double tempWantFtoC() {
return tempWhat - 32 * 0.55;
}
其次,要获取TextView
的文本,不要使用toString
,而是使用getText().toString()
:
tempWhat = Double.parseDouble(tempLabel.getText().toString());
这也是错误发生的原因。
您可能还想添加一些错误处理代码:
try {
tempWhat = Double.parseDouble(tempLabel.getText().toString());
} catch (NumberFormatException ex) {
return;
}
我目前正在为这个温度转换器应用程序苦苦挣扎。这个应用程序的工作原理是,如果我在空白文本中输入一个数字,它会计算到其他温度单位而无需单击按钮(通过 Text Watcher)
在这里,我需要使用 Double 值从 EditText 中提取数字,并使用该值生成一个方程并将其插入到结果视图中。所以在这种情况下,我使用的是:
double tempWantCtoF = 1.8 * tempWhat + 32;
double tempWantFtoC = tempWhat - 32 * 0.55;
而temp在EditText中插入的值是多少。
应用程序可以正常运行,直到我在文本字段中输入任何数字并且应用程序崩溃并显示错误消息到主屏幕,"Unfortunately, APP NAME has stopped."
我认为在 Text Watcher 方法实现的 afterTextChanged 下使用双精度值是一个问题。
如果有人知道是什么导致了这个问题,我将不胜感激。
这是我的主要 activity XML 文件:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="josephshin.tempconv.MainActivity"
android:textAlignment="center">
<Switch
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/tempSwitch"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:checked="false" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:id="@+id/tempIndicator"
android:layout_below="@+id/tempSwitch"
android:layout_centerHorizontal="true"
android:text="@string/c_to_f"
android:layout_marginTop="20dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/is"
android:id="@+id/isLabel"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/enter_your_temperature"
android:id="@+id/tempResult"
android:layout_below="@+id/isLabel"
android:layout_centerHorizontal="true"
android:singleLine="true"
android:layout_marginTop="85dp" />
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal"
android:ems="10"
android:id="@+id/tempEdit"
android:layout_below="@+id/tempIndicator"
android:layout_centerHorizontal="true"
android:layout_marginTop="49dp"
android:hint="@string/enter_your_temperature"
android:textAlignment="center" />
</RelativeLayout>
这是我的主要 ACTIVITY JAVA 文件:
package josephshin.tempconv;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.widget.CompoundButton;
import android.widget.EditText;
import android.widget.Switch;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
boolean CtoF;
double tempWhat;
double tempWantCtoF = 1.8 * tempWhat + 32;
double tempWantFtoC = tempWhat - 32 * 0.55;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Switch tempSwitch = (Switch) findViewById(R.id.tempSwitch);
final TextView tempIndicator = (TextView) findViewById(R.id.tempIndicator);
final EditText tempLabel = (EditText) findViewById(R.id.tempEdit);
final TextView result = (TextView) findViewById(R.id.tempResult);
tempSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton compoundButton, boolean isChecked) {
if (isChecked) {
tempIndicator.setText("°F to °C");
CtoF = false;
}
else {
tempIndicator.setText("°C to °F");
CtoF = true;
}
}
});
tempLabel.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) {
}
@Override
public void afterTextChanged(Editable edi) {
tempWhat = Double.parseDouble(tempLabel.toString());
if (CtoF){
result.setText("" + tempWantCtoF);
}
if (!CtoF){
result.setText("" + tempWantFtoC);
}
}
});
}
}
谢谢! ps。我是初学者!刚开始接触这个,但似乎找不到足够相似的问题。
编辑> logcat 将文本框留空
FATAL EXCEPTION: main
Process: josephshin.tempconv, PID: 31895
java.lang.NumberFormatException: Invalid double: ""
at java.lang.StringToReal.invalidReal(StringToReal.java:63)
at java.lang.StringToReal.parseDouble(StringToReal.java:267)
at java.lang.Double.parseDouble(Double.java:301)
at josephshin.tempconv.MainActivity.afterTextChanged(MainActivity.java:56)
at android.widget.TextView.sendAfterTextChanged(TextView.java:9271)
at android.widget.TextView$ChangeWatcher.afterTextChanged(TextView.java:12015)
at android.text.SpannableStringBuilder.sendAfterTextChanged(SpannableStringBuilder.java:1047)
at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:564)
at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:225)
at android.text.SpannableStringBuilder.delete(SpannableStringBuilder.java:34)
at android.text.method.BaseKeyListener.backspaceOrForwardDelete(BaseKeyListener.java:106)
at android.text.method.BaseKeyListener.backspace(BaseKeyListener.java:51)
at android.text.method.BaseKeyListener.onKeyDown(BaseKeyListener.java:215)
at android.text.method.NumberKeyListener.onKeyDown(NumberKeyListener.java:138)
at android.widget.TextView.doKeyDown(TextView.java:7187)
at android.widget.TextView.onKeyDown(TextView.java:6994)
at android.view.KeyEvent.dispatch(KeyEvent.java:3249)
at android.view.View.dispatchKeyEvent(View.java:9838)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:1739)
at com.android.internal.policy.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:2808)
at com.android.internal.policy.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1838)
at android.app.Activity.dispatchKeyEvent(Activity.java:2977)
at android.support.v7.app.AppCompatActivity.dispatchKeyEvent(AppCompatActivity.java:543)
at android.support.v7.view.WindowCallbackWrapper.dispatchKeyEvent(WindowCallbackWrapper.java:53)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.dispatchKeyEvent(AppCompatDelegateImplBase.java:312)
at com.android.internal.policy.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:2682)
at android.view.ViewRootImpl$ViewPostImeInputStage.processKeyEvent(ViewRootImpl.java:5273)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5226)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4673)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4726)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4692)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4834)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4700)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4891)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4673)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4726)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4692)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4700)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4673)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:7359)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:7237)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:7198)
at android.view.ViewRootImpl$ViewRootHandler.handleMessage(ViewRootImpl.java:4310)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:158)
at android.app.ActivityThread.main(ActivityThread.java:7225)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
a
在将其转换为 Double 之前检查空字符串。 像这样,
if(tempLabel.getText().toString().equals("")){
tempWhat=0;
}else{
tempWhat = Double.parseDouble(tempLabel.getText().toString());
}
你犯了一些错误。
首先,您应该将 tempWantCtoF
和 tempWantFtoC
声明为方法,而不是变量:
private double tempWantCtoF() {
return 1.8 * tempWhat + 32;
}
private double tempWantFtoC() {
return tempWhat - 32 * 0.55;
}
其次,要获取TextView
的文本,不要使用toString
,而是使用getText().toString()
:
tempWhat = Double.parseDouble(tempLabel.getText().toString());
这也是错误发生的原因。
您可能还想添加一些错误处理代码:
try {
tempWhat = Double.parseDouble(tempLabel.getText().toString());
} catch (NumberFormatException ex) {
return;
}