Android Basics: Settings - II
June 28, 2020
Tags: Android, Android Basics, Github Repository App, Settings, Preferences, ListPreference,
All the changes that we make in the activity are reflected in the default SharedPreference. There can be other SharedPreferences, we are going to use the one which is used by default.
You can get the code for everything we have done till now here.
How to listen to changes in Preferences
Overview
- Implement the interface
SharedPreferences.OnSharedPreferenceChangeListener
in the Activity. - Override and fill out the method
onSharedPreferenceChanged
. - Register and unregister the listener in onCreate and onDestroy.
Implement OnSharedPreferenceChangeListener interface
Add SharedPreferences.OnSharedPreferenceChangeListener
to the activity where you want to detect the changes.
public class MainActivity extends AppCompatActivity implements RepositoryAdapter.ListItemClickListener, SharedPreferences.OnSharedPreferenceChangeListener
Override and fill out the method onSharedPreferenceChanged
After adding OnSharedPreferenceChangeListener
android studio will be unhappy and show you those red wavy underline because SharedPreferences.OnSharedPreferenceChangeListener
is an interface with the method onSharedPreferenceChanged
in it, which means we have to override and implement it.
This is where we will add the code that is supposed to run in reaction to the changes in the default sharedPreference.
In our case we want to search Github again with the new sort parameter. I have created a method called searchGithub
which checks if the edit text is not empty and runs our AsyncTask again with the new sort parameter.
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
Log.d("Key", key);
if (key.equals(getString(R.string.pref_sort_by_key))){
searchGithub();
}
Register and unregister the listener in onCreate and onDestroy.
We need to register and unregister the listener. The best places to do it would be the first lifecycle callback onCreate
and the last one onDestroy
.
Register in onCreate:
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
sharedPreferences.registerOnSharedPreferenceChangeListener(this);
Unregister in onDestory:
@Override
protected void onDestroy() {
super.onDestroy();
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
sharedPreferences.unregisterOnSharedPreferenceChangeListener(this);
}
Now when we change settings and come back to our activity the data in our recycler view gets changed according to the sort we selected.
Show ListPreference option selected as summary.
Right now when we go into the settings we don’t get to see the currently selected option until we click and expand the setting. To improve that we want to add the currently selected option as the summary to the ListPreference.
Here is how I did it:
- Go through all the preferences and find
ListPreference
- If the preference is an instance
ListPreference
type cast the preference into aListPreference
- Get the currently selected value and set it as the new summary.
After we do the three steps above we soon realize the summary is shown but does not change when we select a different value in the setting. So just like we did earlier we add OnSharedPreferenceChangeListener
to our Fragment.
- Add
SharedPreferences.OnSharedPreferenceChangeListener
to the fragment. - Override and fill out the method
onSharedPreferenceChanged
and update the summary. - Register the listener in onCreate and unregister in onDestroy.
public class SettingsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
addPreferencesFromResource(R.xml.settings_pref);
updateListPreferenceSummary();
}
private void updateListPreferenceSummary() {
PreferenceScreen preferenceScreen = getPreferenceScreen();
SharedPreferences preferences = preferenceScreen.getSharedPreferences();
int count = preferenceScreen.getPreferenceCount();
for (int i = 0; i < count; i++){
Preference preference = preferenceScreen.getPreference(i);
if (preference instanceof ListPreference) {
String activeValue = preferences.getString(preference.getKey(), null);
ListPreference listPreference = (ListPreference) preference;
int index = listPreference.findIndexOfValue(activeValue);
if (index >= 0){
listPreference.setSummary(activeValue);
}
}
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
updateListPreferenceSummary();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
@Override
public void onDestroy() {
super.onDestroy();
getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
}
}
The Result
You can find the code for everything done up till now here.
As always if you find any errors, have feedback or just want to say hi please don’t hesitate to leave a comment below.