Search code examples
androidlayoutsharedpreferencesandroid-support-libraryseekbar

How to Create a Custom SeekBar Preference?


I'm trying to create a custom seekbar preference, but Android can't seem to find the element. I get

java.lang.NullPointerException: Attempt to invoke virtual method 'void android.view.View.setVisibility(int)' on a null object reference at
    at android.support.v7.preference.SeekBarPreference.onBindViewHolder(SeekBarPreference.java:154)

when I try to access the setting. The reason seems to be that it can't find my custom seekbar element and link it to the preference. Usually I would name the custom preference element something like @android:id/seekbar to make the linkage work, but when it comes to SeekBar, it says that's private. I tried @+id/seekbar as per Android: Creating custom preference, but it doesn't seem to work to tie my custom seekbar to the preference.

Here is my code:

Preference XML

<android.support.v7.preference.SeekBarPreference
            android:key="my_seekbar_preference"
            android:layout="@layout/seekbar_preference"
            android:max="10"
            android:defaultValue="5" />

SeekBar Layout

<?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="wrap_content"
android:orientation="vertical"
android:layout_margin="@dimen/half_normal">

<TextView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_margin="@dimen/half_normal"
    android:layout_marginLeft="@dimen/normal"
    style="@style/SettingsSubHeader"
    android:text="Seekbar Settings"/>

<SeekBar
    android:id="@+id/seekbar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    style="@style/Widget.AppCompat.SeekBar.Discrete"
    android:max="10"
    android:min="0"/>

</LinearLayout>

Any ideas on what I'm doing wrong? I don't this problem with any of my other custom preferences.


Solution

  • The issue seems to be that in addition to my custom layout needing a Seekbar element marked @+id/seekbar, it also needs a Textview element marked @+id/seekbar_value to display the current value of the seekbar. If this is missing, I get a null pointer exception. If I add one in, everything works fine:

    <TextView
        android:id="@+id/seekbar_value"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>
    

    Also note that setting android:visibility="gone" doesn't work in this case, so if you don't want to display the value, you need to set android:textSize="0dp to hide it.