Egert Aia Egert Aia - 2 months ago 7
Android Question

Saving operator on orientation change

I'm trying to make the operator change on switching the orientation.
For instance if user clicks 9 followed by X ( which stands for multiply) and then changes the orientation, followed by 3 and =. I would like it to show 18 rather than 0.

This is my mainactivity:

public class MainActivity extends Activity implements View.OnClickListener{

private static String TAG = "MainActivity";
private EditText mCalculatorDisplay;
private Boolean userIsInTheMiddleOfTypingANumber = false;
private CalculatorBrain mCalculatorBrain;
private static final String DIGITS = "0123456789.";

DecimalFormat df = new DecimalFormat("@###########");

@Override
protected void onCreate(Bundle savedInstanceState) {
if (BuildConfig.DEBUG) { Log.d(TAG, "onCreate called");}

super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mCalculatorBrain = new CalculatorBrain();
mCalculatorDisplay = (EditText) findViewById(R.id.display);

df.setMinimumFractionDigits(0);
df.setMinimumIntegerDigits(1);
df.setMaximumIntegerDigits(8);

findViewById(R.id.Button_Zero).setOnClickListener(this);
findViewById(R.id.Button_One).setOnClickListener(this);
findViewById(R.id.Button_Two).setOnClickListener(this);
findViewById(R.id.Button_Three).setOnClickListener(this);
findViewById(R.id.Button_Four).setOnClickListener(this);
findViewById(R.id.Button_Five).setOnClickListener(this);
findViewById(R.id.Button_Six).setOnClickListener(this);
findViewById(R.id.Button_Seven).setOnClickListener(this);
findViewById(R.id.Button_Eight).setOnClickListener(this);
findViewById(R.id.Button_Nine).setOnClickListener(this);
findViewById(R.id.Button_Add).setOnClickListener(this);
findViewById(R.id.Button_Substract).setOnClickListener(this);
findViewById(R.id.Button_Multiply).setOnClickListener(this);
findViewById(R.id.Button_Divide).setOnClickListener(this);
findViewById(R.id.Button_Dot).setOnClickListener(this);
findViewById(R.id.Button_Sum).setOnClickListener(this);
findViewById(R.id.Button_Clear).setOnClickListener(this);
findViewById(R.id.Button_MemoryRecall).setOnClickListener(this);
findViewById(R.id.Button_MemoryAdd).setOnClickListener(this);
findViewById(R.id.Button_MemoryClear).setOnClickListener(this);

// The following buttons only exist in layout-land (Landscape mode) and require extra attention.
// The messier option is to place the buttons in the regular layout too and set android:visibility="invisible".
if (findViewById(R.id.Button_SquareRoot) != null) {
findViewById(R.id.Button_SquareRoot).setOnClickListener(this);
}
if (findViewById(R.id.Button_Squared) != null) {
findViewById(R.id.Button_Squared).setOnClickListener(this);
}
if (findViewById(R.id.Button_Invert) != null) {
findViewById(R.id.Button_Invert).setOnClickListener(this);
}
if (findViewById(R.id.Button_Sin) != null) {
findViewById(R.id.Button_Sin).setOnClickListener(this);
}
if (findViewById(R.id.Button_Cos) != null) {
findViewById(R.id.Button_Cos).setOnClickListener(this);
}
if (findViewById(R.id.Button_Tan) != null) {
findViewById(R.id.Button_Tan).setOnClickListener(this);
}
if(findViewById(R.id.Button_Toggle) != null){
findViewById(R.id.Button_Toggle).setOnClickListener(this);
}

}

@Override
public void onClick(View v) {

String buttonPressed = ((Button) v).getText().toString();

if (DIGITS.contains(buttonPressed)) {

// digit was pressed
if (userIsInTheMiddleOfTypingANumber) {

if (buttonPressed.equals(".") && mCalculatorDisplay.getText().toString().contains(".")) {
// ERROR PREVENTION
// Eliminate entering multiple decimals
} else {
mCalculatorDisplay.append(buttonPressed);
}

} else {

if (buttonPressed.equals(".")) {
// ERROR PREVENTION
// This will avoid error if only the decimal is hit before an operator, by placing a leading zero
// before the decimal
mCalculatorDisplay.setText(0 + buttonPressed);
} else {
mCalculatorDisplay.setText(buttonPressed);
}

userIsInTheMiddleOfTypingANumber = true;
}

} else {
// operation was pressed
if (BuildConfig.DEBUG) { Log.d(TAG, "operation pressed");}
if (userIsInTheMiddleOfTypingANumber) {

mCalculatorBrain.setOperand(Double.parseDouble(mCalculatorDisplay.getText().toString()));
userIsInTheMiddleOfTypingANumber = false;
}

mCalculatorBrain.performOperation(buttonPressed);
mCalculatorDisplay.setText(df.format(mCalculatorBrain.getResult()));

}

}

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
// Save variables on screen orientation change
outState.putDouble("OPERAND", mCalculatorBrain.getResult());
outState.putDouble("MEMORY", mCalculatorBrain.getMemory());
if (BuildConfig.DEBUG) { Log.d(TAG, "onSaveInstanceState called");}
}

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
// Restore variables on screen orientation change
mCalculatorBrain.setOperand(savedInstanceState.getDouble("OPERAND"));
mCalculatorBrain.setMemory(savedInstanceState.getDouble("MEMORY"));
mCalculatorDisplay.setText(df.format(mCalculatorBrain.getResult()));
if (BuildConfig.DEBUG) { Log.d(TAG, "onRestoreInstanceState called");}
}



}


And here is my calculatorbrain:

public class CalculatorBrain {
// 3 + 6 = 9
// 3 & 6 are called the operand.
// The + is called the operator.
private static String TAG = "CalculatorBrain";
// 9 is the result of the operation.
private double mOperand;
private double mWaitingOperand;
private String mWaitingOperator;
private double mCalculatorMemory;

// operator types
public static final String ADD = "+";
public static final String SUBTRACT = "-";
public static final String MULTIPLY = "x";
public static final String DIVIDE = "÷";
public static final String CLEAR = "DEL" ;
public static final String CLEARMEMORY = "MC";
public static final String ADDTOMEMORY = "M+";
public static final String RECALLMEMORY = "MR";
public static final String SQUAREROOT = "√";
public static final String SQUARED = "x²";
public static final String INVERT = "1/x";
public static final String TOGGLESIGN = "+/-";
public static final String SINE = "sin";
public static final String COSINE = "cos";
public static final String TANGENT = "tan";

// public static final String EQUALS = "=";

// constructor
public CalculatorBrain() {
// initialize variables upon start
mOperand = 0;
mWaitingOperand = 0;
mWaitingOperator = "";
mCalculatorMemory = 0;
}

public void setOperand(double operand) {
if(BuildConfig.DEBUG){Log.d(TAG, "setoperand value" + Double.toString(operand));}
mOperand = operand;
if (BuildConfig.DEBUG) { Log.d(TAG, "setOperand called");}
}

public double getResult() {
if (BuildConfig.DEBUG) { Log.d(TAG, "getResult called");}
return mOperand;

}

// used on screen orientation change
public void setMemory(double calculatorMemory) {
if (BuildConfig.DEBUG) { Log.d(TAG, "setMemory called");}
mCalculatorMemory = calculatorMemory;
}

// used on screen orientation change
public double getMemory() {
if (BuildConfig.DEBUG) { Log.d(TAG, "getMemory called");}return mCalculatorMemory;
}


public String toString() {
return Double.toString(mOperand);
}

protected double performOperation(String operator) {

switch (operator) {
case CLEAR:
mOperand = 0;
mWaitingOperator = "";
mWaitingOperand = 0;
break;
case CLEARMEMORY:
mCalculatorMemory = 0;
break;
case ADDTOMEMORY:
mCalculatorMemory = mCalculatorMemory + mOperand;
break;
case RECALLMEMORY:
`enter code here` mOperand = mCalculatorMemory;
break;
case SQUAREROOT:
mOperand = Math.sqrt(mOperand);
break;
case SQUARED:
mOperand = mOperand * mOperand;
break;
case INVERT:
if (mOperand != 0) {
mOperand = 1 / mOperand;
} else {
mOperand = 0;
}
break;
case TOGGLESIGN:
mOperand = -mOperand;
break;
case SINE:
mOperand = Math.sin(Math.toRadians(mOperand));
break;
case COSINE:
mOperand = Math.cos(Math.toRadians(mOperand));
break;
case TANGENT:
mOperand = Math.tan(Math.toRadians(mOperand));
break;
default:
performWaitingOperation();
mWaitingOperand = mOperand;
mWaitingOperator = operator;
break;

}
return mOperand;
}

protected void performWaitingOperation() {
if (BuildConfig.DEBUG) { Log.d(TAG, "performWaitingOperation called");}
switch (mWaitingOperator){
case ADD:
mOperand = mWaitingOperand + mOperand;
break;
case MULTIPLY:
mOperand = mWaitingOperand * mOperand;
break;
case SUBTRACT:
mOperand = mWaitingOperand - mOperand;
break;
case DIVIDE:
mOperand = mWaitingOperand / mOperand;
break;
}
}
}


Thanks in advance!
Egert

Answer

This is happening because it restarts when your activity changes its orientation. Add this in your manifest file

android:configChanges="orientation|screenSize|keyboardHidden"

This will prevent it from restarting.

Comments