How to update summary of preference from sub-preference - android

I can't solve this problem. I have preference screen and there is sub-preference that opens up another screen. On that another screen change of items can be caught with OnSharedPreferenceChangeListener and I change summary in parent preference screen, but when I go back to that parent preference screen, summary did not changed.
Same question was asked here, but conclusion was not clear, and I could not solve this problem. It seems a common problem to me and I guess there is good solution for this.
Dose anyone know a solution for this problem?
There is one thing I like to keep: sub-preference is standard one, not custom.

I've solved this by adding OnPreferenceClickListener to the preferences which will change the summary in the main screen.
OnPreferenceClickListener viewUpdater = new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference preference) {
updateView();
return false;
}
};
Within the updateView() method I'm setting the summary to a new value and then I'm using the invalidateViews method of the preferences listview to trigger an update of the displayed summary
private void updateView() {
preference.setSummary(newSummary);
getListView().invalidateViews();
}

Check the answer of #jmbouffard that's work for me

Related

Modifying a Preference value in PreferenceActivity has no effect before Activity is closed

I am just trying to change the value of a Preference when the PreferenceActivity has been opened. As there is no "setValue" or similar on a Preference, I try
My code:
long value = System.currentTimeMillis()/1000;
PreferenceManager.getDefaultSharedPreferences(getActivity()).edit().putString("test",""+value).apply();
getPreferenceScreen().findPreference("test").setSummary(""+value);
My XML:
<EditTextPreference
android:key="test" />
What I expect:
When clicking on my Preference, it should display the value of time (same than summary) and let me edit it.
What happen:
The value is only changed after I closed the Activity. Next time I open the screen, the value is correct (but as in fact already changed to the next one)
First attempt:
Let s say value is 1521143527. Correctly written in the summary, but when I click on the Preference, the popup display an empty value.
Second attemp:
Summary has changed to 1521143540. When I click on Preference, I can edit the previous value (1521143527)
Third attempt:
New Summary, but Preference value is not changed and is still: 1521143540
etc...
Any idea what is wrong?
DIRTY WORKAROUND:
setPreferenceScreen(null);
addPreferencesFromResource(R.xml.preferences);
Will now force the preference to update, but that's really dirty, and I still don't understand...
If you look into the PreferenceFragment source code ,you can see that there is a method called bindPreferences() which binds the preference values to Views . Only in 2 scenarios this method is called,
When Activity created onActivityCreated(#Nullable Bundle savedInstanceState)
When addPreferencesFromResource() called. there is a handler which triggers the bindPreferences()
Other than this there is no way the views are updated. bindPreferences() is a private method , so you can't call this method outside of the class. So you should update your preferences before either those events.
You mentioned, As a workaround solution, you should update your preference first then call addPreferencesFromResource() . Like below
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
long value = System.currentTimeMillis()/1000;
getPreferenceManager().getSharedPreferences().edit().putString("test",""+value).commit();
addPreferencesFromResource(R.xml.pref_general);
getPreferenceScreen().findPreference("test").setSummary(""+value);
}

Preference in PreferenceFragment is not getting updated

I have a main activity that loads a PreferenceFragment (its part of an actionBar).
Within the PreferenceFragment I load my preferences from a XML File:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
}
The Problem is if I change the Tab (remember it is getting managed by an ActionBar), change one of the preferences in a different fragment and coming back to my preferenceFragment its not getting updated. Particularly the problem is a SwitchPreference(true/false) which can be changed from different fragments and even by remote calls (then the preference is getting changed in shared preferences. YES I did commit the change).
I searched for different solutions, but to be honest I didn´t find a working one.
My own ideas are the following:
My Problem would be solved if I could get the Switch Element of the switch, so I could set the switch to true in the onStart() or onResume() method. But is there a change to get the Switch Object?
If I would load a usual layout I could access the switch like this:
View v = inflater.inflate(R.layout.start_fragment, container, false);
Switch status = (Switch) v.findViewById(R.id.switch1);
Afterwards I would be able to set the Position of the Switch like this:
status.setChecked(true);
Another solution would be to destroy the actual view and call addPreferencesFromResource() again, but to be honest I have no idea how this could be done....
The third solution could be to use a OnCheckedChangeListener in my PreferenceFragment, but the problem would again be how to change/update the switch.
I am sure that the Preference is updated correctly, because I´m running a OnSharedPreferenceChangeListener in one of my services and to debug this problem I made the listener log the status of my switchPreference.
Can you help me somehow?
unfortunately I cannot answer my own question before tomorrow morning, so I edit my question:
Thank you guys, I don´t want to restart the underlying activity, but only the fragment.
Fortunately I found a clue in this thread: How do you refresh PreferenceActivity to show changes in the settings?
I can really access the SwitchPreference that simple.
My solution is:
private SwitchPreference pref_phone_locked;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.preferences);
status = (SwitchPreference) findPreference("status");
}
public void onStart(){
super.onStart();
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(getActivity());
if(sharedPref.getBoolean("status", false)){
status.setChecked(true);
}else{
status.setChecked(false);
}
}
This way I can simply cast the Preference to a SwitchPreference and modify it after every onStart() call. I guess this is the best solution for my problem.
Hopefully this answer will save someones time in future =)
Thanks you guys again!
I'm not sure if this will work for you ( I've a very basic knowlege of Android ) but I found this solution in a similar question and it works very well for me
private void simulateRefresh(){
Intent intent = getIntent();
overridePendingTransition(0, 0);
intent.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
finish();
overridePendingTransition(0, 0);
startActivity(intent);
}
Basically this destroy and recreate the activity without animation in between.
Found here

Run some code when user closes a particular preference screen?

Is there a way to find out when the user closes a particular preference screen? I need to do some updating when the user has changed the preferences in one of my preference screens. Not when the user clicks an actual checkbox, but rather when they press the back button and are done editing the preferences.
So far, all I've been able to find is that I can override my PreferenceActivity's onPause() event, which seems to happen when the user closes the preferences. It works, but I'm not sure this is the best way of going about it. Any suggestions?
EDIT
I couldn't figure out how to actually call a method of my main activity from within the PreferenceActivity. Tried playing around with putExtra() and all sorts of stuff. Eventually i figured - why not do the completely opposite? So instead I implemented the onResume() method in my main activity. Works great for doing stuff when the user closes the preferences, and I can live with the fact that my update method runs every time I resume my app as well.
Well I have been searching for a solution of this issue for weeks up to 2 min ago...
i think i found the way.
Preference myPrefScreen = findPreference("myPrefScreen");
myPrefScreen
.setOnPreferenceClickListener(new OnPreferenceClickListener() {
#Override
public boolean onPreferenceClick(Preference prefScreen) {
// TODO Auto-generated method stub
Dialog prefScreenDialog = ((PreferenceScreen) prefScreen)
.getDialog();
prefScreenDialog
.setOnDismissListener(new OnDismissListener() {
#Override
public void onDismiss(DialogInterface arg0) {
// TODO Auto-generated method stub
///HERE YOU CAN EXECUTE WHATEVER YOU WANT...
}
});
return false;
}
});
You need OnPreferenceClickListener to correctly instantiate the PreferenceScreen Dialog generated only once the PreferenceScreen entry has been tapped on the screen and the new window with the preference children are shown. Otherwise you always getDialog() returns null and there's no way to attach the OnDismissListener to it.
Once you set the OnDismissListener the trick is done!!
I hope this could help.
Happy coding to all!!
That's the best way to go about it: overriding the onPause() method. It's called right before your activity leaves the foreground.
onPause is the right place to handle and update.

Any examples for "onDialogClosed"?

Can anyone give me an example or explain me how i subscribe to the
onDialogClosed method of an EditTextPreference?
http://developer.android.com/reference/android/preference/EditTextPreference.html#onDialogClosed%28boolean%29
I want to know when a dialog had its OK button clicked
and then retrive the information from the EditTextPreference.
Is there any examples/tutorials of this available or can anyone point
me in the right direction?
Thank you.
Just for completion: Since EditTextPreference is a Preference, you can use a OnPreferenceChangeListener. That will be called when the preference is changed. Check for the EditTextPreferences key in the callback and retrieve the new value to act on it. This is especially useful when the preference can be changed in more than one place or will be changed in the background by your app (e.g. writing defaults back when clicking a "default settings" button), since every change will trigger that callback (when your register it global on your SharedPreferences). The onDialogClosed will only be triggered when the user closed the actual dialog.
If you want to watch the single preference you can also use the EditTextPreference.setOnPreferenceChangedListener() function to assign a listener to that preference only.
OnPreferenceChangeListener documentation
You can make something like that :
#Override
protected void onDialogClosed(boolean positiveResult) {
if (positiveResult) {
String text=MyEditText.getText();
}
else {
// cancel hit
}
}

Change summary when returning from nested PreferenceScreen

I have a PreferencesActivity with a nested PreferenceScreen, so the PreferenceScreen has its own line in the list of preferences, and when you click on it, you're presented with a few more options.
When the user changes one of those options, I update that option's summary to show what the user has selected.
I also want to change the summary of the PreferenceScreen on the main list to show the values of its sub-settings. I'm using an OnSharedPreferenceChangeListener to update both summaries at once. However, only the summary of the preference gets changed, not the summary of the preference screen.
Here is simplified code:
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
if (key.equals(SUB_PREFERENCE)){
updateSubPreferenceSummary(); //works
updatePreferenceScreenSummary(); //doesn't work
} else if (key.equals(SOME_OTHER_PREF_IN_ROOT_OF_PREFERENCEACTIVITY) {
updatePreferenceScreenSummary(); //works. (not what I want--just illustrating issue)
}
}
My theory is that Android is ignoring the first screen when it's not visible, so it doesn't get updated. I tried overriding onBackPressed(), but that doesn't work either.
I found a work-around. Apparently, the summary was getting updated, but the view from the parent screen was not getting invalidated/redrawn.
So I do this after updating the summary:
mHandler.post(new Runnable(){
public void run(){onContentChanged();
}});
I put it in the Handler just as a precaution, because I'm not sure what thread the onSharedPreferenceChanged() gets called from.

Categories

Resources