Building Preference Screen in SUSI Android

SUSI provides various preferences to the user in the settings to customize the app. This allows the user to configure the application according to his own choice. There are different preferences available such as to select the theme or the language for text to speech. Preference Setting Activity is an important part of an Android application. Here we will see how we can implement it in an Android app taking SUSI Android (https://github.com/fossasia/susi_android) as the example. Firstly, we will proceed by adding the Gradle Dependency for the Setting Preferences compile 'com.takisoft.fix:preference-v7:25.4.0.3' Then to create the custom style for our setting preference screen we can set @style/PreferenceFixTheme as the base theme and can apply various other modifications and color over this. By default it has the usual Day and Night theme with NoActionBar extension. Now to make different preferences we can use different classes as shown below: SwitchPreferenceCompat: This gives us the Switch Preference which we can use to toggle between two different modes in the setting. EditTextPreference: This preference allows the user to give its own choice of number or string in the settings which can be used for different actions. For more details on this you can refer the this link. Implementation in SUSI Android In SUSI Android we have created an activity named activity_settings which holds the Preference Fragment for the setting. <?xml version="1.0" encoding="utf-8"?> <fragment   xmlns:android="http://schemas.android.com/apk/res/android"   xmlns:tools="http://schemas.android.com/tools"   android:id="@+id/chat_pref"   android:name="org.fossasia.susi.ai.activities.SettingsActivity$ChatSettingsFragment"   android:layout_width="match_parent"   android:layout_height="match_parent"   tools:context="org.fossasia.susi.ai.activities.SettingsActivity"/> The Preference Settings Fragment contains different Preference categories that are implemented to allow the user to have different customization option while using the app. The pref_settings.xml is as follows <?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"   xmlns:app="http://schemas.android.com/apk/res-auto"   android:title="@string/settings_title">   <PreferenceCategory       android:title="@string/server_settings_title">       <PreferenceScreen           android:title="@string/server_pref"           android:key="Server_Select"           android:summary="@string/server_select_summary">       </PreferenceScreen>   </PreferenceCategory>   <PreferenceCategory       android:title="@string/settings_title">       <com.takisoft.fix.support.v7.preference.SwitchPreferenceCompat           android:id="@+id/enter_key_pref"           android:defaultValue="true"           android:key="@string/settings_enterPreference_key"           android:summary="@string/settings_enterPreference_summary"           android:title="@string/settings_enterPreference_label" />   </PreferenceCategory> All the logic related to Preferences and their action is written in SettingsActivity Java class. It listens for any change in the preference options and take actions accordingly in the following way. public class SettingsActivity extends AppCompatActivity {   private static final String TAG = "SettingsActivity";   private static SharedPreferences prefs;   @Override   protected void onCreate(Bundle savedInstanceState) {       super.onCreate(savedInstanceState);       prefs = getSharedPreferences(Constant.THEME, MODE_PRIVATE);       Log.d(TAG, "onCreate: " + (prefs.getString(Constant.THEME, DARK)));       if(prefs.getString(Constant.THEME, "Light").equals("Dark")) {           setTheme(R.style.PreferencesThemeDark);       }       else {           setTheme(R.style.PreferencesThemeLight);       }       setContentView(R.layout.activity_settings);   } The class contains a ChatSettingFragment which extends the PreferenceFragmentCompat to give access to override functions such as onPreferenceClick. The code below shows the implementation of it. public boolean onPreferenceClick(Preference preference) {               Intent intent = new Intent();               intent.setComponent( new ComponentName("com.android.settings","com.android.settings.Settings$TextToSpeechSettingsActivity" ));               startActivity(intent);               return true;           }       });       rate=(Preference)getPreferenceManager().findPreference(Constant.RATE);       rate.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {           @Override           public boolean onPreferenceClick(Preference preference) {               startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse("http://play.google.com/store/apps/details?id=" + getContext().getPackageName())));               return true;           }       }); } For diving more into the code we can refer to the github repo of Susi Android (https://github.com/fossasia/susi_android). Resources Article by Jakob Ulbrich on building setting screen in Android: https://medium.com/@JakobUlbrich/building-a-settings-screen-for-android-part-1-5959aa49337c Github repository of Android Support Preference Fix by Gericop https://github.com/Gericop/Android-Support-Preference-V7-Fix

Continue ReadingBuilding Preference Screen in SUSI Android

Building Android preference screen

Some days ago, I started building a Setting Screen for my Android app. Everything was fine, until I opened it on an older Android version. The overview screen had no material design, a thing I would have accepted, if there weren’t those completely destroyed dialogs: Android’s internal preferences are using Android’s internal app.AlertDialogs. Those dialogs in combination with the AppCompat Dialog Theme, which I had applied to them, resulted in a dialog with two frames on older devices (One system default dialog and a material frame around it). So I decided to switch to the android.support.v7.preference library, only to face a lot more issues. Including the Library In order to use the new preferences, we need to import a library. To do so, we add this line to our gradle dependencies (You should change the version number to the latest). compile 'com.android.support:preference-v7:23.4.0' Building The Preference Screen Creating the Preferences At first, we need to create our preference structure: We create a new XML Android resource file as xml/app_preferences.xml. Now we can add our preference structure to this file. Make sure to add a unique android:keyattribute for each preference. More information: How to build the XML <android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> <android.support.v7.preference.PreferenceCategory android:title="Category 1"> <android.support.v7.preference.SwitchPreferenceCompat android:key="key1" android:title="Switch Preference" android:summary="Switch Summary" android:defaultValue="true" /> <android.support.v7.preference.EditTextPreference android:key="key2" android:title="EditText Preference" android:summary="EditText Summary" android:dialogMessage="Dialog Message" android:defaultValue="Default value" /> <android.support.v7.preference.CheckBoxPreference android:key="key3" android:title="CheckBox Preference" android:summary="CheckBox Summary" android:defaultValue="true"/></android.support.v7.preference.PreferenceCategory></android.support.v7.preference.PreferenceScreen> The v7.preference library provides some preferences we can use: CheckBoxPreference, SwitchPreferenceCompat, EditTextPreference and a ListPreference (and a basic Preference). If we need more than these predefined preferences, we have to build them on our own. Creating the Preference Fragment Now we need to create our Preference Fragment, where we can show the preferences from our XML file. We do this by creating a new class, called SettingsFragment, which extends PreferenceFragmentCompat. Since the onCreatePreferences is declared as abstract in the source code of the library, we are forced to include our own implementation to tell the fragment to load our just created app_preferences.xml. import android.support.v7.preference.PreferenceFragmentCompat; public class SettingsFragment extends PreferenceFragmentCompat { @Override public void onCreatePreferences(Bundle bundle, String s) { // Load the Preferences from the XML file addPreferencesFromResource(R.xml.app_preferences); } } We can add this SettingsFragment (v4.app.Fragment), like any other Fragment (e.g. with a FragmentTransaction) to an Activity. Applying the Preference Theme Finally we need to specify a preferenceTheme in our Activity’s theme. If we don’t do so, the App will crash with an IllegalStateException. The v7.preference library provides only one Theme: PreferenceThemeOverlay(You may have a look at its source code). We add this with the following line in our Activity’s theme: <item name="preferenceTheme">@style/PreferenceThemeOverlay</item> After we have done this, our result should now look like this. (The Activity’s parent theme is Theme.AppCompat and the background is set with android:windowBackground) Settings Screen with PreferenceThemeOverlay As you can see, it has an oversized font and a horizontal line below the category title. This is definitely not material design. It more looks like a mixture of material design for the CheckBoxand Switch widgets on the right and an old…

Continue ReadingBuilding Android preference screen