Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Slider on my PreferenceScreen

Tags:

android

I want my preference menu to have something to change the duration of a vibration.

There is no slider tag for prefs.xml, so what is the best way to do this?

like image 653
Macarse Avatar asked Dec 29 '09 11:12

Macarse


People also ask

What is Preferences screen?

This settings screen is used to manage the preferences of the users. For creating this settings screen android provides a feature to make a settings preferences screen. In this article, we will take a look at implementing the preferences setting screen in Android.

What is Preference button?

Android shared preference is used to store and retrieve primitive information.

Where are preferences in Android Studio?

From the menu bar, click File > Settings (on macOS, click Android Studio > Preferences).

What are preferences in Android?

Preferences in Android are used to keep track of application and user preferences. In any application, there are default preferences that can accessed through the PreferenceManager instance and its related method getDefaultSharedPreferences(Context)


2 Answers

I improved the link provided by Macarse, so that the value is saved only on ok button click, and so that you can use @string/... values in the XML file.

Here is the code:

/* 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();     }     // ------------------------------------------------------------------------------------------ } 

EDIT :

Here is a screenshot :

Screenshot SeekBarPreference

EDIT : on arlomedia's demand, here are all the needed pieces of code (I just recreated a new projet, it is perfectly working. I corrected some bugs in SeekBarPreference class, so don't forget to re-copy/paste it) :

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

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> 

Don't forget to add your SettingsActivity to the manifest, and it should be OK.

like image 151
Tim Autin Avatar answered Sep 17 '22 14:09

Tim Autin


You could create your own Preference class that extends DialogPreference and shows a SeekBar as the dialog view.

like image 36
Mirko N. Avatar answered Sep 18 '22 14:09

Mirko N.