Preference API | Build Settings UI in Android Studio

Preference API | Build Settings UI in Android Studio

In this article we will learn how to build Settings UI in android studio using Preference API. To clarify more, in app setting allows the user to change the functionality and behavior of your app. Furthermore, it can affect the background behavior such as change the app data synchronization. Moreover, settings can affect the app content and user interface.

AndroidX Preference API is the recommended way to integrate user settings in your app. Moreover, this library comes with material theme that provides a consistent user experience across devices and OS versions. In addition, the library manages user interface and interacts with storage.

Screen settings contains a Preference hierarchy which is defined as XML file. In order to build screen setting we need to use Androidx Preference dependency of this version “androidx.preference:preference:1.1.0” or higher.

// add this dependency in module level gradle file.

implementation 'androidx.preference:preference:1.1.1'

How to Create Preference hierarchy

The following image showing simple preference hierarchy in XML file.

preference hierarchy screen

This Preference hierarchy contains two Preference. The first is “SwitchPreferenceCompate” that allow the user to toggle the settings on or off. The second is basic preference without widget. In order to build this hierarchy you need to create a new resource layout file. This file must be placed in “res/xml” folder. the following image shows how to create this layout.

create preference hierarchy for settings screen.

After that, you will note that a new folder generated in the “res” folder. Open the generated resource layout file and paste the following code and not that I used “androidx.preference.PreferenceScreen” tag. Moreover, we can not that each preference should have a unique key.

<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <SwitchPreferenceCompat
        app:key="notification"
        app:title="Enable Message Notification" />
    <Preference
        app:key="feedback"
        app:title="Send Feedback"
        app:summary="Report technical issues or suggest new features"/>

</androidx.preference.PreferenceScreen>

After that, we need to inflate the hierarchy from the xml file. In order to do this step we need to create a new java class that inherits the “PreferenceFragmentCompat”. Then, provide the preference xml file in the overrided “onCreatePreferences” method as following.

//please make sure the names of the created files are the same in this code.
public class MyPreferenceAPI extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.my_preference,rootKey);
    }
}

In order to use the Preference fragment open main activity layout file and change the code as the following. I added a fram layout with id to replace the fragment with it.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">


   <FrameLayout
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:id="@+id/fragment_Layout"/>
</FrameLayout>

Finally, in main activity java file we need to use the following code. After that run the app, you should see the above preference settings screen.

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        getSupportFragmentManager()
                .beginTransaction()
                .replace(R.id.fragment_Layout, new MyPreferenceAPI())
                .commit();
    }
}

How to Organize Preference Settings Screen?

Large and complex settings can make it hard for a user to find a particular setting they want to modify. So that, the Preference Library can help you organize your settings screens better. You can group them with a Preference Category when you have several related Preferences on a single screen. Moreover, a Preference Category shows the title of the category and divides the category visually. The following XML code show how to use the preference category to organize settings.

Organize Preference Settings
Organize Preference Settings
<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <PreferenceCategory
        app:key="notifications_category"
        app:title="Notifications">

        <SwitchPreferenceCompat
            app:key="notifications"
            app:title="Enable message notifications"/>

    </PreferenceCategory>

    <PreferenceCategory
        app:key="help_category"
        app:title="Help">

        <Preference
            app:key="feedback"
            app:summary="Report technical issues or suggest new features"
            app:title="Send feedback"/>

    </PreferenceCategory>

</androidx.preference.PreferenceScreen>

How to Spit your hierarchy into multiple screens?

You can display them separately on separate screens if you have a large number of preferences or different categories. Moreover, each display should have its own separate hierarchy as a PreferenceFragmentCompat. You can then connect the preferences to sub-screens containing corresponding preferences on your first screen.

In order to apply the separation, we need to create and new preference xml file for each sub screen as following.

<!--create a new preference screen xml file, name if notification and add this code-->

<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen xmlns:app="http://schemas.android.com/apk/res-auto">
    <PreferenceCategory
        app:key="notifications_category"
        app:title="Notifications">

        <SwitchPreferenceCompat
            app:key="notifications"
            app:title="Enable message notifications"/>

    </PreferenceCategory>
</androidx.preference.PreferenceScreen>
<?xml version="1.0" encoding="utf-8"?>
<!--create a new preference screen xml file, name if help and add this code-->

<PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <PreferenceCategory
        app:key="help_category"
        app:title="Help">

        <Preference
            app:key="feedback"
            app:summary="Report technical issues or suggest new features"
            app:title="Send feedback"/>

    </PreferenceCategory>

</PreferenceScreen>

Then update the my_preference xml file as following.

<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <Preference
        app:title="Notification"
        app:key="notifications"
        app:fragment="com.androidhands.preferenceapidemo.NotificationFragment"/>
    <Preference
        app:key="feedback"
        app:title="Send feedback"
        app:fragment="com.androidhands.preferenceapidemo.HelpFragment"/>

</androidx.preference.PreferenceScreen>

After that, you need to create two PreferenceFragmentCompat fragments.

import androidx.preference.PreferenceFragmentCompat;

public class NotificationFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.notification,rootKey);
    }
}

import androidx.preference.PreferenceFragmentCompat;

public class HelpFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.help,rootKey);
    }
}

The interface method (PreferenceFragmentCompat.OnPreferenceStartFragmentCallback.onPreferenceStartFragment()) is called when a user taps a Preference with the associated fragment. This method is where the new screen is displayed and the surrounding activity should be implemented. Add the implementation in the MyPreference Fragment as the following code.

public class MyPreferenceAPI extends PreferenceFragmentCompat implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        setPreferencesFromResource(R.xml.my_preference,rootKey);
    }

    @Override
    public boolean onPreferenceStartFragment(PreferenceFragmentCompat caller, Preference pref) {
        // Instantiate the new Fragment
        final Bundle args = pref.getExtras();
        final Fragment fragment = getActivity().getSupportFragmentManager().getFragmentFactory().instantiate(
                getActivity().getClassLoader(),
                pref.getFragment());
        fragment.setArguments(args);
        fragment.setTargetFragment(caller, 0);
        // Replace the existing Fragment with the new Fragment
        getActivity().getSupportFragmentManager().beginTransaction()
                .replace(R.id.fragment_Layout, fragment)
                .addToBackStack(null)
                .commit();
        return false;
    }
}

customized preference screen

Thank You

Reed about view binding

Related posts

Leave a Comment