Est-il possible de créer une préférence individuelle dans un PreferenceScreen
?
Je voudrais coder les paramètres de couleur comme ça:
Je sais que le choix de la couleur est facile à réaliser avec le ListPreference
, mais ce serait génial avec ce genre de "cases à cocher".
La page Android Developer montre uniquement comment créer un DialogFragment
. Il est toujours possible de personnaliser l'apparence d'un élément Preference
. Dans votre XML, vous devez déclarez l'élément racine comme Android:id="@Android:id/widget_frame
, puis déclarez TextView
comme Android:title
et Android:summary
. Vous pouvez ensuite déclarer les autres éléments que vous souhaitez voir apparaître dans la mise en page. Voici un exemple montrant un SeekBar
que vous pourriez facilement adapter à un sélecteur de couleurs à plusieurs cases à cocher.
seekbar_preference.xml
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:id="@Android:id/widget_frame"
Android:layout_width="match_parent"
Android:layout_height="match_parent"
Android:orientation="vertical" >
<TextView
Android:id="@Android:id/title"
style="@Android:style/TextAppearance.DeviceDefault.SearchResult.Title"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Title" />
<TextView
Android:id="@Android:id/summary"
style="@Android:style/TextAppearance.DeviceDefault.SearchResult.Subtitle"
Android:layout_width="wrap_content"
Android:layout_height="wrap_content"
Android:text="Summary" />
<SeekBar
Android:id="@+id/seekbar"
Android:layout_width="match_parent"
Android:layout_height="wrap_content" />
</LinearLayout>
Ensuite, dans une classe qui dérive de Preference
, remplacez la méthode onCreateView()
:
SeekbarPreference.Java
@Override
protected View onCreateView( ViewGroup parent )
{
LayoutInflater li = (LayoutInflater)getContext().getSystemService( Context.LAYOUT_INFLATER_SERVICE );
return li.inflate( R.layout.seekbar_preference, parent, false);
}
Ensuite, dans le fichier preferences.xml, utilisez la préférence:
preferences.xml
<PreferenceScreen xmlns:Android="http://schemas.Android.com/apk/res/Android" >
<com.example.SeekbarPreference
Android:key="pref_max_volume"
Android:title="@string/max_volume" />
<com.example.SeekbarPreference
Android:key="pref_balance"
Android:title="@string/balance" />
</PreferenceScreen>
Cela donne une préférence qui se présente comme suit:
Vous pouvez facilement adapter cette méthode pour afficher plusieurs cases à cocher sur une ligne comme c'était le cas dans la question d'origine.
Voici comment je le fais, en utilisant la bibliothèque de support preference-v7
.
Preference
et remplacez onBindViewHolder()
. Cette méthode vous permet d'obtenir des références à la vue de vos préférences via l'objet ViewHolder
.setWidgetLayoutResource()
ou setLayoutResource()
dans le constructeur.layout/preference_theme.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:Android="http://schemas.Android.com/apk/res/Android"
Android:orientation="horizontal"
Android:layout_width="match_parent"
Android:layout_height="wrap_content">
<Button Android:id="@+id/theme_light" ... />
<Button Android:id="@+id/theme_dark"... />
<Button Android:id="@+id/theme_sepia"... />
<Button Android:id="@+id/theme_green"... />
</LinearLayout>
PreferenceTheme.Java (classe de préférence personnalisée)
import Android.support.v7.preference.Preference;
import Android.support.v7.preference.PreferenceViewHolder;
public class PreferenceTheme extends Preference {
public PreferenceTheme(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public PreferenceTheme(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
setWidgetLayoutResource(R.layout.preference_theme);
}
@Override
public void onBindViewHolder(PreferenceViewHolder holder) {
super.onBindViewHolder(holder);
holder.itemView.setClickable(false); // disable parent click
View button = holder.findViewById(R.id.theme_dark);
button.setClickable(true); // enable custom view click
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// persist your value here
}
});
// the rest of the click binding
}
}
preferences.xml
<?xml version="1.0" encoding="utf-8"?>
<Android.support.v7.preference.PreferenceScreen xmlns:Android="http://schemas.Android.com/apk/res/Android"
xmlns:app="http://schemas.Android.com/apk/res-auto"
Android:layout_width="match_parent"
Android:layout_height="match_parent">
<Android.support.v7.preference.PreferenceCategory
Android:title="Reading">
<example.com.preference.PreferenceTheme
Android:key="pref_theme"
Android:title="Theme"
Android:defaultValue="light" />
...
</Android.support.v7.preference.PreferenceCategory>
</Android.support.v7.preference.PreferenceScreen>
La création d'une préférence personnalisée est similaire à la création d'un fragment ou d'autres composants d'interface utilisateur, en définissant des vues et des actions.
Les développeurs Android ont un bon guide sur la création de paramètres, qui comprend une section pour créer des préférences personnalisées: http://developer.Android.com/guide/topics/ui/settings.html#Custom
Vous pouvez créer votre mise en page personnalisée de préférence et vous pouvez la définir dans Android:layout
attribut dans Préférence en res/xml comme ceci:
<Preference
......................
Android:layout="@layout/your_layout" />
Ou vous pouvez utiliser une activité au lieu de préférence
Ou une meilleure alternative sera d'étendre la classe DialogPreference. Vous pouvez définir un widget sélecteur de couleurs comme vue de dialogue et obtenir le résultat positif dans la préférence étendue elle-même. Ici est une question similaire, mais elle est très utile pour votre scénario.