Wie füge ich einem PreferenceScreen eine Schaltfläche hinzu?

135

Ich bin ziemlich neu in der Android-Entwicklung und bin gerade auf Einstellungen gestoßen. Ich fand PreferenceScreenund wollte damit eine Login-Funktionalität erstellen. Das einzige Problem, das ich habe, ist, dass ich nicht weiß, wie ich der Schaltfläche "Anmelden" hinzufügen kann PreferenceScreen.

So PreferenceScreensieht mein aus:

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

Der Knopf sollte direkt unter den beiden EditTextPreferences sein.

Gibt es eine einfache Lösung für dieses Problem? Die einzige Lösung, die ich gefunden habe, hat nicht funktioniert, weil ich Sub- PreferenceScreens verwende.

Aktualisieren:

Ich habe herausgefunden, dass ich Schaltflächen folgendermaßen hinzufügen kann:

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

und die Layoutdatei ( loginButtons.xml) sieht folgendermaßen aus:

<?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>

Jetzt erscheinen die Schaltflächen, aber ich kann nicht im Code darauf zugreifen. Ich habe es mit versucht, findViewById()aber dies gibt null zurück. Irgendwelche Ideen, wie ich auf diese Schaltflächen zugreifen könnte?

Van Naaktgeboren
quelle
Schauen Sie sich diese Frage an stackoverflow.com/questions/2697233/…
Juozas Kontvainis
2
Übrigens, die Antwort von @neelabh ist am einfachsten - Sie können das erforderliche Verhalten erreichen, indem Sie im XML-Layout den Ereignishanderer angeben: Fügen Sie einfach android:onClick="method"zu jeder Schaltfläche hinzu, wobei die Methode in der Aktivität als definiert ist public void method(View v).
Stan

Antworten:

304

Für die XML:

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

Dann für die Java in Ihrem 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;
                }
            });

Dies wird wie eine normale Voreinstellung mit nur einem Titel und einer Zusammenfassung angezeigt, sodass es so aussieht, als ob es dazu gehört.

Bearbeiten: Ich habe die Verwendung geändert @string/myCoolButtonund getString(R.string.myCoolButton)weil es am besten ist, Ressourcen für die Compilerunterstützung, die Sprachübersetzung und die einfache Änderung von Zeichenfolgen zu verwenden.

Schilf
quelle
7
Viele der vorinstallierten Google Apps verwenden diesen Ansatz, und daher ist es eine gute Idee, dem zu folgen! Ich habe festgestellt, dass eine graue Standardschaltfläche auf einem Einstellungsbildschirm fehl am Platz ist, und dank Ihnen habe ich eine gute Möglichkeit gefunden, sie standardisiert aussehen zu lassen :)
Tom
5
Stellen Sie sicher, dass android:key="key"und findPreference("key");verwenden Sie den gleichen Schlüssel.
Reed
4
Tatsächlich wird hier überhaupt keine Schaltfläche angezeigt, was den Benutzer verwirrt und nicht den Anforderungen des OP entspricht. Die richtige Antwort, um tatsächlich einen Knopf zu zeigen, ist die von Nicolas.
mutable2112
7
Mir ist gerade aufgefallen, dass ich dies 2011 um 1:11 gepostet habe. Haha.
Reed
3
Hätte das 1 Monat und 11 Tage später tun sollen: 11/1 / '11 - 1:11 :)
P Kuijpers
43

Ich nehme an, es ist zu spät. Dies ist, was ich für eine Schaltflächeneinstellung getan habe.

Die Voreinstellung in der Datei "Preference.xml" im XML-Ordner

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

und pref_reset_bd_button.xml im Layoutordner

 <?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
quelle
android:widgetLayoutist die perfekte Verbindung zwischen Fragmenten und und Einstellungen (eines oder beide in XML definiert). Vielen Dank. Hier
peter_the_oak
Hallo @Nicolas. Ihr Code funktioniert, aber eine Frage ... Wie können Sie das tun? Die Schaltfläche funktioniert in einer Klasse, die PreferenceActivity
SP
4
Bitte sagen Sie mir, wie ich diesen Button mit der ID "resetButton" finde, danke!
Ben Jima
Ich fand die Verwendung von Android: Layout besser als Android: WidgetLayout. Mit widgetLayout wurde meine Schaltfläche zu dem, was ich nur als layout_alignParentRight = "true" beschreiben kann, aber dieses Verhalten verschwand, wenn stattdessen android: layout verwendet wurde
JoeHz
1
Und ich kann dies nicht dazu bringen, einen onPreferenceChange- oder Click-Ereignishandler
auszulösen
38

Ich wollte den Einstellungen einen Exit-Link hinzufügen und konnte den Code von Jakar so ändern, dass er wie folgt funktioniert:

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

Ursprünglich war die 'Präferenz' eine 'EditTextPreference', die ich von Hand bearbeitet habe.

Dann in der Klasse:

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
quelle
3
Funktioniert super. Das ist hervorragend !
RRTW
8

Hinzufügen

setContentView(R.layout.buttonLayout);

Unten

addPreferencesFromResource(R.xml.yourPreference);

buttonLayout:

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

Zugriffstaste von:

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

Sie können die Schaltfläche oben oder unten auf dem Bildschirm anzeigen, indem Sie die Schaltfläche in RelativeLayout einfügen:

  • top_control_bar
  • bottom_control_bar

bottom_control_bar

Das hat bei mir funktioniert. Ich hoffe, ich kann jemandem mit diesem Code helfen.

Thijs Limmen
quelle
Ich habe dies in meiner App verwendet. Dadurch bleibt die Schaltfläche ganz oben auf der Liste, was besser aussieht und für die Schaltflächen OK und Abbrechen benutzerfreundlicher ist. Danke dir.
Grux
1

Ich glaube nicht, dass es eine einfache Möglichkeit gibt, einem Einstellungsbildschirm einfach eine Schaltfläche hinzuzufügen. Die Einstellungen sind beschränkt auf:

EditTextPreference
ListPreference
RingtonePreference
CheckboxPreference

Während Sie einen Einstellungsbildschirm verwenden, können Sie diese Optionen nur verwenden, und es gibt keine einzige "Schaltflächeneinstellung", die für Ihre Anforderungen problemlos verwendet werden könnte.

Ich habe nach ähnlichen Funktionen gesucht, indem ich dem Einstellungsbildschirm Schaltflächen hinzugefügt habe, aber es scheint, als müssten Sie dafür einen eigenen Bildschirm erstellen und die Änderung der Einstellungen in Ihrer eigenen Implementierung verwalten.

Eric Nordvik
quelle
Hatte das gleiche Problem, wenn Sie eine Schaltfläche in Ihren Einstellungen möchten, müssen Sie einen selbst erstellten Voreinstellungsbildschirm verwenden :(
Janusz
1

Sie können dies so tun, um auf die Schaltfläche zuzugreifen!

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

Vergessen Sie nicht android:id, dem LinearLayout hinzuzufügen , das die Schaltfläche in layoutButtons.xml enthält , d. H.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!
Schah
quelle
Vergessen Sie nicht, diese Frage als WAHR zu markieren, wenn Sie das Gefühl haben, ich habe Ihnen dabei geholfen?
Shah
0

Sie können das Layout einer Voreinstellung auch durch Überschreiben anpassen Preference.onCreateView(parent). Im folgenden Beispiel wird eine anonyme innere Klasse verwendet, um rote Einstellungen vorzunehmen.

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

Mit dieser Technik können Sie der Standardansicht eine Schaltfläche hinzufügen.

Roger Keays
quelle
0

Wenn jemand den Benutzer anweist, auf eines der Einstellungselemente und Handles zu klicken, auf die geklickt wird und auf denen Ihre Lösung basiert PreferenceFragmentCompat, können Sie Folgendes tun:

<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
quelle
0

Erstellen Sie ein benutzerdefiniertes Layout für die SettingsFragment.javadhlayout_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>

Lesen Sie dann die Layoutdatei in Ihrem 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>

Und dann können Sie in onViewCreated()Ihrer Methode SettingsFragment.javadie Schaltfläche folgendermaßen verwenden:

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

Beispieleinstellungsbildschirm mit Schaltfläche

cgb_pandey
quelle
-1

try android: onClick = "myMethod" funktioniert wie ein Zauber für einfache Onclick-Ereignisse

neelabh
quelle
4
Preferencehat kein onClickEigentum
ercan
Die Antwort impliziert android:onClickin der angehängten Schaltflächenansicht, nicht in der Einstellung selbst.
Stan