Comment ajouter un bouton à un PreferenceScreen?

135

Je suis assez nouveau dans le développement Android et je viens de tomber sur les préférences. J'ai trouvé PreferenceScreenet je voulais créer une fonctionnalité de connexion avec. Le seul problème que j'ai est que je ne sais pas comment je pourrais ajouter un bouton "Connexion" au fichier PreferenceScreen.

Voici à quoi mon PreferenceScreenressemble:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
...
    <PreferenceScreen android:title="@string/login" android:key="Login">
        <EditTextPreference android:persistent="true" android:title="@string/username" android:key="Username"></EditTextPreference>
        <EditTextPreference android:title="@string/password" android:persistent="true" android:password="true" android:key="Password"></EditTextPreference>
    </PreferenceScreen>
...
</PreferenceScreen>

Le bouton devrait être juste sous les deux EditTextPreferences.

Existe-t-il une solution simple à ce problème? La seule solution que j'ai trouvée ne fonctionnait pas car j'utilise des sous- PreferenceScreens.

Mettre à jour:

J'ai compris que je pouvais ajouter des boutons de cette façon:

<PreferenceScreen android:title="@string/login" android:key="Login">
        <EditTextPreference android:persistent="true" android:title="@string/username" android:key="Username"></EditTextPreference>
        <EditTextPreference android:title="@string/password" android:persistent="true" android:password="true" android:key="Password"></EditTextPreference>
        <Preference android:layout="@layout/loginButtons" android:key="loginButtons"></Preference>
</PreferenceScreen>

et le fichier de mise en page ( loginButtons.xml) ressemble à ceci:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_height="wrap_content"
    android:layout_width="fill_parent"
    android:weightSum="10" 
    android:baselineAligned="false" android:orientation="horizontal">
    <Button android:text="Login" android:layout_width="fill_parent"
        android:layout_weight="5" android:layout_height="wrap_content"
        android:id="@+id/loginButton" android:layout_gravity="left"></Button>
    <Button android:text="Password?" android:layout_width="fill_parent"
        android:layout_weight="5" android:layout_height="wrap_content"
        android:id="@+id/forgottenPasswordButton"></Button>
</LinearLayout>

Alors maintenant, les boutons apparaissent mais je ne peux pas y accéder dans le code. Je l'ai essayé avec findViewById()mais cela retourne null. Des idées sur la façon dont je pourrais accéder à ces boutons?

Van Naaktgeboren
la source
Regardez cette question stackoverflow.com/questions/2697233/…
Juozas Kontvainis
2
BTW, la réponse @neelabh est la plus simple - vous pouvez obtenir le comportement requis en spécifiant le gestionnaire d'événement dans la mise en page xml: ajoutez simplement android:onClick="method"à chaque bouton, où la méthode est définie dans l'activité comme public void method(View v).
Stan

Réponses:

304

Pour le xml:

<Preference android:title="Acts like a button"
                android:key="@string/myCoolButton"
                android:summary="This is a cool button"/>

Ensuite, pour le java dans votre onCreate()

Preference button = findPreference(getString(R.string.myCoolButton));
button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
                @Override
                public boolean onPreferenceClick(Preference preference) {   
                    //code for what you want it to do   
                    return true;
                }
            });

Cela apparaîtra comme une préférence normale, avec juste un titre et un résumé, donc il semblera qu'il appartient.

Edit: J'ai changé pour utiliser @string/myCoolButtonet getString(R.string.myCoolButton)parce qu'il est préférable d'utiliser des ressources pour l'assistance du compilateur, la traduction de la langue et la facilité des changements de chaîne.

Roseau
la source
7
De nombreuses applications google préchargées utilisent cette approche, et c'est donc une bonne idée de la suivre! J'ai trouvé qu'un bouton gris standard ne semble pas à sa place sur un écran de préférences, et grâce à vous, j'ai trouvé un bon moyen de le rendre standardisé :)
Tom
5
Assurez-vous que android:key="key"et findPreference("key");utilisez la même clé.
Reed
4
en fait, cela n'affiche pas du tout de bouton, ce qui déroutera l'utilisateur et n'est pas ce que l'OP a demandé. La bonne réponse pour montrer réellement un bouton est celle de Nicolas.
mutable2112
7
Je viens de remarquer que j'ai posté ceci en 2011 à 1:11. Haha.
Reed
3
J'aurais dû faire ça 1 mois et 11 jours plus tard: 11/1 / '11 - 1:11 :)
P Kuijpers
43

Je suppose qu'il est trop tard. C'est ce que j'ai fait pour une préférence de bouton.

La préférence dans le fichier preferences.xml dans le dossier xml

....
    <Preference
        android:key="resetBD"
        android:title="@string/ajustes_almacenamiento"
        android:summary="@string/ajustes_almacenamiento_desc"
        android:widgetLayout="@layout/pref_reset_bd_button" 
    ></Preference>
  ...

et pref_reset_bd_button.xml dans le dossier layout

 <?xml version="1.0" encoding="utf-8"?>
   <Button
       xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/resetButton" 
        android:text="@string/ajustes_almacenamiento_bt" 
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:onClick="resetearBD">

   </Button>
Nicolas
la source
android:widgetLayoutest la connexion parfaite entre les fragments et les préférences (l'une ou les deux définies en XML). Merci beaucoup. Ici
peter_the_oak
Salut @Nicolas. Votre code fonctionne, mais une question ... Comment pouvez-vous faire que le bouton fonctionne dans une classe qui étend PreferenceActivity
SP
4
Veuillez me dire comment trouver ce bouton avec l'ID "resetButton" merci!
Ben Jima
J'ai trouvé en utilisant android: layout supérieur à android: widgetLayout. En utilisant widgetLayout, mon bouton est devenu ce que je ne peux décrire que comme layout_alignParentRight = "true", mais ce comportement a disparu lors de l'utilisation d'android: layout à la place
JoeHz
1
Et je ne peux pas obtenir cela pour déclencher un gestionnaire d'événements onPreferenceChange ou Click
JoeHz
38

Je voulais ajouter un lien de sortie aux préférences et j'ai pu modifier le code de Jakar pour qu'il fonctionne comme ceci:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >   
   <PreferenceCategory android:title="Settings">
       <Preference android:title="Click to exit" android:key="exitlink"/>       
   </PreferenceCategory>    
</PreferenceScreen>

À l'origine, la «préférence» était un «EditTextPreference» que j'ai édité à la main.

Puis dans la classe:

public class MyPreferences extends PreferenceActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    addPreferencesFromResource(R.xml.mypreferences);

    Preference button = (Preference)getPreferenceManager().findPreference("exitlink");      
    if (button != null) {
        button.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
            @Override
            public boolean onPreferenceClick(Preference arg0) {
                finish();   
                return true;
            }
        });     
    }
}
}
Dunfield
la source
3
Fonctionne très bien. C'est brillant !
RRTW
8

Ajouter

setContentView(R.layout.buttonLayout);

Au dessous de

addPreferencesFromResource(R.xml.yourPreference);

disposition des boutons:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

<RelativeLayout
        android:id="@+id/top_control_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
</RelativeLayout>

<LinearLayout
        android:id="@+id/bottom_control_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true">

    <Button
            android:id="@+id/button"
            android:layout_width="match_parent"
            android:layout_height="70dp"
            android:text="@string/saveAlarm"/>
</LinearLayout>

<ListView
        android:id="@android:id/list"
        android:layout_width="fill_parent"
        android:layout_height="0dip"
        android:layout_above="@id/bottom_control_bar"
        android:layout_below="@id/top_control_bar"
        android:choiceMode="multipleChoice">
</ListView>

Bouton d'accès par:

Button button = (Button) findViewById(R.id.button);
button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        //Your event
    }
});

Vous pouvez obtenir le bouton en haut ou en bas de l'écran en mettant le bouton dans RelativeLayout:

  • top_control_bar
  • bottom_control_bar

bottom_control_bar

Cela a fonctionné pour moi. J'espère pouvoir aider quelqu'un avec ce morceau de code.

Thijs Limmen
la source
Je l'ai utilisé dans mon application, il garde le bouton en haut de la liste, ce qui est meilleur et plus convivial pour les boutons OK et Annuler. Je vous remercie.
Grux
1

Je ne pense pas qu'il existe un moyen facile d'ajouter simplement un bouton à un écran de préférences. Les préférences sont limitées à:

EditTextPreference
ListPreference
RingtonePreference
CheckboxPreference

Lorsque vous utilisez un écran de préférence, vous êtes limité à l'utilisation de ces options, et il n'y a pas de "préférence de bouton" unique qui pourrait être facilement utilisée pour vos besoins.

J'ai recherché des fonctionnalités similaires, avec l'ajout de boutons à l'écran des préférences, mais il semble que vous deviez créer votre propre écran pour cela, en gérant le changement des préférences dans votre propre implémentation.

Eric Nordvik
la source
J'ai eu le même problème, si vous voulez un bouton dans vos préférences, vous devez utiliser un écran de préférence fait par vous-même :(
Janusz
1

Vous pouvez le faire comme ceci pour accéder au bouton!

 View footerView = ((LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE)).inflate(R.layout.layoutButtons, null, false);

N'oubliez pas d'ajouter android:idau LinearLayout qui contient le bouton dans layoutButtons.xml , ie android:id="@+id/mylayout"

 LinearLayout mLayout = (LinearLayout) footerView.findViewById(R.id.mylayout);
 Button login = (Button) footerView.findViewById(R.id.loginButton);
 login.setOnClickListener(this);
 ListView lv = (ListView) findViewById(android.R.id.list);
 lv.addFooterView(footerView);

 // Lines 2 and 3 can be used in the same way for a second Button!
Shah
la source
N'oubliez pas de marquer cette question comme VRAI si vous sentez que je vous ai aidé?
Shah
0

Vous pouvez également personnaliser la mise en page d'une préférence en la remplaçant Preference.onCreateView(parent). L'exemple ci-dessous utilise une classe interne anonyme pour créer des préférences rouges.

    screen.addPreference(
        new Preference(context) {
            @Override
            protected View onCreateView(ViewGroup parent) {
                View view = super.onCreateView(parent);
                view.setBackgroundColor(Color.RED);
                return view;
            }
        });

Vous pouvez utiliser cette technique pour ajouter un bouton à la vue par défaut.

Roger Keays
la source
0

Si quelqu'un vient demander à l'utilisateur de cliquer sur l'un des éléments et des poignées de préférences sur lesquels vous cliquez et sur lequel votre solution est basée PreferenceFragmentCompat, vous pouvez le faire:

<PreferenceScreen
...
>
...
<Preference
    android:key="@string/pref_key_clickable_item"
    android:persistent="false"
    android:title="Can be clicked"
    android:summary="Click this item so stuff will happen"/>
...
</PreferenceScreen>

Java:

@Override
onPreferenceTreeClick(Preference preference) {
    if (preference.getKey().equals(getContext().getString(R.string.pref_key_clickable_item))) {
       // user clicked the item
       // return "true" to indicate you handled the click
       return true;
    }
    return false;
}

Kotlin:

override fun onPreferenceTreeClick(preference: Preference): Boolean {
    if (preference.key == context?.getString(R.string.pref_key_clickable_ite)) {
       // user clicked the item
       // return "true" to indicate you handled the click
       return true
    }
    return false
}
Csaba Toth
la source
0

Créez une mise en page personnalisée pour l' SettingsFragment.javaIElayout_settings.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".ui.settings.SettingsFragment"
    tools:ignore="NewApi">

    <com.google.android.material.appbar.AppBarLayout
        android:id="@+id/appBarSettings"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:theme="@style/AppBarOverlay">

        <com.google.android.material.appbar.MaterialToolbar
            android:id="@+id/toolbarSettings"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:minHeight="?attr/actionBarSize"
            app:title="@string/fragment_title_settings" />
    </com.google.android.material.appbar.AppBarLayout>

    <!--this works as the container for the SettingsFragment.java
    put the code for the Button above or below this FrameLayout
    according to your requirement-->

    <FrameLayout
        android:id="@android:id/list_container"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
      app:layout_behavior="com.google.android.material.appbar.AppBarLayout$ScrollingViewBehavior" />


    <com.google.android.material.button.MaterialButton
        android:id="@+id/btnSample"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="bottom|center"
        android:text="@string/button_sample_text" />

</androidx.coordinatorlayout.widget.CoordinatorLayout>

Ensuite, reportez-vous au fichier de mise en page dans votre styles.xml:

<style name="AppTheme" parent="....">
      ...............
      ...............
      <item name="preferenceTheme">@style/MyPreferenceThemeOverlay</item>
</style>

<style name="MyPreferenceThemeOverlay" parent="PreferenceThemeOverlay">
      <item name="android:layout>@layout/layout_settings</item>
</style>

Et puis, dans la onViewCreated()méthode de votre SettingsFragment.java, vous pouvez utiliser le bouton comme ceci:

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle 
                             savedInstanceState) {

        MaterialButton btnSample = view.findViewById(R.id.btnSample);
        btnSample.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Toast.makeText(requireContext(), "Sample Button 
                   clicked!!", Toast.LENGTH_LONG).show();
            }
        });
    }

Exemple d'écran des paramètres avec bouton

cgb_pandey
la source
-1

essayez android: onClick = "myMethod" fonctionne comme un charme pour les événements onclick simples

neelabh
la source
4
Preferencen'a pas de onClickpropriété
ercan
La réponse implique android:onClickdans la vue des boutons attachée, pas dans la préférence elle-même.
Stan