Android Settings Series (part 2)
Welcome to this series post.
In this series post, we are going to create a complete Settings for a productive app.
We already published a post-
pref_advance.xml
we need to modify activity_sttings.xml
activity_sttings.xml
that's we finished XML coding
Now time for java code-
create two new java file like SettingsFragment.java
note: I show you how you can do that. I am going throw step by step. But Don't worry I will provide full code for other two class.
AdvacnceSettingsFragment.java
now create two variable in this class
now add this method
that it for this class. You can also check git. AdvanceSettingsFragment
Now time for BackupFragment.java
BackupFragment.java
now change SettingsFragment.java (that's found in the part1)
SettingsFragment.java
add this method and two variable. Are you confused where you need to put this code, you can see this on git SettingsFragment
We are almost last step-
we need to make some changes on Settings Activity-
Steps-
See the code-
we need to implement this method-
we do this later in this post.
create a new Fragment Manager and make these changes-
Now change this method
That's it.
we finished the coding of Android Settings with the fragment. In the next parts, we do same this by using 2 activity. As we use single activity on Android App Settings with Preference Fragment Compat this post. We have already one activity and We create two new other activity and do same settings. Until then Happy coding.
Possible Error and Fix:
you can get that class cannot find. If you find this error you probably miss adding preference as in your dependencies
Or, If your app is Crashed then check the Styles.xml
add this line
Still not working, please recheck the code
All Java Class:
Layout XML:
Pref XML
Once again Happy coding
In this series post, we are going to create a complete Settings for a productive app.
We already published a post-
Now I am starting where I left in the previous post.
Now we need to create other 2 XML file. (In our final settings we need 3 XML file, we already have done one.)
pref_backup.xml
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <Preference android:key="@string/bps_ex_fav_key" android:summary="@string/bps_ex_fav_summery" android:title="@string/bps_ex_fav_title" /> <Preference android:key="@string/bps_im_fav_key" android:summary="@string/bps_im_fav_summery" android:title="@string/bps_im_fav_title" /> <Preference android:key="@string/bps_ex_add_key" android:summary="@string/bps_ex_add_summery" android:title="@string/bps_ex_add_title" /> <Preference android:key="@string/bps_im_add_key" android:summary="@string/bps_im_add_summery" android:title="@string/bps_im_add_title" /> </PreferenceScreen>
pref_advance.xml
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <CheckBoxPreference android:defaultValue="false" android:key="@string/switchKey" android:summaryOff="@string/switchOFF" android:summaryOn="@string/switchON" android:title="@string/switchLabel"/> </PreferenceScreen>
we need to modify activity_sttings.xml
activity_sttings.xml
<!-- <fragment android:layout_marginTop="?attr/actionBarSize" android:id="@+id/settings_fragment" android:name="com.blogspot.shudiptotrafder.soilscience.settings.SettingsFragment" android:layout_width="match_parent" android:layout_height="match_parent" /> --> <RelativeLayout android:layout_marginTop="?attr/actionBarSize" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/settingsContainer" />
that's we finished XML coding
Now time for java code-
create two new java file like SettingsFragment.java
note: I show you how you can do that. I am going throw step by step. But Don't worry I will provide full code for other two class.
AdvacnceSettingsFragment.java
public class AdvanceSettingsFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener { @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { Preference preference = findPreference(key); //if for re queries if (preference != null) { if (!(preference instanceof CheckBoxPreference)) { String value = sharedPreferences.getString(preference.getKey(), ""); setPreferenceSummery(preference, value); } } } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { // Add 'general' preferences, defined in the XML file addPreferencesFromResource(R.xml.pref_advance); SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences(); PreferenceScreen preferenceScreen = getPreferenceScreen(); int count = preferenceScreen.getPreferenceCount(); for (int i = 0; i < count; i++) { Preference p = preferenceScreen.getPreference(i); if (!(p instanceof CheckBoxPreference)) { String value = sharedPreferences.getString(p.getKey(), ""); setPreferenceSummery(p, value); } } } private void setPreferenceSummery(Preference preference, Object value) { String stringValue = value.toString(); if (preference instanceof ListPreference) { // For list preferences, look up the correct display value in // the preference's 'entries' list (since they have separate labels/values). ListPreference listPreference = (ListPreference) preference; int prefIndex = listPreference.findIndexOfValue(stringValue); //same code in one line //int prefIndex = ((ListPreference) preference).findIndexOfValue(value); //prefIndex must be is equal or garter than zero because //array count as 0 to .... if (prefIndex >= 0) { listPreference.setSummary(listPreference.getEntries()[prefIndex]); } } else { // For other preferences, set the summary to the value's simple string representation. preference.setSummary(stringValue); } } //register and unregister on lifecycle @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getPreferenceScreen().getSharedPreferences() .registerOnSharedPreferenceChangeListener(this); } @Override public void onDestroy() { super.onDestroy(); getPreferenceScreen().getSharedPreferences() .unregisterOnSharedPreferenceChangeListener(this); } }
now create two variable in this class
private static final String TAG = AdvanceSettingsFragment.class.getName(); public static final String PAGE_ID = "page_id";
now add this method
public static AdvanceSettingsFragment newInstance(String pageId) { AdvanceSettingsFragment f = new AdvanceSettingsFragment(); Bundle args = new Bundle(); args.putString(PAGE_ID, pageId); f.setArguments(args); return (f); }
that it for this class. You can also check git. AdvanceSettingsFragment
Now time for BackupFragment.java
BackupFragment.java
public class BackupSettings extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = AdvanceSettingsFragment.class.getName(); public static final String PAGE_ID = "page_id"; public static BackupSettings newInstance(String pageId) { BackupSettings f = new BackupSettings(); Bundle args = new Bundle(); args.putString(PAGE_ID, pageId); f.setArguments(args); return (f); } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { Preference preference = findPreference(key); if (preference != null) { if (!(preference instanceof CheckBoxPreference)) { String value = sharedPreferences.getString(preference.getKey(), ""); setPreferenceSummery(preference, value); } } } @Override public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { // Add 'general' preferences, defined in the XML file addPreferencesFromResource(R.xml.pref_backup); SharedPreferences sharedPreferences = getPreferenceScreen().getSharedPreferences(); PreferenceScreen preferenceScreen = getPreferenceScreen(); int count = preferenceScreen.getPreferenceCount(); for (int i = 0; i < count; i++) { Preference p = preferenceScreen.getPreference(i); if (!(p instanceof CheckBoxPreference)) { String value = sharedPreferences.getString(p.getKey(), ""); setPreferenceSummery(p, value); } } //my all preference Preference exportFavourite = findPreference(getString(R.string.bps_ex_fav_key)); Preference importFavourite = findPreference(getString(R.string.bps_im_fav_key)); Preference exportAddWord = findPreference(getString(R.string.bps_ex_add_key)); Preference importAddWord = findPreference(getString(R.string.bps_im_add_key)); //export favourite exportFavourite.setOnPreferenceClickListener(preference -> { //your code }); //import favourite importFavourite.setOnPreferenceClickListener(preference -> { //your code }); //export added word exportAddWord.setOnPreferenceClickListener(preference -> { //you code }); //import added word importAddWord.setOnPreferenceClickListener(preference -> { //your code }); } private void setPreferenceSummery(Preference preference, Object value) { String stringValue = value.toString(); if (preference instanceof ListPreference) { ListPreference listPreference = (ListPreference) preference; int prefIndex = listPreference.findIndexOfValue(stringValue); if (prefIndex >= 0) { listPreference.setSummary(listPreference.getEntries()[prefIndex]); } } else { preference.setSummary(stringValue); } } //register and unregister on lifecycle @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getPreferenceScreen().getSharedPreferences() .registerOnSharedPreferenceChangeListener(this); } @Override public void onDestroy() { super.onDestroy(); getPreferenceScreen().getSharedPreferences() .unregisterOnSharedPreferenceChangeListener(this); } }
now change SettingsFragment.java (that's found in the part1)
SettingsFragment.java
private static final String TAG = SettingsFragment.class.getName(); public static final String PAGE_ID = "page_id"; public SettingsFragment newInstance(String pageId) { SettingsFragment f = new SettingsFragment(); Bundle args = new Bundle(); args.putString(PAGE_ID, pageId); f.setArguments(args); return f; }
add this method and two variable. Are you confused where you need to put this code, you can see this on git SettingsFragment
We are almost last step-
we need to make some changes on Settings Activity-
Steps-
- implement this "PreferenceFragmentCompat.OnPreferenceStartScreenCallback"
- add fragment manager and replace the fragment
See the code-
public class SettingsActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartScreenCallback { }
we need to implement this method-
@Override public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen preferenceScreen) { return false; }
we do this later in this post.
create a new Fragment Manager and make these changes-
FragmentManager fragmentManager = getSupportFragmentManager(); Fragment fragment; if (savedInstanceState == null) { FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); fragment = new SettingsFragment().newInstance("Advanced_Setting"); fragmentTransaction.add(R.id.settingsContainer, fragment); fragmentTransaction.commit(); }
Now change this method
@Override public boolean onPreferenceStartScreen(PreferenceFragmentCompat caller, PreferenceScreen preferenceScreen) { //Log.d(TAG, "callback called to attach the preference sub screen"); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); AdvanceSettingsFragment fragment = AdvanceSettingsFragment.newInstance("Advanced Settings Subscreen"); BackupSettings backupSettings = BackupSettings.newInstance("BackUp Settings"); Bundle args = new Bundle(); //Defining the sub screen as new root for the subscreen args.putString(PreferenceFragmentCompat.ARG_PREFERENCE_ROOT, preferenceScreen.getKey()); fragment.setArguments(args); if (preferenceScreen.getKey().equalsIgnoreCase("backup")) { ft.replace(R.id.settingsContainer, backupSettings, preferenceScreen.getKey()); } else { ft.replace(R.id.settingsContainer, fragment, preferenceScreen.getKey()); } ft.addToBackStack(null); ft.commit(); return true; }
That's it.
we finished the coding of Android Settings with the fragment. In the next parts, we do same this by using 2 activity. As we use single activity on Android App Settings with Preference Fragment Compat this post. We have already one activity and We create two new other activity and do same settings. Until then Happy coding.
Possible Error and Fix:
you can get that class cannot find. If you find this error you probably miss adding preference as in your dependencies
//for settings compile 'com.android.support:preference-v14:26.1.0'
Or, If your app is Crashed then check the Styles.xml
add this line
<!-- must add this line or app will crash --> <item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>
Still not working, please recheck the code
All Java Class:
Layout XML:
Pref XML
Once again Happy coding
No comments :