Сенсорный калькулятор в Android
Я пытаюсь создать дизайн калькулятора. Но я не получаю никаких ошибок во время компиляции. Наконец, во время выполнения проекта / кода произошла ошибка исключения nullpointer.
MainActivity.java:
public class MainActivity extends Activity {
GridView mKeypadGrid;
KeyAdapter mKeypadAdapter;
private TextView userInputText;
private boolean resetInput;
private boolean hasFinalResult;
private String mDecimalSeperator;
private Stack<String> mInputStack;
private Stack<String> mOperationStack;
private double memoryValue;
private TextView mStackText;
private TextView memoryStatText;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userInputText= (TextView) findViewById(R.id.txtInput);
mStackText=(TextView)findViewById(R.id.txtStack);
memoryStatText=(TextView)findViewById(R.id.txtMemory);
mKeypadGrid = (GridView)findViewById(R.id.grdButtons);
mKeypadAdapter = new KeyAdapter(this);
mKeypadGrid.setAdapter(mKeypadAdapter);
mKeypadAdapter.setOnButtonClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
Button btn = (Button) v;
KeypadButton keypadButton = (KeypadButton) btn.getTag();
ProcessKeypadInput(keypadButton);
}});
mKeypadGrid.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,int position, long id) {
}
});
}
public void ProcessKeypadInput(KeypadButton keypadButton) {
String text = keypadButton.getText().toString();
String currentInput = userInputText.getText().toString();
int currentInputLen = currentInput.length();
String evalResult = null;
double userInputValue = Double.NaN;
switch (keypadButton) {
case BACKSPACE:
if (resetInput)
return;
int endIndex = currentInputLen - 1;
if (endIndex < 1) {
userInputText.setText("0");
}
else {
userInputText.setText(currentInput.subSequence(0, endIndex));
}
break;
case SIGN:
if (currentInputLen > 0 && currentInput != "0") {
if (currentInput.charAt(0) == '-') {
userInputText.setText(currentInput.subSequence(1,
currentInputLen));
}
else {
userInputText.setText("-" + currentInput.toString());
}
}
break;
case CE:
userInputText.setText("0");
break;
case C:
userInputText.setText("0");
clearStacks();
break;
case DECIMAL_SEP:
if (hasFinalResult || resetInput) {
userInputText.setText("0" + mDecimalSeperator);
hasFinalResult = false;
resetInput = false;
} else if (currentInput.contains("."))
return;
else
userInputText.append(mDecimalSeperator);
break;
case DIV:
case PLUS:
case MINUS:
case MULTIPLY:
if (resetInput) {
mInputStack.pop();
mOperationStack.pop();
} else {
if (currentInputLen >0) {
if (currentInput.charAt(0) == '-') {
} else {
if(currentInput!=null)
mInputStack.add(currentInput);
}
mOperationStack.add(currentInput);
}
}
if(text!=null){
mInputStack.add(text); //132nd Line
mOperationStack.add(text);
}
dumpInputStack();
evalResult = evaluateResult(false);
if (evalResult != null)
userInputText.setText(evalResult);
resetInput = true;
break;
case CALCULATE:
if (mOperationStack.size() == 0)
break;
mOperationStack.add(currentInput);
evalResult = evaluateResult(true);
if (evalResult != null) {
clearStacks();
userInputText.setText(evalResult);
resetInput = false;
hasFinalResult = true;
}
break;
case M_ADD:
userInputValue = tryParseUserInput();
if (Double.isNaN(userInputValue))
return;
if (Double.isNaN(memoryValue))
memoryValue = 0;
memoryValue += userInputValue;
displayMemoryStat();
hasFinalResult = true;
break;
case M_REMOVE:
userInputValue = tryParseUserInput();
if (Double.isNaN(userInputValue))
return;
if (Double.isNaN(memoryValue))
memoryValue = 0;
memoryValue -= userInputValue;
displayMemoryStat();
hasFinalResult = true;
break;
case MC:
memoryValue = Double.NaN;
displayMemoryStat();
break;
case MR:
if (Double.isNaN(memoryValue))
return;
userInputText.setText(doubleToString(memoryValue));
displayMemoryStat();
break;
case MS:
userInputValue = tryParseUserInput();
if (Double.isNaN(userInputValue))
return;
memoryValue = userInputValue;
displayMemoryStat();
hasFinalResult = true;
break;
default:
if (Character.isDigit(text.charAt(0))) {
if (currentInput.equals("0") || resetInput || hasFinalResult) {
userInputText.setText(text);
resetInput = false;
hasFinalResult = false;
} else {
userInputText.append(text);
resetInput = false;
}
}
break;
}
}
public void clearStacks() {
mInputStack.clear();
mOperationStack.clear();
mStackText.setText("");
}
public void dumpInputStack() {
Iterator<String> it = mInputStack.iterator();
StringBuilder sb = new StringBuilder();
while (it.hasNext()) {
CharSequence iValue = it.next();
sb.append(iValue);
}
mStackText.setText(sb.toString());
}
public String evaluateResult(boolean requestedByUser) {
if ((!requestedByUser && mOperationStack.size() != 4)
|| (requestedByUser && mOperationStack.size() != 3))
return null;
String left = (String) mOperationStack.get(0);
String operator = (String) mOperationStack.get(1);
String right = (String) mOperationStack.get(2);
String tmp = null;
if (!requestedByUser)
tmp = (String) mOperationStack.get(3);
double leftVal = Double.parseDouble(left.toString());
double rightVal = Double.parseDouble(right.toString());
double result = Double.NaN;
if (operator.equals(KeypadButton.DIV.getText())) {
result = leftVal / rightVal;
} else if (operator.equals(KeypadButton.MULTIPLY.getText())) {
result = leftVal * rightVal;
} else if (operator.equals(KeypadButton.PLUS.getText())) {
result = leftVal + rightVal;
} else if (operator.equals(KeypadButton.MINUS.getText())) {
result = leftVal - rightVal;
}
String resultStr = doubleToString(result);
if (resultStr == null)
return null;
mOperationStack.clear();
if (!requestedByUser) {
mOperationStack.add(resultStr);
mOperationStack.add(tmp);
}
return resultStr;
}
public String doubleToString(double value) {
if (Double.isNaN(value))
return null;
long longVal = (long) value;
if (longVal == value)
return Long.toString(longVal);
else
return Double.toString(value);
}
public double tryParseUserInput() {
String inputStr = userInputText.getText().toString();
double result = Double.NaN;
try {
result = Double.parseDouble(inputStr);
} catch (NumberFormatException nfe) {}
return result;
}
public void displayMemoryStat() {
if (Double.isNaN(memoryValue)) {
memoryStatText.setText("");
} else {
memoryStatText.setText("M = " + doubleToString(memoryValue));
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/txtStack"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:gravity="right"
android:layout_marginTop = "3sp"
android:layout_marginLeft = "5sp"
android:layout_marginRight = "5sp"/>
<TextView
android:id="@+id/txtInput"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="25sp"
android:gravity="right"
android:layout_marginLeft = "5sp"
android:layout_marginRight = "5sp"/>
<TextView
android:id="@+id/txtMemory"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:textSize="15sp"
android:gravity="left"
android:layout_marginLeft = "5sp"
android:layout_marginRight = "5sp"/>
<GridView
android:id="@+id/grdButtons"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:columnWidth="90dp"
android:numColumns="5"
android:verticalSpacing="10dp"
android:horizontalSpacing="10dp"
android:stretchMode="columnWidth"
android:gravity="center"/>
</LinearLayout>
Выход:
Трассировки стека:
E/AndroidRuntime(1492): FATAL EXCEPTION: main
E/AndroidRuntime(1492): Process: com.calculator, PID: 1492
E/AndroidRuntime(1492): java.lang.NullPointerException
E/AndroidRuntime(1492): at com.calculator.MainActivity.ProcessKeypadInput(MainActivity.java:132)
E/AndroidRuntime(1492): at com.calculator.MainActivity$1.onClick(MainActivity.java:50)
E/AndroidRuntime(1492): at android.view.View.performClick(View.java:4438)
E/AndroidRuntime(1492): at android.view.View$PerformClick.run(View.java:18422)
E/AndroidRuntime(1492): at android.os.Handler.handleCallback(Handler.java:733)
E/AndroidRuntime(1492): at android.os.Handler.dispatchMessage(Handler.java:95)
E/AndroidRuntime(1492): at android.os.Looper.loop(Looper.java:136)
E/AndroidRuntime(1492): at android.app.ActivityThread.main(ActivityThread.java:5017)
E/AndroidRuntime(1492): at java.lang.reflect.Method.invokeNative(Native Method)
E/AndroidRuntime(1492): at java.lang.reflect.Method.invoke(Method.java:515)
E/AndroidRuntime(1492): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
E/AndroidRuntime(1492): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
E/AndroidRuntime(1492): at dalvik.system.NativeStart.main(Native Method)
Я не знаю, как исправить ошибку исключения NullPointer.
Проблема во время нажатия
+(плюс),-(минус),*(мул),/(див),MC,MR,C,=(равно) и запятая Произошла ошибка Logcat. Другие кнопки, такие как 0,1,2,3-9, это хорошо.Ваш ответ будет приветствоваться здесь.
Спасибо
2 ответа
В onCreate необходимо добавить findViewById для userInputText
userInputText= (TextView) findViewById(R.id.txtInput);
Аналогично и для других компонентов макета, иначе нет идентификации для getText()
И когда вы это сделаете, пожалуйста, не используйте один и тот же TextView из кода для всех компонентов...
userInputText= (TextView) findViewById(R.id.txtInput);
userInputText=(TextView)findViewById(R.id.txtStack);
userInputText=(TextView)findViewById(R.id.txtMemory);
это неверно.
Используйте разные TextView для стека и памяти.... как stackInputText, memoryInputText
Под вашим ProcessKeypadInput
метод, у вас есть следующий код:
case MULTIPLY:
if (resetInput) {
mInputStack.pop();
mOperationStack.pop();
} else {
if (currentInput.charAt(0) == '-') { // <-------- Problem line
mInputStack.add("(" + currentInput + ")");
} else {
mInputStack.add(currentInput);
}
mOperationStack.add(currentInput);
}
Я указал, какая строка вызывает проблему, которую вы видите в logcat. Вы пытаетесь оценить первый персонаж currentInput
но не имеет ничего, что обеспечит currentInput
содержит любые символы. Если вы попытаетесь вычислить первый символ строки, в которой вообще нет символов, она выдаст исключение, которое вы видите.
Одним из решений было бы изменить указанную строку и ниже следующее:
...
if (currentInputLen > 0) {
if (currentInput.charAt(0) == '-') {
mInputStack.add("(" + currentInput + ")");
} else {
mInputStack.add(currentInput);
}
mOperationStack.add(currentInput);
}
}
Это предотвратит эту попытку оценить первый символ, если строка не содержит хотя бы одного символа, а также предотвратит исключения нулевого указателя.