Ползунок на моем экране предпочтений

Я хочу, чтобы в моем меню предпочтений было что-то, чтобы изменить продолжительность вибрации.

Нет тега slider для prefs.xml, так что лучший способ сделать это?

Ответ 1

Вы можете создать свой собственный класс предпочтений, который расширяет DialogPreference и показывает SeekBar в качестве диалогового окна.

Ответ 2

Я улучшил ссылку, предоставленную Macarse, так что значение сохраняется только при нажатии кнопки ОК, и поэтому вы можете использовать значения @string/... в файле XML.

Вот код:

/* The following code was written by Matthew Wiggins 
 * and is released under the APACHE 2.0 license 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Improvements :
 * - save the value on positive button click, not on seekbar change
 * - handle @string/... values in xml file
 */

package fr.atcm.carpooling.views.utils;

import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;


public class SeekBarPreference extends DialogPreference implements SeekBar.OnSeekBarChangeListener, OnClickListener
{
    // ------------------------------------------------------------------------------------------
    // Private attributes :
    private static final String androidns="http://schemas.android.com/apk/res/android";

    private SeekBar mSeekBar;
    private TextView mSplashText,mValueText;
    private Context mContext;

    private String mDialogMessage, mSuffix;
    private int mDefault, mMax, mValue = 0;
    // ------------------------------------------------------------------------------------------



    // ------------------------------------------------------------------------------------------
    // Constructor :
    public SeekBarPreference(Context context, AttributeSet attrs) {

        super(context,attrs); 
        mContext = context;

        // Get string value for dialogMessage :
        int mDialogMessageId = attrs.getAttributeResourceValue(androidns, "dialogMessage", 0);
        if(mDialogMessageId == 0) mDialogMessage = attrs.getAttributeValue(androidns, "dialogMessage");
        else mDialogMessage = mContext.getString(mDialogMessageId);

        // Get string value for suffix (text attribute in xml file) :
        int mSuffixId = attrs.getAttributeResourceValue(androidns, "text", 0);
        if(mSuffixId == 0) mSuffix = attrs.getAttributeValue(androidns, "text");
        else mSuffix = mContext.getString(mSuffixId);

        // Get default and max seekbar values :
        mDefault = attrs.getAttributeIntValue(androidns, "defaultValue", 0);
        mMax = attrs.getAttributeIntValue(androidns, "max", 100);
    }
    // ------------------------------------------------------------------------------------------



    // ------------------------------------------------------------------------------------------
    // DialogPreference methods :
    @Override 
    protected View onCreateDialogView() {

        LinearLayout.LayoutParams params;
        LinearLayout layout = new LinearLayout(mContext);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.setPadding(6,6,6,6);

        mSplashText = new TextView(mContext);
        mSplashText.setPadding(30, 10, 30, 10);
        if (mDialogMessage != null)
            mSplashText.setText(mDialogMessage);
        layout.addView(mSplashText);

        mValueText = new TextView(mContext);
        mValueText.setGravity(Gravity.CENTER_HORIZONTAL);
        mValueText.setTextSize(32);
        params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.FILL_PARENT, 
                LinearLayout.LayoutParams.WRAP_CONTENT);
        layout.addView(mValueText, params);

        mSeekBar = new SeekBar(mContext);
        mSeekBar.setOnSeekBarChangeListener(this);
        layout.addView(mSeekBar, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.FILL_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));

        if (shouldPersist())
            mValue = getPersistedInt(mDefault);

        mSeekBar.setMax(mMax);
        mSeekBar.setProgress(mValue);

        return layout;
    }

    @Override 
    protected void onBindDialogView(View v) {
        super.onBindDialogView(v);
        mSeekBar.setMax(mMax);
        mSeekBar.setProgress(mValue);
    }

    @Override
    protected void onSetInitialValue(boolean restore, Object defaultValue)  
    {
        super.onSetInitialValue(restore, defaultValue);
        if (restore) 
            mValue = shouldPersist() ? getPersistedInt(mDefault) : 0;
            else 
                mValue = (Integer)defaultValue;
    }
    // ------------------------------------------------------------------------------------------



    // ------------------------------------------------------------------------------------------
    // OnSeekBarChangeListener methods :
    @Override
    public void onProgressChanged(SeekBar seek, int value, boolean fromTouch)
    {
        String t = String.valueOf(value);
        mValueText.setText(mSuffix == null ? t : t.concat(" " + mSuffix));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seek) {}
    @Override
    public void onStopTrackingTouch(SeekBar seek) {}

    public void setMax(int max) { mMax = max; }
    public int getMax() { return mMax; }

    public void setProgress(int progress) { 
        mValue = progress;
        if (mSeekBar != null)
            mSeekBar.setProgress(progress); 
    }
    public int getProgress() { return mValue; }
    // ------------------------------------------------------------------------------------------



    // ------------------------------------------------------------------------------------------
    // Set the positive button listener and onClick action : 
    @Override
    public void showDialog(Bundle state) {

        super.showDialog(state);

        Button positiveButton = ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE);
        positiveButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        if (shouldPersist()) {

            mValue = mSeekBar.getProgress();
            persistInt(mSeekBar.getProgress());
            callChangeListener(Integer.valueOf(mSeekBar.getProgress()));
        }

        ((AlertDialog) getDialog()).dismiss();
    }
    // ------------------------------------------------------------------------------------------
}

ИЗМЕНИТЬ:

Вот скриншот:

Screenshot SeekBarPreference

EDIT: по требованию arlomedia, вот все необходимые фрагменты кода (я только что воссоздал новый проект, он отлично работает. Я исправил некоторые ошибки в классе SeekBarPreference, поэтому не забудьте повторно его скопировать/вставить ):

MainActivity:

package fr.at.testsliderpref;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }


    @Override
    public boolean onCreateOptionsMenu(Menu menu) {

        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {

        switch(item.getItemId()) {

            case R.id.menu_settings : {

                startActivity(new Intent(this, SettingsActivity.class));

                break;
            }
        }

        return true;    
    }
}

SettingsActivity:

package fr.at.testsliderpref;

import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceFragment;
import android.preference.PreferenceManager;
import fr.at.testsliderpref.utils.SeekBarPreference;

public class SettingsActivity extends PreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        // Call super :
        super.onCreate(savedInstanceState);

        // Set the activity fragment :
        getFragmentManager().beginTransaction().replace(android.R.id.content, new SettingsFragment()).commit();
    }


    public static class SettingsFragment extends PreferenceFragment implements OnSharedPreferenceChangeListener {

        private SeekBarPreference _seekBarPref;

        @Override
        public void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            // Load the preferences from an XML resource
            addPreferencesFromResource(R.xml.activity_settings);


            // Get widgets :
            _seekBarPref = (SeekBarPreference) this.findPreference("SEEKBAR_VALUE");

            // Set listener :
            getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);

            // Set seekbar summary :
            int radius = PreferenceManager.getDefaultSharedPreferences(this.getActivity()).getInt("SEEKBAR_VALUE", 50);
            _seekBarPref.setSummary(this.getString(R.string.settings_summary).replace("$1", ""+radius));
        }

        @Override
        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {

            // Set seekbar summary :
            int radius = PreferenceManager.getDefaultSharedPreferences(this.getActivity()).getInt("SEEKBAR_VALUE", 50);
            _seekBarPref.setSummary(this.getString(R.string.settings_summary).replace("$1", ""+radius));
        }
    }
}

layout > activity_main.xml:

<RelativeLayout 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:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/textview_text" />

</RelativeLayout>

menu > main.xml:

<menu xmlns:android="http://schemas.android.com/apk/res/android" >

    <item
        android:id="@+id/menu_settings"
        android:title="@string/menu_settings"
        android:icon="@android:drawable/ic_menu_preferences"/>

</menu>

xml > activity_settings.xml:

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

        <fr.at.testsliderpref.utils.SeekBarPreference
            android:defaultValue="50"
            android:dialogMessage="@string/settings_dialog_message"
            android:key="SEEKBAR_VALUE"
            android:max="100"
            android:summary="@string/settings_summary"
            android:text="@string/settings_unit"
            android:title="@string/settings_title" />

</PreferenceScreen>

values > strings.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">TestSliderPref</string>
    <string name="textview_text">SeekBarPreference test</string>

    <string name="menu_settings">Settings</string>
    <string name="settings_dialog_message">Here comes a message</string>
    <string name="settings_summary">Current value is $1</string>
    <string name="settings_unit">Km</string>
    <string name="settings_title">Here comes the title</string>

</resources>

Не забудьте добавить свой атрибут SettingsActivity в манифест, и все должно быть в порядке.

Ответ 3

Простым способом достижения этого является добавление пустого предпочтения к вашему preferences.xml, который использует макет, включающий в себя поиск.

В вашем preferences.xml добавить

<Preference android:layout="@layout/sliderlayout" />

под макетами добавьте sliderlayout

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

<SeekBar
    android:id="@+id/seekBar1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

</LinearLayout>

Ответ 5

Еще одна реализация этого. Все кредиты отправляются Тиму Аутину.

Мне хотелось, чтобы отображаемые значения загружались из массива XML

Похоже на это

Seekbar setting loading items from XML

Код - это теперь расширяет ListPreference

import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.preference.ListPreference;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

public class SeekBarListPreference extends ListPreference implements SeekBar.OnSeekBarChangeListener, View.OnClickListener {
    // ------------------------------------------------------------------------------------------
    // Private attributes :
    private static final String androidns = "http://schemas.android.com/apk/res/android";

    private SeekBar mSeekBar;
    private TextView mSplashText, mValueText;
    private Context mContext;

    private String mDialogMessage;
    // ------------------------------------------------------------------------------------------


    public SeekBarListPreference(Context context, AttributeSet attrs) {
        super(context, attrs);

        mContext = context;

        // Get string value for dialogMessage :
        int mDialogMessageId = attrs.getAttributeResourceValue(androidns, "dialogMessage", 0);
        if (mDialogMessageId == 0)
            mDialogMessage = attrs.getAttributeValue(androidns, "dialogMessage");
        else mDialogMessage = mContext.getString(mDialogMessageId);
    }

    // ------------------------------------------------------------------------------------------
    // DialogPreference methods :
    @Override
    protected View onCreateDialogView() {

        LinearLayout.LayoutParams params;
        LinearLayout layout = new LinearLayout(mContext);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.setPadding(6, 6, 6, 6);

        mSplashText = new TextView(mContext);
        mSplashText.setPadding(30, 10, 30, 10);
        if (mDialogMessage != null)
            mSplashText.setText(mDialogMessage);
        layout.addView(mSplashText);

        mValueText = new TextView(mContext);
        mValueText.setGravity(Gravity.CENTER_HORIZONTAL);
        mValueText.setTextSize(32);
        params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.MATCH_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        layout.addView(mValueText, params);

        mSeekBar = new SeekBar(mContext);
        mSeekBar.setOnSeekBarChangeListener(this);
        layout.addView(mSeekBar, new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT));

        setProgressBarValue();

        return layout;
    }

    @Override
    protected void onPrepareDialogBuilder(AlertDialog.Builder builder) {
        // do not call super
    }

    private void setProgressBarValue() {
        String mValue = null;
        if (shouldPersist()) {
            mValue = getValue();
        }

        final int max = this.getEntries().length - 1;

        mSeekBar.setMax(max);
        mSeekBar.setProgress(this.findIndexOfValue(mValue));
    }

    @Override
    protected void onBindDialogView(View v) {
        super.onBindDialogView(v);
        setProgressBarValue();
    }

    @Override
    public void onProgressChanged(SeekBar seek, int value, boolean fromTouch) {
        final CharSequence textToDisplay = getEntryFromValue(value);
        mValueText.setText(textToDisplay);
    }

    private CharSequence getEntryFromValue(int value) {
        CharSequence[] entries = getEntries();
        return value >= 0 && entries != null ? entries[value] : null;
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
    }

    @Override
    public void showDialog(Bundle state) {
        super.showDialog(state);

        Button positiveButton = ((AlertDialog) getDialog()).getButton(AlertDialog.BUTTON_POSITIVE);
        positiveButton.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {

        if (shouldPersist()) {
            final int progressChoice = mSeekBar.getProgress();
            setValueIndex(progressChoice);
        }

        getDialog().dismiss();
    }
}

Использование в файле настроек теперь

<com.yourfullpackage.SeekBarListPreference
        android:defaultValue="0"
        android:dialogMessage="@string/time_limit_pref"
        android:entries="@array/timeListArray"
        android:entryValues="@array/timeListValues"
        android:key="time"
        android:summary="Select time limit"
        android:title="Time"
        />

И массивы

<string-array name="timeListArray">
    <item>10 Seconds</item>
    <item>30 Seconds</item>
    <item>1 Minute</item>
    <item>2 Minutes</item>
    <item>Unlimited</item>
</string-array>

<!--This is going to be in seconds-->
<string-array name="timeListValues">
    <item>10</item>
    <item>30</item>
    <item>60</item>
    <item>120</item>
    <item>0</item>
</string-array>

В качестве бонуса, если у вас уже есть ListPreferences, вам не нужно добавлять ничего лишнего, чтобы отобразить сводку как текущее значение. Так что это работает просто отлично

    @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    SetSummaryForPreferenceKey(key);
}

private void SetSummaryForPreferenceKey(String key) {
    Preference preference = findPreference(key);

    // This works with our new SeekBarPreference
    if (preference instanceof ListPreference) {
        ListPreference listPref = (ListPreference) preference;
        listPref.setSummary(listPref.getEntry());
    }
}

Ответ 6

Я немного улучшил код, указанный в ответе Тима. Это просто делает живые корректировки выходного значения, когда пользователь перемещает слайдер, вместо того, чтобы требовать от пользователя нажать кнопку "ОК" для внесения изменений.

Это полезно для таких вещей, как ползунок Music Volume, где пользователь должен иметь возможность слышать изменение громкости по мере его создания.

Если пользователь нажимает "ОК", новое значение сохраняется. Если пользователь нажимает "Отмена", тогда восстанавливается исходное значение предварительной настройки.

Спасибо, и кредит должен идти к Тиму, я просто добавил дополнительный слушатель onClick и нажал обновление значения в слушателе onChange.

package fr.atcm.carpooling.views.utils;

/* The following code was written by Matthew Wiggins 
 * and is released under the APACHE 2.0 license 
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Improvements :
 * - save the value on positive button click and/or seekbar change
 * - restore pre-adjustment value on negative button click
 */

import android.R;
import android.app.AlertDialog;
import android.content.Context;
import android.os.Bundle;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.SeekBar;
import android.widget.TextView;

public class SeekBarPreference extends DialogPreference implements
        SeekBar.OnSeekBarChangeListener, OnClickListener {
    // ------------------------------------------------------------------------------------------
    // Private attributes :
    private static final String androidns = "http://schemas.android.com/apk/res/android";

    private SeekBar mSeekBar;
    private TextView mSplashText, mValueText;
    private Context mContext;

    private String mDialogMessage, mSuffix;
    private int mDefault, mMax, mValue, mOrig = 0;

    // ------------------------------------------------------------------------------------------

    // ------------------------------------------------------------------------------------------
    // Constructor :
    public SeekBarPreference(Context context, AttributeSet attrs) {

        super(context, attrs);
        mContext = context;

        // Get string value for dialogMessage :
        int mDialogMessageId = attrs.getAttributeResourceValue(androidns,
                "dialogMessage", 0);
        if (mDialogMessageId == 0)
            mDialogMessage = attrs
                    .getAttributeValue(androidns, "dialogMessage");
        else
            mDialogMessage = mContext.getString(mDialogMessageId);

        // Get string value for suffix (text attribute in xml file) :
        int mSuffixId = attrs.getAttributeResourceValue(androidns, "text", 0);
        if (mSuffixId == 0)
            mSuffix = attrs.getAttributeValue(androidns, "text");
        else
            mSuffix = mContext.getString(mSuffixId);

        // Get default and max seekbar values :
        mDefault = attrs.getAttributeIntValue(androidns, "defaultValue", 0);
        mMax = attrs.getAttributeIntValue(androidns, "max", 100);
    }

    // ------------------------------------------------------------------------------------------

    // ------------------------------------------------------------------------------------------
    // DialogPreference methods :
    @Override
    protected View onCreateDialogView() {

        LinearLayout.LayoutParams params;
        LinearLayout layout = new LinearLayout(mContext);
        layout.setOrientation(LinearLayout.VERTICAL);
        layout.setPadding(6, 6, 6, 6);

        mSplashText = new TextView(mContext);
        mSplashText.setPadding(30, 10, 30, 10);
        if (mDialogMessage != null)
            mSplashText.setText(mDialogMessage);
        layout.addView(mSplashText);

        mValueText = new TextView(mContext);
        mValueText.setGravity(Gravity.CENTER_HORIZONTAL);
        mValueText.setTextSize(32);
        params = new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.FILL_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT);
        layout.addView(mValueText, params);

        mSeekBar = new SeekBar(mContext);
        mSeekBar.setOnSeekBarChangeListener(this);
        layout.addView(mSeekBar, new LinearLayout.LayoutParams(
                LinearLayout.LayoutParams.FILL_PARENT,
                LinearLayout.LayoutParams.WRAP_CONTENT));

        if (shouldPersist())
            mValue = getPersistedInt(mDefault);

        mSeekBar.setMax(mMax);
        mSeekBar.setProgress(mValue);

        return layout;
    }

    @Override
    protected void onBindDialogView(View v) {
        super.onBindDialogView(v);
        mSeekBar.setMax(mMax);
        mSeekBar.setProgress(mValue);
    }

    @Override
    protected void onSetInitialValue(boolean restore, Object defaultValue) {
        super.onSetInitialValue(restore, defaultValue);
        // Set adjustable value
        if (restore)
            mValue = shouldPersist() ? getPersistedInt(mDefault) : 0;
        else
            mValue = (Integer) defaultValue;
        // Set original pre-adjustment value
        mOrig = mValue;
    }

    // ------------------------------------------------------------------------------------------

    // ------------------------------------------------------------------------------------------
    // OnSeekBarChangeListener methods :
    @Override
    public void onProgressChanged(SeekBar seek, int value, boolean fromTouch) {
        String t = String.valueOf(value);
        mValueText.setText(mSuffix == null ? t : t.concat(" " + mSuffix));

        if (shouldPersist()) {
            mValue = mSeekBar.getProgress();
            persistInt(mSeekBar.getProgress());
            callChangeListener(Integer.valueOf(mSeekBar.getProgress()));
        }

    }

    @Override
    public void onStartTrackingTouch(SeekBar seek) {
    }

    @Override
    public void onStopTrackingTouch(SeekBar seek) {
    }

    public void setMax(int max) {
        mMax = max;
    }

    public int getMax() {
        return mMax;
    }

    public void setProgress(int progress) {
        mValue = progress;
        if (mSeekBar != null)
            mSeekBar.setProgress(progress);
    }

    public int getProgress() {
        return mValue;
    }

    // ------------------------------------------------------------------------------------------

    // ------------------------------------------------------------------------------------------
    // Set the positive button listener and onClick action : 
    @Override
    public void showDialog(Bundle state) {

        super.showDialog(state);

        Button positiveButton = ((AlertDialog) getDialog())
                .getButton(AlertDialog.BUTTON_POSITIVE);
        Button negativeButton = ((AlertDialog) getDialog())
                .getButton(AlertDialog.BUTTON_NEGATIVE);
        positiveButton.setOnClickListener(cListenPos);
        negativeButton.setOnClickListener(cListenNeg);
    }

    View.OnClickListener cListenPos = new View.OnClickListener() {
        public void onClick(View v) {
            if (shouldPersist()) {
                mValue = mSeekBar.getProgress();
                mOrig = mSeekBar.getProgress();
                persistInt(mSeekBar.getProgress());
                callChangeListener(Integer.valueOf(mSeekBar.getProgress()));
            }
            ((AlertDialog) getDialog()).dismiss();
        }
    };

    View.OnClickListener cListenNeg = new View.OnClickListener() {
        public void onClick(View v) {
            if (shouldPersist()) {
                mValue = mOrig;
                persistInt(mOrig);
                callChangeListener(Integer.valueOf(mOrig));
            }
            ((AlertDialog) getDialog()).dismiss();
        }
    };

    @Override
    public void onClick(View v) {}

    // ------------------------------------------------------------------------------------------
}

Ответ 7

Небольшое улучшение ответа Тима и его производных:

protected void onBindDialogView(View v) {
    super.onBindDialogView(v);
    mSeekBar.setMax(mMax);
    mSeekBar.setProgress(mValue);
    String t = String.valueOf(mValue);
    mValueText.setText(mSuffix == null ? t : t.concat(" " + mSuffix));
}

В начале будет заполнено текущее значение, которое в противном случае будет пустым, пока вы не сдвинете ползунок.

Ответ 8

Если вы уже перешли на androidX, вы можете просто использовать androidx.preference.SeekBarPreference. Документация здесь и здесь

Определите это в XML следующим образом:

<SeekBarPreference
        app:defaultValue="8"
        app:key="FAST_COUNT_SPEED"
        app:title="Fast count speed"
        />

Примечание: теперь в Android Studio (моя текущая версия 3.2.1) автоматические предложения не работают для androidx.preference.PreferenceScreen в prefs.xml, но не волнуйтесь, накачка настроек из xml с помощью setPreferencesFromResource() работает нормально. Все необходимые имена атрибутов и ссылки на компоненты вы можете найти здесь.