I have a weird bug which I'm not sure why it's happening,
I have 2 activities: activity A and activity B.
When the app starts, it initializes a spinner once. I go to the second activity and then go back <-
onRestart() of the Activity A will be called. My problem is that even though I clear my spinner and reinitialize it in onRestart() it keeps reading the values.
For example, if spinner has 1/2 when you go to activity B then back to activity A, spinner has = 1/2/1/2.
I find this weird because when I just set the spinner adapter to null and comment out my initialize of spinner when I go back to activity A from activity B, my spinner is empty.
here is my code:
#Override public void onRestart() {
super.onRestart();
Spinner location = findViewById(R.id.spinnerLocation);
location.setAdapter(null);
initSpinner();// if this is commented out spinner is cleared, if not commented the same valus are added again
}
here is code for initSpinner(reads from shared prefs) this is not the problem
public void initSpinner(){
Spinner location = findViewById(R.id.spinnerLocation);
location.setAdapter(null);
SharedPreferences prefs = this.getSharedPreferences("Locations", Context.MODE_PRIVATE); //preffilename
SharedPreferences.Editor editor = prefs.edit();
editor.putString("1","St. Catharines");
editor.putString("2","Toronto");
editor.putString("3","Niagara Falls");
editor.commit();
int s = prefs.getAll().size();
for(int f=0;f<25;f++) {
if (prefs.getString(String.valueOf(f + 1), null) != null) {
DefaultLocations.add(prefs.getString(String.valueOf(f + 1), null));
}
}
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_dropdown_item, DefaultLocations);
//set the spinners adapter to the previously created one.
location.setAdapter(adapter);
}
do
DefaultLocations.clear() before for loop inside initSpinner() method it may not clear when u adding new values
Related
I am overriding onResume method to load previos state of my activity where it was ie spinner's last selected item etc. However the same code works fine for some activities but for some it causes crash as when i remove this onResume from them, Activity doesnt crash.
Here's the code
#Override
protected void onResume() {
super.onResume();
sp1 = (Spinner)findViewById(R.id.spinner);
sp2=(Spinner)findViewById(R.id.spinner1);
sp3=(Spinner)findViewById(R.id.spinner2);
sp4=(Spinner)findViewById(R.id.spinner3);
sp5=(Spinner)findViewById(R.id.spinner4);
TextView tx=(TextView)findViewById(R.id.upgradeResult) ;
SharedPreferences prefs = getSharedPreferences("restore_defensiveBuildings_state", Context.MODE_PRIVATE);
int spinner1Indx = prefs.getInt("spinner1_indx", 0);
int spinner2Indx = prefs.getInt("spinner2_indx", 0);
int spinner3Indx = prefs.getInt("spinner3_indx", 0);
int spinner4Indx = prefs.getInt("spinner4_indx", 0);
int spinner5Indx = prefs.getInt("spinner5_indx", 0);
sp1.setSelection(spinner1Indx);
sp2.setSelection(spinner2Indx);
sp3.setSelection(spinner3Indx);
sp4.setSelection(spinner4Indx);
sp5.setSelection(spinner5Indx);
tx.setText(""+totalAirBombUpgradeCost);
}
This is how i loaded items to the adapter
Spinner sp1;
Spinner sp2;
Spinner sp3;
Spinner sp4;
Spinner sp5;
TextView tx;
Button sbmt;
String levels[]={"Level 1",
"Level 2",
"Level 3",
"Level 4"
};
int[] images={R.drawable.giant_bomb_1and2,
R.drawable.giant_bomb_1and2 ,
R.drawable.giant_bomb_3and4,
R.drawable.giant_bomb_3and4
};
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_giant_bomb);
//// initialize all your visual fields
// if (savedInstanceState != null) {
// sp1.setSelection(savedInstanceState.getInt("MySpinner1", 0));
// // do this for each of your text views
// }
sbmt=(Button)findViewById(R.id.submit);
tx=(TextView)findViewById(R.id.upgradeResult);
sp1=(Spinner)findViewById(spinner);
sp2=(Spinner)findViewById(R.id.spinner1);
sp3=(Spinner)findViewById(R.id.spinner2);
sp4=(Spinner)findViewById(R.id.spinner3);
sp5=(Spinner)findViewById(R.id.spinner4);
SpinnerAdapterGiant adapter=new SpinnerAdapterGiant(this,levels,images);
sp1.setAdapter(adapter);
sp2.setAdapter(adapter);
sp3.setAdapter(adapter);
sp4.setAdapter(adapter);
sp5.setAdapter(adapter);
And this is the error
java.lang.ArrayIndexOutOfBoundsException: length=4; index=4
EDIT: When i remove onResume(), everything works fine app doesn't crash, just that it doesn't load activity's previous state.
Because in array you put only 4 value and there 5 spinner so in 5th spinner error occur.
Your are trying to access the 5th element in an array of size 4. Your levels and images array have only for element but you have 5 spinners
Increase your array size to 5.
the question is quite obvious but still nothing worked for me. In my application i'm selecting value from spinner and wanna to let spinner to show selected value after restarting application. to store spinner value i'm using shared preferences But when restarts application logcat shows null pointer error. Here's code
String options[]={"-Select-", "Domino's","Pizza Hut", "Pizza Bite"};
Spinner spin;
int formatposition;
fSpinner = (Spinner)findViewById(R.id.fSpinner);
ArrayAdapter<String> adp = new ArrayAdapter<String> (MainActivity.this,android.R.layout.simple_spinner_dropdown_item,options);
fSpinner.setAdapter(adp);
To store spinner selected value:
Editor editee = preferences.edit();
editee.putInt("lastindex", spin.getSelectedItemPosition());
editee.commit();
To restore shared preferences when application restarts
protected void onCreate(Bundle savedInstanceState) //onCreate is called when the activity is starting
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
context=this;
listViewSMS=(ListView)findViewById(R.id.lvSMS); //view that shows items in a vertically scrolling list
btnaddnew = (Button)findViewById(R.id.btnaddnew);
btnaddnew.setOnClickListener(this);
formatposition = preferences.getInt("lastindex", 0);
spin.setSelection(formatposition);
}
How could array find index without name of array??
Try this one to solve:-
spinposition = preferences.getInt("lastindex", 0);
spin.setSelection(spinposition);
Here is my scenario:
I have a MainActivity and a CustomListViewActivity. In my MainActivity, I have 1 button and 1 spinner. On click of the button, I pass the selected spinner value to the CustomListViewActivity via Bundle and using Intents.
Now, in my CustomListViewActivity, I have a ListView that uses ArrayAdapter for populating it. I send a ArrayList from MainActivity, say for example
items = [abc]
In my CustomListViewActivity, I receive the same and use it to populate my ListView. The first time I do this, my value gets populated. The second time I do the same, the value existing is now replaced with the new one and the ListView shows one item instead of showing two.
So basically the problem is that the ListView is not updating and not showing both the items. Instead it shows me a single item always.
Here are snippets of my code
MainActivity.java
//code inside button click
..
{
items.add(spinner1.getSelectedItem().toString());
Bundle bundle =new Bundle();
bundle.putStringArrayList("data",items);
Intent i = new Intent(MainActivity.this,MyListViewActivity.class);
i.putExtras(bundle);
startActivity(i);
finish();
}
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
Log.i("App","onSave");
icicle.putStringArrayList("data",items);
}
#Override
protected void onRestoreInstanceState(Bundle icicle2) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(icicle2);
Log.i("App","onRestore");
icicle2.putStringArrayList("data",items);
}
MyListViewActivity.java
private ArrayList<String> myItems;
private static String[] titles;
CustomListViewAdapter adapter;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.list_main);
listView = (ListView) findViewById(R.id.list1);
rowItems = new ArrayList<RowItem>();
adapter = new CustomListViewAdapter(this,R.layout.list_item, rowItems);
listView.setAdapter(adapter);
b=getIntent().getExtras();
if(b!=null)
{
myItems=b.getStringArrayList("data");
titles= new String[myItems.size()];
titles = myItems.toArray(myItems);
}
...
int i=0;
while(i<titles.length) {
item = new RowItem(titles[i]);
//rowItems.add(item);
Log.i("ROW", ""+rowItems.size());
i++;
adapter.add(item);
listView.setAdapter(adapter);
}
adapter.setNotifyOnChange(true);
adapter.notifyDataSetChanged();
}
}
How to make the ListView maintain the current data as well reflect the added data?
Thanks in advance
EDIT : Forgot to mention one more thing. In my MyListViewActivity class I have a button above the ListView that on clicked takes me to my MainActivity so that I can add a new Item again. So when I go back to MainActivity and try and add a new Item , it's the new Item that get displayed rather than showing both the previous and the new one
You need to persist and restore your items list in MainActivity's onSaveInstanceState and onRestoreInstanceState methods.
You also probably don't need to close the MainActivity by calling finish() every time you start the ListView activity but that depends on your application.
Basically, the problem you are having is that items is being recreated with each new instance of MainActivity. Since you finish MainActivity, a new instance is used every time you access that activity (and I assume you thought that items would just keep getting items added to it).
I'm trying to implement a listview and what I want exactly is:
The app launches, 1 item from ListView is being chosen and starts a webview. This step is done
But what I want is that 2. time when I launch the app, it will start from that item and not show the list again. So it will continue always to start on that item I pressed first time.
I hope someone can show me a tutorial I can follow or some keyword I will try to see if I can do it.
*UPDATE --> Code
public class AndroidListViewActivity extends ListActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String[] adobe_products = getResources().getStringArray(R.array.adobe_products);
this.setListAdapter(new ArrayAdapter<String>(this, R.layout.list_item, R.id.label, adobe_products));
ListView lv = getListView();
SharedPreferences prefs = getSharedPreferences("PREFERENCE", MODE_PRIVATE);
boolean firstrun = prefs.getBoolean("firstrun", true);
if (firstrun) {
SharedPreferences.Editor editor = prefs.edit();
editor.putBoolean("firstrun", false);
editor.apply();
// listening to single list item on click
lv.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
Intent i = new Intent(getApplicationContext(), EnkeltView.class);
// sending data to new activity
i.putExtra("url", "https://google.dk");
startActivity(i);
}
});
}
// Save the state
getSharedPreferences("PREFERENCE", MODE_PRIVATE)
.edit()
.putBoolean("firstrun", false)
.commit();
}
}
Use SharedPreference works like a DB but in a small scale:SharedPreference
Android documentation: This data will persist across user sessions (even if your application is killed).
So SharedPreferences shouldn't be getting wiped when a device reboots or force closes.
you can store item in shared preferences in 1st time and during second time you can check if your shared Preference is not null then It launch the application with item stored in it.
Hi I am trying to save some values in my activity but I'm having a problem when I save it with onSaveInstanceState and restore with onRestoreInstanceState, I am saving an int years and it saves the first time the screen changes orientation, the spinner repopulates and sets it at the last value , but not when I switch back the orientation again.
My orientation is set to landscape in my manifest, and I have the two save and restore method overridden but it doesn't seem to work, do I need to do something in onPause aswell?
here is my code:
int years;//global variable
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Spinner spinnerYears = (Spinner) findViewById(R.id.spinYears);//Spinner
final ArrayAdapter <Integer> adapter = new ArrayAdapter <Integer>(this,android.R.layout.simple_spinner_item );
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
for(int i=0;i<=100;i++)
{
adapter.add(i);
}
spinnerYears.setAdapter(adapter);
years = spinnerYears.getSelectedItemPosition();
}//onCreate
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
super.onSaveInstanceState(savedInstanceState);
savedInstanceState.putInt("MyInt", years);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Spinner spinnerYears = (Spinner) findViewById(R.id.spinYears);//Spinner
final ArrayAdapter <Integer> adapter = new ArrayAdapter <Integer> (this, android.R.layout.simple_spinner_item );
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
for(int i=0;i<=100;i++)
{
adapter.add(i);
}
spinnerYears.setAdapter(adapter);
TextView tvYears = (TextView) findViewById(R.id.tvYears);//spinner Tv
tvYears.setVisibility(TextView.GONE);
int myInt = savedInstanceState.getInt("MyInt");
spinnerYears.setSelection(myInt);//
Toast.makeText(getBaseContext(), "Restored int"+myInt, Toast.LENGTH_LONG).show();
}
Because you don't handle the event of changing orientation, so everytime you change orientation, your program (or Activity) is re-created, which means the onCreate() method is called always; which leads to a result that onSaveInstanceState() and onRestoreInstanceState() never being called.
It's being explained here in Android Documentation: http://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges
In order to fix this, in AndroidManifest.xml , adding this attribute:
android:configChanges="orientation"
to avoid Activity restarted and, well, good luck with that!
In onRestoreInstanceState(), you never assign the value back the the variable years. You assign it to an int and then disregard it. So when onSaveInstanceState() is called, years hasn't been set yet and it saves that unset value (0).
If you change your getInt() line towards the bottom to be:
years = savedInstanceState.getInt("MyInt");
spinnerYears.setSelection(years);
it should start working. Good Luck!