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
Related
I've a settings fragment which load a xml with a default settings page, I also added one click listener to one specific preference
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Load the preferences from an XML resource
addPreferencesFromResource(R.xml.settings);
preferences.findPreference(getString(R.string.pref_custom_list)).setOnPreferenceChangeListener(this);
//other stuff.....
this works fine, when user clicks triggers an event and i can check some info about the switch including deny the change...
But i would like to turn on/off other switches in the same screen when this even happen
i tried to
preferences.findPreference(getString(R.string.xpto)).setEnabled(true);
but it doesn't turn any switch on or off... it just set the view enabled or disabled for clicks
if i do something like
PreferenceManager.getDefaultSharedPreferences(this).edit().putBoolean("xpto",true).apply();
It does change the preference, but the changes are not loaded to the screen so user doesn't know
how can i switch some preference on or off programatically and make it reflect to the preference screen
You can use SwitchPreferenceCompat.
<SwitchPreferenceCompat
app:key="key"
app:title="Some Confs" />
Try this in your fragment if you are using SwitchPreferenceCompat as above.
SwitchPreferenceCompat switchPref = findPreference("key");
switchPref.setChecked(true);
You're looking for setChecked(), not setEnabled():
preferences.findPreference(getString(R.string.xpto)).setChecked(true);
I think you need to implement a listener when the SharedPreferences change.
SharedPreferences.OnSharedPreferenceChangeListener spChanged = new
SharedPreferences.OnSharedPreferenceChangeListener() {
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// change the Switch Preference state here
}
};
Then when the prefs change, you can change the user's screen to match it.
For your reference:
How to detect if changes were made in the preferences?
So my title may be hard to follow, but I'll try to clarify and expand on what my issue is below.
I currently have an app that starts its life as a MainActivity with multiple Fragments sitting in a ViewPager.
In the MainActivity, I have Android In-App Billing V3 (library) setup so that the user can pay to remove ads. This works just fine in the MainActivity but my issue arises when moving to another Activity.
The first Fragment the user is presented with upon launching the app, contains a RecyclerView with an ArrayList of items. To get to a sub-Activity from the MainActivity, the user presses a button on one of the items in the RecyclerView, which means that the Intent data used to change Activities is contained within the RecyclerViewAdapter.
My issue is that once my app knows that the user has paid to remove ads, I want the app to also remove ads in all sub-Activities as well.
I don't know how to pass this info (that the "Remove Ads" in-app has been purchased) from Activity -> sub-Activity, when sub-Activity is launched through the RVAdapter instead.
So my question is: How would I pass data from MainActivity -> RVAdapter -> Sub-Activity?
Or is there an even better, more efficient way of passing this data along without using Intents? Do let me know!
Did my description of the issue make sense? I hope so! Otherwise let me know how I might clarify it! If you need me to paste in any code, let me know as well.
Thanks for any of your help!
you can use EventBus (greenrobot) nice library for send event this linke
to send evnts
after add library put below method to your main activity:
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event)
don't forget about Register and unregister subscriber, do it like this :
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
finally post your event from everywhere like your subactivity :
EventBus.getDefault().postSticky(new MessageEvent());
Notice:I add postSticky(); to cache data on memory ,Then the sticky event can be delivered to subscribers or queried explicitly.
better solution
but i think you can save value in Sharedpreferences after purcahse:
SharedPreferences.Editor editor = getSharedPreferences(MY_PREFS_NAME,
MODE_PRIVATE).edit();
editor.putBoolean("pay", true);
editor.apply();
then check this valu every Activity on onCreat method
to show adds or don't
SharedPreferences prefs = getSharedPreferences(MY_PREFS_NAME, MODE_PRIVATE);
pay = prefs.getBoolean("pay", false);
if (pay) {
show();
}else dontShow();
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);
}
I'm trying to create a very basic preferences activity, extending PreferenceActivity. In the documentation, I read:
The PreferenceActivity automatically persists the settings associated with each Preference when the user makes a change.
However, when I:
Change a setting (any setting)
Close the app
Remove the app from the recently used list
Relaunch the app
The setting is reset to the default value, which seems to conflict the quoted documentation above. Do I misunderstand something here, is the template faulty, or do I perhaps need additional permissions or other settings to use the PreferenceActivity auto-persist feature?
public class SettingsActivity extends PreferenceActivity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getFragmentManager().beginTransaction()
.replace(android.R.id.content, new SettingsFragment()).commit();
}
public static class SettingsFragment extends PreferenceFragment {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}
}
And preferences.xml:
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:key="pref_language_reading"
android:title="#string/pref_title_language_dailyreading"
android:entries="#array/pref_languages_dailyreading_entries"
android:entryValues="#array/pref_languages_dailyreading_values"
android:defaultValue="#string/pref_language_dailyreading_default"
android:persistent="true" />
</PreferenceScreen>
The strings and arrays exist, and I can select a language properly. The setting is saved when I go to another activity, and then back. But closing the app and relaunching discards the saved value.
When I read out the SharedPreference corresponding to this preference (before relaunching), I see the correct setting. After relaunching, the SharedPreference does not exist anymore though.
The code should work. There is likely something else in your code that causes this behaviour.
In my specific case, it turned out there was a line
PreferenceManager.getDefaultSharedPreferences(this).edit().clear().commit();
In the onCreate() method of the main Activity, causing the SharedPreferences to clear on every launch of the app.
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