2009-12-29 66 views
37

我希望我的偏好菜单有一些东西来改变振动的持续时间。我的偏好屏幕上的滑块

prefs.xml没有slider标签,那么最好的方法是什么?

+6

这似乎是相当不错的http://robobunny.com/wp/2011/08/13/android-seekbar-preference/ – Kuitsi 2012-10-06 10:34:53

+0

检查出我的内联(无对话框)SeekBarPreference这里:http://stackoverflow.com/questions/9/is-there-a-way-to-add-a-seekbar-to-my-actual-preference-screen/30236143#30236143 – 2015-05-14 18:17:15

回答

19

您可以创建自己的首选项类,该类延伸DialogPreference并显示SeekBar作为对话框视图。

+3

链接不再可用。 – m0skit0 2013-02-27 15:35:18

+2

使用对话框并不总是最好的选择,如果你有几个滑块并且希望看到它们彼此相邻,那该怎么办? – gatopeich 2013-11-17 08:35:06

+1

有没有办法将滑块直接放在屏幕上? – theblang 2014-01-28 20:15:33

38

我改进了由Macarse提供的链接,以便仅在ok按钮单击时保存该值,以便您可以在XML文件中使用@string/...值。

下面是代码:

/* 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

编辑:于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's 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)); 
     } 
    } 
} 

布局> 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> 

菜单> 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> 

值>的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添加到清单中,它应该没问题。

+0

这是否应该显示对话框中的滑块,或正确的偏好页面?代码看起来像使用对话框,但是当我实现它时,滑块位于首选项页面上。 – arlomedia 2014-02-21 18:49:11

+0

另外,你可以添加一个安装XML代码片段来显示类正在寻找的值吗? – arlomedia 2014-02-21 18:50:10

+0

嗨。是的,这个前提是可点击的,并打开一个弹出窗口。我添加了一个XML片段和一个快照。 – 2014-02-21 23:46:29

7

这是一个好滑块组件偏好 - Android的滑块偏好图书馆 enter image description here

https://github.com/jayschwa/AndroidSliderPreference

+1

来解决我的问题,我只是将其添加到我的项目中。它将该值存储为0-1的浮点数,这是我想要的,但可能不是您想要的。此外,它使用一个单独的布局文件,与从类代码构建布局的解决方案相比,该布局文件的自包含性较差。 – arlomedia 2014-02-21 19:42:53

+1

这是一段让我绊倒的东西:这个库将这个值保存为一个浮点数,并且如果您之前已经将您的值保存为int,则会在运行时崩溃。在这种情况下,您需要清除先前的值,或更新应用以在运行首选项活动之前转换该值的类型。 – arlomedia 2014-02-22 00:07:40

15

一个简单的方法来实现,这是一个空的喜好添加到您的preferences.xml它使用的布局,包括搜索条。

在你的preferences.xml添加

<Preference android:layout="@layout/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> 
+0

启示录!谢谢@AndreasSchwander! – 2016-04-29 06:11:28

1

我已在由Tim答案提供的代码略有改善的sliderlayout。这只需在用户移动滑块时对输出值进行实时调整,而不是要求用户单击“确定”按钮才能进行更改。

这对像音乐音量滑块这样的东西很有用,用户应该能够在音量调整时听到音量调整。

如果用户单击“确定”,则会保留新值。如果用户点击“取消”,则恢复原始的预调节值。

感谢和信任应该去蒂姆,我只是增加了额外的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) {} 

    // ------------------------------------------------------------------------------------------ 
} 
+0

我只是想知道你是如何去捕捉滑动条实时调整的。我应该实现OnSharedPreferenceChangeListener?但是你写道,确定按钮将持续最终的价值。 – 2016-06-14 05:10:30

2

另外还有一个这样的实现。所有的积分都归Tim Autin所有。

我想有显示的值从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()); 
    } 
} 
+0

我如何存储价值并通过SharedPreference返回? – 2017-12-31 17:21:51

1

一个小的改进添的回答及其衍生物的:

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)); 
} 

这将填充在启动电流值,直到你真正滑动滑块,否则空。