onSaveInstanceState not working as expected - android

I have a button that goes from one activity to another activity and its supposed to save the value int Counter, but every time it never saves. What am I doing wrong? I have seen other solutions, but i check and im doing the exact same thing as them.
package com.example.navjeevenmann.mytycoon;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button myButton;
private int Counter;
private Button myButton2;
private TextView myTextView;
Handler handler = new Handler();
private int add;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
add = savedInstanceState.getInt("Count");
Counter = savedInstanceState.getInt("Add");
}
myButton = (Button) findViewById(R.id.button);
myButton2 = (Button) findViewById(R.id.button2);
myTextView = (TextView) findViewById(R.id.textView);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Counter = ButtonCounter(Counter);
}
});
myButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(), SecondActivity.class);
intent.putExtra("Count", Counter);
startActivity(intent);
}
});
handler.postDelayed(new Runnable() {
#Override
public void run() {
Counter = AutoCounter(Counter, add);
Display(Counter, myTextView);
handler.postDelayed(this, 100);
}
}, 10);
}
protected void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("Count", Counter);
savedInstanceState.putInt("Add", add);
}
public int ButtonCounter(int Counter) {
Counter += 1;
return Counter;
}
public int AutoCounter(int Counter, int add) {
Counter += add;
return Counter;
}
public void Display(int Counter, TextView myTextView) {
String man = String.valueOf(Counter);
myTextView.setText("$" + man);
}
}

you're not implementing the right method
from the docs:
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("Count", Counter);
savedInstanceState.putInt("Add", add);
// call superclass to save any view hierarchy
super.onSaveInstanceState(outState);
}
Source: https://developer.android.com/guide/components/activities/activity-lifecycle.html#oncreate

Related

java.lang.ClassCastException: com.example.harshitbahri.expensebook.MainActivity cannot be cast to com.example.harshitbahri.expensebook.EditorActivity

I want to change the TextView of editor activity by clicking on Button buttonExpense which should also open editor activity and show value of the result in
EditText mAmountEditText.
I am getting java.lang.ClassCastException in which it is clearly written that MainActivity cannot be cast to EditorActivity
Calculator.java
package com.example.harshitbahri.expensebook;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class Calculator extends android.support.v4.app.Fragment {
Button button0;
Button button1;
Button button2;
Button button3;
Button button4;
Button button5;
Button button6;
Button button7;
Button button8;
Button button9;
Button buttonAdd;
Button buttonSubstract;
Button buttonMul;
Button buttonDiv;
Button buttonClear;
Button buttonEqual;
Button buttonExpense;
String result;
String tmp;
String operator;
TextView resultTextView;
FragmentActivity fa2;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
fa2 = (FragmentActivity) super.getActivity();
final View RootView= inflater.inflate(R.layout.activity_calculator, container, false);
button0 = (Button)RootView.findViewById(R.id.button0);
button1 = (Button)RootView.findViewById(R.id.button1);
......
buttonAdd = (Button)RootView.findViewById(R.id.buttonAdd);
buttonClear = (Button)RootView.findViewById(R.id.buttonClear);
buttonSubstract = (Button)RootView.findViewById(R.id.buttonSub);
buttonMul = (Button)RootView.findViewById(R.id.buttonMul);
buttonDiv = (Button)RootView.findViewById(R.id.buttonDiv);
buttonEqual = (Button)RootView.findViewById(R.id.buttonEqual);
buttonExpense= (Button)RootView.findViewById(R.id.buttonExp);
resultTextView = (TextView)RootView.findViewById(R.id.text_view_result);
button0.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onNumberButtonClicked("0");
}
});
button1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onNumberButtonClicked("1");
}
});
button2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onNumberButtonClicked("2");
}
});
button3.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onNumberButtonClicked("3");
}
});
button4.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onNumberButtonClicked("4");
}
});
button5.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onNumberButtonClicked("5");
}
});
button6.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onNumberButtonClicked("6");
}
});
button7.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onNumberButtonClicked("7");
}
});
button8.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onNumberButtonClicked("8");
}
});
button9.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onNumberButtonClicked("9");
}
});
buttonClear.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onClearButtonClicked();
}
});
buttonSubstract.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v){
onOperatorButtonClicked("-");
}
});
buttonAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onOperatorButtonClicked("+");
}
});
buttonMul.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onOperatorButtonClicked("X");
}
});
buttonDiv.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onOperatorButtonClicked("/");
}
});
buttonEqual.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
onEqualButtonClicked();
}
});
buttonExpense.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(fa2, EditorActivity.class);
startActivity(intent);
((EditorActivity) getActivity()).updateGoldTextView(result);
/*Intent intent = new Intent(fa2, EditorActivity.class);
intent.putExtra(, result);
final int result2=1;
startActivityForResult(intent, result2);*/
}
});
return RootView;
}
private void onEqualButtonClicked() {
int res = 0;
try {
int number = Integer.valueOf(tmp);
int number2 = Integer.valueOf(resultTextView.getText().toString());
switch (operator) {
case "+":
res = number + number2;
break;
case "/":
res = number / number2;
break;
case "-":
res = number - number2;
break;
case "X":
res = number * number2;
break;
}
result = String.valueOf(res);
resultTextView.setText(result);
}
catch (Exception e) {
e.printStackTrace();
}
}
public void onOperatorButtonClicked(String operator) {
..
}
public void onClearButtonClicked() {
...
}
public void onNumberButtonClicked(String pos) {
..
}
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
void onFragmentInteraction(Uri uri);
}
}`
EditorActivity.java
package com.example.harshitbahri.expensebook;
import android.app.AlertDialog;
import android.app.LoaderManager;
...
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
public class EditorActivity extends AppCompatActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
private static final int EXISTING_EXPENSE_LOADER = 0;
private Uri mCurrentExpenseUri;
private EditText mAmountEditText;
private EditText mDescEditText;
private Spinner mCategorySpinner;
private String mCategory = ExpenseEntry.CATEGORY_GENERAL;
private View.OnTouchListener mTouchListener = new View.OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
mExpenseHasChanged = true;
return false;
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_editor);
// Examine the intent that was used to launch this activity,
// in order to figure out if we're creating a new pet or editing an existing one.
Intent intent = getIntent();
mCurrentExpenseUri = intent.getData();
// If the intent DOES NOT contain a pet content URI, then we know that we are
// creating a new pet.
if (mCurrentExpenseUri == null) {
// This is a new pet, so change the app bar to say "Add a Pet"
setTitle("Add Expense");
yet.)
invalidateOptionsMenu();
} else {
// Otherwise this is an existing pet, so change app bar to say "Edit Pet"
setTitle("Edit Expense");
getLoaderManager().initLoader(EXISTING_EXPENSE_LOADER, null, this);
}
mAmountEditText = (EditText) findViewById(R.id.exp_amount);
mDescEditText = (EditText) findViewById(R.id.description);
mCategorySpinner = (Spinner) findViewById(R.id.spinner_category);
.....
}
......
finish();
}
public void updateGoldTextView(String goldAmount) {
mAmountEditText.setText(goldAmount);
}
}
MainActivity.java
package com.example.harshitbahri.expensebook;
import android.net.Uri;
import android.support.design.widget.TabLayout;
import android.support.v4.app.FragmentPagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity implements
Calculator.OnFragmentInteractionListener ,
Entries.OnFragmentInteractionListener,Info.OnFragmentInteractionListener{
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TabLayout tabLayout = (TabLayout)findViewById(R.id.tablayout);
tabLayout.addTab(tabLayout.newTab().setText("Tab 1"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 2"));
tabLayout.addTab(tabLayout.newTab().setText("Tab 3"));
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
final ViewPager viewPager = (ViewPager)findViewById(R.id.pager);
final Pageradapter adapter = new Pageradapter(getSupportFragmentManager(),tabLayout.getTabCount());
viewPager.setAdapter(adapter);
viewPager.setOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
viewPager.setCurrentItem(1, false);
tabLayout.setOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
#Override
public void onTabSelected(TabLayout.Tab tab) {
viewPager.setCurrentItem(tab.getPosition());
}
#Override
public void onTabUnselected(TabLayout.Tab tab) {
}
#Override
public void onTabReselected(TabLayout.Tab tab) {
}
});
}
#Override
public void onFragmentInteraction(Uri uri) {
}
}
Your fragment is loaded from MainActivity and not EditorActivity, hence the class cast exception. If you want to pre-fill some data in the editor activity, you can pass that in the intent ( the code you commented on your onclick listener) and retrieve in the EditorActivity and set your UI elements.
Edited
buttonExpense.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(fa2, EditorActivity.class);
intent.putExtra("result", result);
startActivity(intent);
}});
In your EditorActivity class, in on create
String result=getIntent().getStringExtra("result")
updateGoldTextView(result)

Making a line of code repeat in android every second

This is the line i want to repeat.
handler.postDelayed(runnableCode, 1);
This app is a tycoon app and so the user can buy upgrades and if they tap the button the get $$ and so when they buy upgrades keeping the value up-to-date is required.
package com.example.navjeevenmann.mytycoon;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button myButton;
private int Counter = 0;
private Button myButton2;
private TextView myTextView;
Handler handler = new Handler();
private int Test = 5;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler.postDelayed(runnableCode, 1);
myButton = (Button) findViewById(R.id.button);
myButton2 = (Button) findViewById(R.id.button2);
myTextView = (TextView) findViewById(R.id.textView);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
ButtonCounter(Counter);
}
});
myButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),
SecondActivity.class);
intent.putExtra("Count", Counter);
startActivity(intent);
finish();
}
});
}
public int ButtonCounter(int Counter){
Counter+=1;
return Counter;
}
public int AutoCounter(int Counter, int add) {
Counter+=add;
return Counter;
}
public void Display(int Counter, TextView myTextView) {
String man = String.valueOf(Counter);
myTextView.setText("$" + man);
}
private Runnable runnableCode = new Runnable() {
#Override
public void run() {
// Do something here on the main thread
Counter = AutoCounter(Counter,Test);
Display(Counter, myTextView);
}
};
}
handler.postDelayed(runnableCode, 1);
call that line inside onResume() method. Make sure your show an AlertDialog to the user whenever he or she hits the button to get $$. Since the AlertDialog pops up everytime the user tries to buy $$. onResume() will be called.
Try this
private void startAnimation() {
countDownTimer = new CountDownTimer(700, 500) {
#Override
public void onTick(long millisUntilFinished) {
}
#Override
public void onFinish() {
//your code to repeat
}
start();
}
}.start();
}

Method stops running after switching activities

In this app the users score is supposed to increase every second or so, and they can use that score and buy upgrades from the second Activity. When the user starts the app the program works fine, but when they go from the first activity to the second and back it stops updating the textview with the score that increases every second. Can you guys explain whats going on?
package com.example.navjeevenmann.mytycoon;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button myButton;
private int Counter;
private Button myButton2;
private TextView myTextView;
Handler handler = new Handler();
private int add = 1;
#Override
protected void onCreate(Bundle savedInstanceState) {
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
Bundle bundle = getIntent().getExtras();
if (bundle != null) {
if (bundle.containsKey("Count")) {
Counter = bundle.getInt("Count");
}
if (bundle.containsKey("Add")) {
add = bundle.getInt("Add");
}
}
myButton = (Button) findViewById(R.id.button);
myButton2 = (Button) findViewById(R.id.button2);
myTextView = (TextView) findViewById(R.id.textView);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Counter = ButtonCounter(Counter);
}
});
myButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),
SecondActivity.class);
intent.putExtra("Count", Counter);
startActivity(intent);
}
});
handler.postDelayed(new Runnable() {
#Override
public void run() {
Counter= AutoCounter(Counter, add);
Display(Counter);
handler.postDelayed(this, 1000);
}
},100);
}
public int ButtonCounter(int Counter) {
Counter += 1;
return Counter;
}
public int AutoCounter(int Counter, int add) {
Counter += add;
return Counter;
}
public void Display(int Counter) {
String man = String.valueOf(Counter);
myTextView.setText("$" + man);
}
}
You start the counting handler only inside onCreate() method.
When you go back from SecondActivity to MainActivity the onResume() method is called, So
You need to start the counting inside onResume() method.
P.S Make sure to check for nulls before updating you UI from postDelay().
Your Activity might be destroyed by the time the code runs, make sure your TextView is not null before updating.

onsaveInstancestate not saving int values

When i try rotating the screen it does not erase the data, but when I go from the activity and back the counter value goes back to 0.
I have set make the method for saving the data, but it still doesnt save. Why is this?
package com.example.navjeevenmann.mytycoon;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private Button myButton;
private int Counter = 0;
private Button myButton2;
private TextView myTextView;
Handler handler = new Handler();
private int add = 0;
#Override
protected void onCreate(final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
Counter = savedInstanceState.getInt("Count");
add = savedInstanceState.getInt("Add");
}
setContentView(R.layout.activity_main);
myButton = (Button) findViewById(R.id.button);
myButton2 = (Button) findViewById(R.id.button2);
myTextView = (TextView) findViewById(R.id.textView);
myButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Counter = ButtonCounter(Counter);
}
});
myButton2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(getApplicationContext(),
SecondActivity.class);
intent.putExtra("Count", Counter);
startActivity(intent);
finish();
}
});
handler.postDelayed(new Runnable() {
#Override
public void run() {
Counter = AutoCounter(Counter, add);
Display(Counter, myTextView);
handler.postDelayed(this, 100);
}
}, 10);
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putInt("Count", Counter);
savedInstanceState.putInt("Add", add);
super.onSaveInstanceState(savedInstanceState);
}
public int ButtonCounter(int Counter) {
Counter += 1;
return Counter;
}
public int AutoCounter(int Counter, int add) {
Counter += add;
return Counter;
}
public void Display(int Counter, TextView myTextView) {
String man = String.valueOf(Counter);
myTextView.setText("$" + man);
}
}
My code runs like that...
#Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
outState.putInt("Count", Counter);
}
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null)
{
if (savedInstanceState.containsKey("Count"))
{
Counter = savedInstanceState.getInt("Count");
}
}
}
Difference is that i don't have final Bundle on create and i save it after super.onSave.. wich seems odd....

check what image is set to image view each 500 ms

I am working on this small game where each 500 ms an image is set to the image view
so what i want to check is when i click one of the arrow images(left,right,up,down) to check if it is equal to the random image ...if so then the score increases by 1.
here is my layout
https://i.stack.imgur.com/wPxZB.png
and here is my code
package com.andreh.catchthatarrow;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Timer;
import java.util.TimerTask;
public class GameActivity extends AppCompatActivity {
ImageView img_up;
ImageView img_down;
ImageView img_left;
ImageView img_right,imgRand;
private int time = 600;
private static int SCORE = 0;
private TextView score;
int pos = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
score = (TextView)findViewById(R.id.textView3);
img_up = (ImageView)findViewById(R.id.imgUp);
img_down = (ImageView)findViewById(R.id.imgDown);
img_left = (ImageView)findViewById(R.id.imgLeft);
img_right = (ImageView)findViewById(R.id.imgRight);
imgRand = (ImageView)findViewById(R.id.changeable);
final int [] arrBuckets = {R.drawable.arrow_left,R.drawable.arrow_right,R.drawable.up,R.drawable.down};
Timer mTimer = new Timer();
mTimer.schedule(new TimerTask() {
#Override
public void run() {
runOnUiThread(new Runnable() {
#Override
public void run() {
pos = arrBuckets[(int) (Math.random() * arrBuckets.length)];
imgRand.setImageResource(pos);
if(time>10 || time<20) time=100;
}
});
}
},0,time);
img_up.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(pos==2){
SCORE++;
score.setText(SCORE+"");
}
}
});
img_down.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(pos==3){
SCORE++;
score.setText(SCORE+"");
}
}
});
img_left.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(pos==0){
SCORE++;
score.setText(SCORE+"");
}
}
});
img_right.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(pos==1){
SCORE++;
score.setText(SCORE+"");
}
}
});
}
}
You are checking the data in the index and you need the position so use this instead:
pos = Array.asList(arrayBuckets).indexOf((int) (Math.random() * arrBuckets.length));
img_up.setOnClickListener(new View.OnClickListener() {
#Override public void onClick(View view) {
if(pos==2)
{
SCORE++;
score.setText(SCORE+"");
}
});

Categories

Resources