Search code examples
javaandroidxmlandroid-preferencesandroidx

How to use PreferenceScreen of Androidx


My problem is that I wanted to add a PreferenceScreen to my Application, but I can't use it and I don't know why.

I implemented the library androidx.preference:preference:1.1.0-rc01. Then I wanted to add the PreferenceScreen to my XML-layout and it doesn't suggest any suggestion.

Next, I copied the XML-Code from Android-Developers into my XML-layout and compiled it, but by starting the activity it breaks with the error: java.lang.ClassCastException: class androidx.preference.PreferenceScreen cannot be cast to android.view.View

Can somebody help me to use the androidx.preference.PreferenceScreen correctly?

My Layout:

<?xml version="1.0" encoding="utf-8"?>
<androidx.preference.PreferenceScreen  xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="match_parent"
    android:layout_width="match_parent">
    <androidx.preference.SwitchPreference
        android:defaultValue="true"
        android:key="example_switch"
        android:summary="Turn this option on or off"
        android:title="Settings option" />
</androidx.preference.PreferenceScreen>

Solution

  • Now the whole answer:

    1. Add this line to your App-Gradle: implementation 'androidx.preference:preference:1.1.1' or implementation 'androidx.preference:preference-ktx:1.1.1' for Kotlin. And sync Gradle. Create a Directory named xml in res Folder.

    2. Create in this directory an XML-File with your prefered name for example main_preferences. Root Element must be androidx.preference.PreferenceScreen.

    3. Fill XML-File with your settings for example:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.preference.PreferenceScreen  xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_height="match_parent"
        android:layout_width="match_parent">
        <androidx.preference.SwitchPreference
            android:defaultValue="true"
            android:key="example_switch"
            android:summary="Turn this option on or off"
            android:title="Settings option" />
    </androidx.preference.PreferenceScreen>
    
    1. Create somewhere in the folder com.???.??? a java file for example named MainSettingsFragment. Superclass (means <Classname> extends <Superclass>) must be PreferenceFragmentCompat and override onCreatePreferences. You can copy this code:
    import android.os.Bundle; 
    import androidx.preference.PreferenceFragmentCompat;
    import com.???.???.R;
    
    public class <YourClassname> extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
            // Load the preferences from an XML resource
            setPreferencesFromResource(R.xml.<yourXmlFilename>, rootKey);
        }
    }
    
    1. Next, there are two options to implement the PreferencesSreen in your .

    The beautiful and best way is, it to implement it per code on creation. Add in your SettingsActivty a FrameLayout and give it an ID for example fl_main_settings:

    <?xml version="1.0" encoding="utf-8"?>
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_height="match_parent"
        android:layout_width="match_parent"
        android:id="@+id/<!-- yourID -->">
    
    </FrameLayout>
    

    And in your Activity Code add really on the top of the onCreate method this:

    package com.???.???;
    import android.graphics.drawable.ColorDrawable;
    import android.os.Bundle;
    import android.text.Html;
    import android.view.MenuItem;
    import androidx.annotation.Nullable;
    import androidx.appcompat.app.AppCompatActivity;
    import androidx.core.text.HtmlCompat;
    
    import com.???.???.MainSettingsFragment;
    public class SettingsActivity extends AppCompatActivity {
        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.<SettingsActivityXML(with the FrameLayout)>);
    
            //If you want to insert data in your settings
            <YourSettingsFragmentClass> settingsFragment = new <YourSettingsFragmentClass>();
            settingsFragment. ...
            getSupportFragmentManager().beginTransaction().replace(R.id.<YourFrameLayout>,settingsFragment).commit();
            
            //Else
            getSupportFragmentManager().beginTransaction().replace(R.id.<YourFrameLayout>,new <YourSettingsFragmentClass>()).commit();
        }
    

    Or you implement a Fragment in your SettingsActivityXml. But I don't recommend this ,because starting the activity takes a few seconds:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:baselineAligned="false">
    
        <fragment
            android:tag="frag"
            android:name="com.quickme.musicme.Fragments.MainSettingsFragment"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>
    </LinearLayout>
    

    That's it have fun.