Curseur sur mon écran de préférence

Je veux que mon menu de préférences ait quelque chose qui change la durée d’une vibration.

Il n’y a pas de tag slider pour prefs.xml, alors quelle est la meilleure façon de le faire?

Vous pouvez créer votre propre classe Preference qui étend DialogPreference et affiche un SeekBar en tant que vue de dialog.

J’ai amélioré le lien fourni par Macarse, de sorte que la valeur est enregistrée uniquement avec le clic sur le bouton ok, et que vous puissiez utiliser les valeurs @ssortingng/... dans le fichier XML.

Voici le 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 @ssortingng/... 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.AtsortingbuteSet; 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 atsortingbutes : private static final Ssortingng androidns="http://schemas.android.com/apk/res/android"; private SeekBar mSeekBar; private TextView mSplashText,mValueText; private Context mContext; private Ssortingng mDialogMessage, mSuffix; private int mDefault, mMax, mValue = 0; // ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------ // Constructor : public SeekBarPreference(Context context, AtsortingbuteSet attrs) { super(context,attrs); mContext = context; // Get ssortingng value for dialogMessage : int mDialogMessageId = attrs.getAtsortingbuteResourceValue(androidns, "dialogMessage", 0); if(mDialogMessageId == 0) mDialogMessage = attrs.getAtsortingbuteValue(androidns, "dialogMessage"); else mDialogMessage = mContext.getSsortingng(mDialogMessageId); // Get ssortingng value for suffix (text atsortingbute in xml file) : int mSuffixId = attrs.getAtsortingbuteResourceValue(androidns, "text", 0); if(mSuffixId == 0) mSuffix = attrs.getAtsortingbuteValue(androidns, "text"); else mSuffix = mContext.getSsortingng(mSuffixId); // Get default and max seekbar values : mDefault = attrs.getAtsortingbuteIntValue(androidns, "defaultValue", 0); mMax = attrs.getAtsortingbuteIntValue(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) { Ssortingng t = Ssortingng.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(); } // ------------------------------------------------------------------------------------------ } 

MODIFIER :

Voici une capture d’écran:

Capture d'écran SeekBarPreference

EDIT: à la demande d’Arlomedia, voici toutes les parties de code nécessaires (je viens de recréer un nouveau projet, il fonctionne parfaitement. J’ai corrigé quelques bugs dans la classe SeekBarPreference, alors n’oubliez pas de le copier / coller):

Activité principale :

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

ParamètresActivité:

 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.getSsortingng(R.ssortingng.settings_summary).replace("$1", ""+radius)); } @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Ssortingng key) { // Set seekbar summary : int radius = PreferenceManager.getDefaultSharedPreferences(this.getActivity()).getInt("SEEKBAR_VALUE", 50); _seekBarPref.setSummary(this.getSsortingng(R.ssortingng.settings_summary).replace("$1", ""+radius)); } } } 

layout> activity_main.xml:

    

menu> main.xml:

    

xml> activity_settings.xml:

     

valeurs> ssortingngs.xml:

   TestSliderPref SeekBarPreference test Settings Here comes a message Current value is $1 Km Here comes the title  

N’oubliez pas d’append votre SettingsActivity au manifeste et cela devrait être OK.

Un moyen simple d’y parvenir est d’append une préférence vide à votre preferences.xml qui utilise une disposition incluant une barre de recherche.

Dans votre preferences.xml add

  

sous les dispositions append le sliderlayout

     

Ceci est un bon composant de préférence Slider – Bibliothèque de préférences de Slider Android entrer la description de l'image ici

https://github.com/jayschwa/AndroidSliderPreference

Une autre implémentation de ceci. Tout le crédit va à Tim Autin.

Je voulais que les valeurs affichées soient chargées à partir de tableaux XML

Ça ressemble à ça

Paramètre Seekbar chargeant des éléments à partir de XML

Code – cela étend maintenant ListPreference

 import android.app.AlertDialog; import android.content.Context; import android.os.Bundle; import android.preference.ListPreference; import android.util.AtsortingbuteSet; 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 atsortingbutes : private static final Ssortingng androidns = "http://schemas.android.com/apk/res/android"; private SeekBar mSeekBar; private TextView mSplashText, mValueText; private Context mContext; private Ssortingng mDialogMessage; // ------------------------------------------------------------------------------------------ public SeekBarListPreference(Context context, AtsortingbuteSet attrs) { super(context, attrs); mContext = context; // Get ssortingng value for dialogMessage : int mDialogMessageId = attrs.getAtsortingbuteResourceValue(androidns, "dialogMessage", 0); if (mDialogMessageId == 0) mDialogMessage = attrs.getAtsortingbuteValue(androidns, "dialogMessage"); else mDialogMessage = mContext.getSsortingng(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() { Ssortingng mValue = null; if (shouldPersist()) { mValue = getValue(); } final int max = this.getEnsortinges().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[] ensortinges = getEnsortinges(); return value >= 0 && ensortinges != null ? ensortinges[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(); } } 

L’utilisation dans le fichier de préférences est maintenant

  

Et les tableaux

  10 Seconds 30 Seconds 1 Minute 2 Minutes Unlimited    10 30 60 120 0  

En bonus, si vous avez déjà des ListPreferences, vous n’avez rien à append pour afficher le résumé en tant que valeur actuelle. Donc ça marche très bien

  @Override public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, Ssortingng key) { SetSummaryForPreferenceKey(key); } private void SetSummaryForPreferenceKey(Ssortingng key) { Preference preference = findPreference(key); // This works with our new SeekBarPreference if (preference instanceof ListPreference) { ListPreference listPref = (ListPreference) preference; listPref.setSummary(listPref.getEntry()); } } 

J’ai légèrement amélioré le code fourni dans la réponse de Tim. Cela permet simplement d’ajuster en direct la valeur de sortie lorsque l’utilisateur déplace le curseur, plutôt que de demander à l’utilisateur de cliquer sur le bouton “OK” pour effectuer les modifications.

Ceci est utile pour des choses comme un curseur de volume de musique, où l’utilisateur doit pouvoir entendre le réglage du volume au fur et à mesure de sa création.

Si l’utilisateur clique sur “OK”, la nouvelle valeur est maintenue. Si l’utilisateur clique sur “Annuler”, la valeur de pré-ajustement d’origine est restaurée.

Merci et crédit devrait aller à Tim, j’ai juste ajouté l’auditeur supplémentaire onClick et poussé la mise à jour de la valeur dans l’auditeur 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.AtsortingbuteSet; 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 atsortingbutes : private static final Ssortingng androidns = "http://schemas.android.com/apk/res/android"; private SeekBar mSeekBar; private TextView mSplashText, mValueText; private Context mContext; private Ssortingng mDialogMessage, mSuffix; private int mDefault, mMax, mValue, mOrig = 0; // ------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------ // Constructor : public SeekBarPreference(Context context, AtsortingbuteSet attrs) { super(context, attrs); mContext = context; // Get ssortingng value for dialogMessage : int mDialogMessageId = attrs.getAtsortingbuteResourceValue(androidns, "dialogMessage", 0); if (mDialogMessageId == 0) mDialogMessage = attrs .getAtsortingbuteValue(androidns, "dialogMessage"); else mDialogMessage = mContext.getSsortingng(mDialogMessageId); // Get ssortingng value for suffix (text atsortingbute in xml file) : int mSuffixId = attrs.getAtsortingbuteResourceValue(androidns, "text", 0); if (mSuffixId == 0) mSuffix = attrs.getAtsortingbuteValue(androidns, "text"); else mSuffix = mContext.getSsortingng(mSuffixId); // Get default and max seekbar values : mDefault = attrs.getAtsortingbuteIntValue(androidns, "defaultValue", 0); mMax = attrs.getAtsortingbuteIntValue(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) { Ssortingng t = Ssortingng.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) {} // ------------------------------------------------------------------------------------------ } 

Une petite amélioration de la réponse de Tim et de ses dérivés:

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

Il va renseigner la valeur courante au début, qui est vide sinon vous faites glisser le curseur.