Search code examples
androidandroid-preferencesseekbarpreference

SeekBarPreference with discrete values ()


I just wanted to include a SeekBarPreference in my project with only 3 values (level of emergency : low-Medium-high)

This can easily be done on a classic SeekBar (see example below) but I don't get how I could inlude that is a Preference.

If I use this code, it will work in a SeekBar (not Preference) but in Preferences it will still display a SeekBar without the thick marks.

CODE:

<SeekBar
     android:id="@+id/sb"
     android:layout_width="match_parent"
     android:layout_height="wrap_content"
     android:max="10"
     android:thumb="@drawable/ic_location"
     android:theme="@style/Widget.AppCompat.SeekBar.Discrete" />

Any idea, or suggestion?

enter image description here


Solution

  • You need to use the support SeekbarPreference to customize the thumb and all. You can pass in your own custom layout for your seek bar preference. please check the example from below.

    Your activity where you will add your preference fragment

    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
    
            BlankFragment mPrefsFragment = new BlankFragment();
    
            FragmentManager mFragmentManager = getSupportFragmentManager();
            FragmentTransaction mFragmentTransaction = mFragmentManager
                    .beginTransaction();
            mFragmentTransaction.replace(android.R.id.content, mPrefsFragment);
            mFragmentTransaction.commit();
    
        }
    }
    

    You have to add a specific theme in your manifest for this activity

    <activity
        android:name=".MainActivity"
        android:theme="@style/AppTheme.SettingsTheme" />
    

    styles.xml

    <style name="AppTheme.SettingsTheme" parent="AppTheme.NoActionBar">
        <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
    </style>
    

    Your fragment where you load your preferences from xml

    BlankFragment.java

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

    And your preference file from xml res folder

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.v7.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
    
        <android.support.v7.preference.SeekBarPreference
            android:key="your_pref_key"
            android:max="3"
            android:thumb="@drawable/thumb_icon"
            android:summary="Summary"
            android:layout="@layout/my_custom_seekbar"
            android:title="Title" />
    </android.support.v7.preference.PreferenceScreen>
    

    Here you can see that the android:layout attribute takes a resource layout file where you can supply your own custom seekbar and a textview-which shows the selected value from seekbar

    my_custom_seekbar.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <SeekBar xmlns:android="http://schemas.android.com/apk/res/android"
            android:id="@+id/seekbar"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentLeft="true"
            android:layout_toLeftOf="@+id/seekbar_value"
            android:max="10"
            android:theme="@style/Widget.AppCompat.SeekBar.Discrete"
            android:thumb="@drawable/ic_location" />
    
        <TextView
            android:id="@+id/seekbar_value"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_alignParentRight="true" />
    </RelativeLayout>
    

    Note that you have to use the exact same identifier for your custom SeekBar and TextView, otherwise it will throw a NullPointerException

        android:id="@+id/seekbar" for your custom Seekbar
        android:id="@+id/seekbar_value" for your custom TextView