PreferenceActivity listpreference value resets to default on reload - android

I am facing two problems in my app.
In my app i am using preferenceActivity that contains simple settings for the app (checkboxpreference and listpreference), i have three activities mainActivity,secondActivity and settingsActivity which is prefrenceActivity, in secondActivity i am showing a form that lets user choose a value from a spinner view , what i want to do is user can select a default value of that spinner from settingsActivity so user dont have to manually select the value of spinner everytime.
Now my first problem is: whenever i reopen my settingsActivity(preferenceActivity) the summery of the listPreference is resets to default it only shows selected value while settingsActivity is open, when i go back to mainActivity and i again open the settingsActivity the summery of listPreferece shows default value(if i open list of values,it shows last selected value checked).
Second problem is: Whenever i close the app and open again the preference value gets destroyed means the secondActivity dosent show user selected default value instead it shows the first value of spinner.
here is my code
settingsActivity:
public class settingsActivity extends PreferenceActivity
{
MainActivity mainActivity = new MainActivity();
ListPreference listpref;
#Override
public void onCreate(Bundle savedInstenceState)
{
super.onCreate(savedInstenceState);
addPreferencesFromResource(R.xml.settings);
getActionBar().setDisplayHomeAsUpEnabled(true);
listpref = (ListPreference)findPreference("prefDefaultCurrency");
listpref.setOnPreferenceChangeListener(new OnPreferenceChangeListener()
{
#Override
public boolean onPreferenceChange(Preference preference, Object value) {
// TODO Auto-generated method stub
listpref.setSummary(value.toString());
mainActivity.pref_default_currency_index = listpref.findIndexOfValue(value.toString());
return true;
}
});
CharSequence curenttext = listpref.getEntry();
mainActivity.pref_default_currency_index = listpref.findIndexOfValue(curenttext.toString());
}
pref_default_currency_index is a static int variable declared in mainActivity,
i retrive this variable to set the value of spinner in secondActivity, when user clicks a button to open an alertdialoug that contains spinner.
Please help me, thanks in advance.

I got the solution to both of my problems.. i was making it too difficult when it as very easy!!
My first problem was to get back the option user selected from listPreference from PreferenceActivity, i realized that preferenceActivity automatically saves information to SharedPrererences so what i have to do is just retrieve that information in onCreate() method and save it in a local variable.
SharedPreferences sharedPrefs= PreferenceManager.getDefaultSharedPreferences(this);
pref_default_currency_index = Integer.parseInt(sharedPrefs.getString("prefDefaultCurrency","0"));
Second problem was that whenever i open settings activity (preferenceActivity) the summery of listPreference was not showing last chosen value, to solve that problem i just have to set the summery of listPreference in setOnPreferenceChangeListener() method
listpref = (ListPreference)findPreference("prefDefaultCurrency");
listpref.setOnPreferenceChangeListener(new OnPreferenceChangeListener()
{
#Override
public boolean onPreferenceChange(Preference preference, Object value) {
// TODO Auto-generated method stub
listpref.setSummary(value.toString());
return true;
}
});
thats it, it was easy!

Related

Button listener not working in Preference fragment

I've created a subclass of PreferenceFragment that implements CompoundButton.OnCheckedChangeListener. I have one preference that contains a Switch (a subclass of CompoundButton). Here's the callback I've created for when the value of the switch changes:
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
mAppController.doSomething(isChecked);
Log.v("rose_tag", "hi");
}
I declare the preference in OnCreate as follows:
Switch mySwitch = (Switch) myView.findViewById(R.id.switch);
mySwitch.setEnabled(true);
mySwitch.setOnCheckedChangeListener(this);
The callback gets called when the view first opens (a breakpoint in the callback is hit), but no log prints, and the callback never gets called again, even when I switch the switch on and off. How can I make this callback work?
I also tried creating an inline anonymous listener. I also tried using a simple Button with an onClick listener, and that didn't work either.
I can see you are trying to use PreferenceFragment as any other normal fragment. However, you must to take in count the correct mechanism, one example is you cannot use all the widgets for making a preferences view for the user, you must use the Preference objects (see Preference subclasses).
Another example is that you must use addPreferencesFromResource(int) to inflate preferences from an XML resource.
Check both links above and this example.
I hope It helps you.
If you use the anwser from Jorge Gil, you will not be able to easily get a reference to the view you are declaring in the PreferenceScreen.
However you can easily get one of the preference Object which in that case is a SwitchPreference. So in your res/xml/preferences.xml add your switch preference:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:key="screen">
<SwitchPreference
android:key="switch_preference"
android:title="title"
android:summary="summary" />
</PreferenceScreen>
Then in your PreferenceFragment/PreferenceActivity's onCreate function add this:
addPreferencesFromResource(R.xml.preferences);
SwitchPreference switchPref = (SwitchPreference) findPreference("switch_preference");
switchPref.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Log.e(getClass().getSimpleName(),"onPreferenceChange:" + newValue);
return true;
}
});

Show a Toast when user change setting in preferences activity

I have a preferences Activity with a ListPreference on it and I use this preferences in another activity,
But I want to show a Toast whenever, user changing option in preference Activity.
For example, when user clicks on second radio button in ListPreference, suddenly a toast shown and says "second".
What is the problem?
Resolve the preference and set a listener that does the toast?
Something like this for example
ListPreference listPreference = findPreference(key);
listPreference.setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
Toast.makeText(SettingsActivity.this, "second", Toast.LENGTH_LONG).show();
return true;
}
});

How to call another intent without losing previous data?

I have 2 pages in my application. From Page A I am calling Page B. On page B I have a ListView which is filled by users. Now when User clicks on Back Button of the phone he comes back to Page A. But when he clicks menu and select Add Items again, it opens Page B but my ListView is empty. How can I get back to Page B without losing data in ListView?
Override the onBackPressed in page B, and save your data some where..
then in the onStart of page B reload the data..
One way to accomplish this is to use the SharedPreferences:
public void onStop(Bundle bundle)
{
SharedPreferences mySharedPreferences = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor editor = mySharedPreferences.edit();
editor.putBoolean("myBool",true);
//Continue saving all the data you need to recreate the listView
}
Then when you restart the activity, you can reload the preferences in the OnCreate() method like this:
public void onCreate(Bundle bundle)
{
SharedPreferences mySharedPreferences = getPreferences(MODE_PRIVATE);
// Retrieve the saved values.
boolean myBool = mySharedPreferences.getBoolean("myBool");
//Recreate the ListView here
}
It might not be the cleanest way to do so. But since onSavedInstanceState can't be used in your case, it will have to do :)
You can use SharedPreferences to save and load the data in a list
I.e
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
SharedPreferences settingsActivity = getPreferences(MODE_PRIVATE);
SharedPreferences.Editor prefEditor = settingsActivity.edit();
prefEditor.putString(LISTFROMB, savedItems);
prefEditor.commit();
}
return super.onKeyDown(keyCode, event);
}
And then load it in A like :
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.simple);
// Find the ListView resource.
mainListView = (ListView) findViewById(R.id.list);
ArrayList<String> selectedItems = new ArrayList<String>();
SharedPreferences settingsActivity = getPreferences(MODE_PRIVATE);
String savedItems = settingsActivity.getString(LISTFROMB, "");
selectedItems.addAll(Arrays.asList(savedItems.split(",")));
[CALL YOUR ADAPTER HERE WITH THE SELECTED ITEMS LIST]
}
Thanks for your help. I solved the problem just by declaring the ArrayList in Page A. So now when I go back to Page B the source of the ListView is in Page A so easy to load it back.
Don't know if this approach is wrong. Please leave your comment if you think this shouldn't be done.

Android how to save the tab state when switching between tabs

I have TabActivity which holds 4 tabs.
the tabs created in the tabhost activity like this
TabSpec firstTabSpec = tabHost.newTabSpec("tid1");
Intent send_names_intent1 = new Intent(this,tab1.class);
//here is some data I receive it from previous activity
//and want to send them to the tab
send_names_intent1.putExtra("names", names);
send_names_intent1.putExtra("check", test1);
firstTabSpec.setIndicator("Kingdom I").setContent(send_names_intent1);
tabHost.addTab(firstTabSpec);
in every tab the user do some work and the result will displayed in the tab,
the problem is that when switching to the 2nd tab and then go back to the 1st tab all the results will gone and the tab will be created again.
NOTICE : I tried to use the getsharedprefrences() but it will loads the saved data even if the application closed and opens again.
You can use a boolean value boolean test; and int value int last=0 then use this method
tabHost.setOnTabChangedListener(new OnTabChangeListener(){
#Override
public void onTabChanged(String tabId) {
int currenttab = tabHost.getCurrentTab();
if (currenttab != last){
test[last] = false;
send_names_intent [last].putExtra("check", test[last]);
last = currenttab;
}
}
});
when you use this method you will have a boolean value in your tab1.class
Intent names_intent = getIntent();
prefcheck = names_intent.getBooleanExtra("check", false);
then check the prefcheck value if (prefcheck == false) save the SharedPreferences.
Have you tried onSaveInstanceState?
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(outState);
icicle.putString("names", names);
}
You say you used shared preferences right? Why not have it so that when a tab is opened, it increments a value of a shared preference by one, and om destroy decrements it, and then checks to see if the value is 0, if so it deletes all the save preferences you want by setting them to the default value, or the value you want.

PreferenceScreen android:summary update !

In my android application I have a PreferenceScreen parent that has 3 CheckBoxPreferences as children.
When I click the parent preferenceScreen, and the 3 checkboxes are displayed, I select one of them, and in the Preference.OnPreferenceChangeListener asociated with the checkboxes I set the parent's preferenceScreen summary with:
Parent.setSummary("string depending on the selection")
The thing is that when I return to the parent, it's summary is not updated, even if internally the value has correspondingly changed to the value setted.
Has anyone any idea regarding this behavior?
Use
Parent.setSummary("string depending on the selection");
((BaseAdapter)getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
works like a charm and can be used regardless the place you change the summary.
This is the correct way
Preference pref = findPreference(getString(R.string.key_of_pref));
PreferenceScreen parent = (PreferenceScreen) sf.findPreference(getString(R.string.key_of_preference_screen));
pref.setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
#Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
boolean newValueBool = (Boolean) newValue;
parent.setSummary(newValueBool ? "Summary is true" : "Summary is false");
((BaseAdapter) getPreferenceScreen().getRootAdapter()).notifyDataSetChanged();
// true to update the state of the Preference with the new value
// in case you want to disallow the change return false
return true;
}
});
I discovered that it seems to work by following up setSummary() with getListView().invalidate()
You can use BaseAdapter.notifyDataSetChanged() on the parent PreferenceScreen to update the UI. See here for example code: Update existing Preference-item in a PreferenceActivity upon returning from a (sub)PreferenceScreen
If you're using support preference than go for:
findPreference("your_preference").setOnPreferenceChangeListener(new Preference.OnPreferenceChangeListener() {
public boolean onPreferenceChange(Preference preference, Object o) {
getListView().getAdapter().notifyDataSetChanged();
return true;
}
});
The new insistence on fragments instead of activities seems to make this harder. The invalidate route didn't seem to work nor approaches using the underlying View. Thanks to halxinate's answer I have now managed to work this through. For people who are as new as I am to all this here are a few more details:
When creating the settings fragment, save a reference in your main activity, e.g.:
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
switch (item.getItemId()) {
case R.id.action_preferences:
if (getFragmentManager().getBackStackEntryCount() < 1) {
FragmentTransaction trans = getFragmentManager()
.beginTransaction();
// Save a reference to the settings fragment
settingsFrag = new SettingsFragment();
trans.replace(R.id.container, settingsFrag);
trans.addToBackStack(null);
trans.commit();
}
return true;
default:
return super.onOptionsItemSelected(item);
}
}
Then when you want to update the summaries of the outer PreferenceScreen from the OnSharedPreferenceChangeListener use this sort of thing. Note that you need to have defined a key in your preference fragment xml for the outer PreferenceScreen (in this case android:key="prefs_root"):
public static void setOuterSummaries(SettingsFragment sf) {
// Set the outer preferences summaries
if (sf == null)
return;
//Code to update the summaries....
// Force the parent screen summaries to update
prefScr = (PreferenceScreen) sf.findPreference("prefs_root");
if (prefScr != null)
((BaseAdapter) prefScr.getRootAdapter()).notifyDataSetChanged();
}
OnSharedPreferenceChangeListener listener = new SharedPreferences.OnSharedPreferenceChangeListener() {
public void onSharedPreferenceChanged(SharedPreferences prefs,
String key) {
Log.e("L", "Change");
setOuterSummaries(settingsFrag);
}
};
Note that you could save a reference to the BaseAdapter instead of to the settings fragment but this approach seems safer when you think of generalizing it to a multi-fragment situation or code which dynamically creates the fragment content.

Categories

Resources