So fügen Sie PreferenceScreen eine Schaltfläche hinzu

106

Gibt es eine Möglichkeit, am unteren Rand des Einstellungsbildschirms eine Schaltfläche hinzuzufügen, damit diese beim Scrollen korrekt funktioniert?

vlaku
quelle
2
Haben Sie sich überlegt, eine benutzerdefinierte Einstellung zu erstellen?
Prashast
2
Für zukünftige Besucher gibt es, während Max 'Lösung funktioniert, eine alternative Lösung: stackoverflow.com/a/7251575/802469
Reed

Antworten:

249

Es gibt eine andere Lösung zum Anpassen des Erscheinungsbilds der Einstellungen.

Entwerfen Sie ein normales XML-Layout mit Schaltflächen oder was auch immer Sie zu den Standardeinstellungen hinzufügen möchten. Fügen Sie ein ListViewin Ihr Layout ein und geben Sie ihm die ID @android:id/list.

Angenommen, wir rufen die Layoutdatei auf res/layout/main.xml. Es könnte ungefähr so ​​aussehen:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical">
    <Button android:text="This is a button on top of all preferences."
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    <ListView android:id="@android:id/list"
              android:layout_width="match_parent"
              android:layout_height="wrap_content" />
</LinearLayout>

Fügen Sie in Ihrem PreferenceActivitydiese beiden Zeilen hinzu onCreate:

addPreferencesFromResource(R.xml.preferences);
setContentView(R.layout.main);

Das ListViewin Ihrem Layout wird dann durch die Einstellungen ersetzt, die auf die übliche Weise in definiert wurden res/xml/preferences.xml.

Max
quelle
10
Funktioniert nicht, wenn die Schaltfläche unter der Listenansicht platziert ist. Funktioniert nicht, wenn die Voreinstellungsaktivität das Dialogthema verwendet.
Greg Ennis
11
In der neuesten Dokumentation zur Verwendung von PreferenceActivity unter developer.android.com/reference/android/preference/… wird erwähnt, dass PreferenceFragment für alle Neuentwicklungen die bevorzugte Methode zur Implementierung ist. Es scheint, dass die gegebene Lösung in einem solchen Szenario nicht funktioniert.
Pankaj
4
Es wird immer noch nicht mit der Liste gescrollt.
Sudarshan Bhat
7
Ich bin etwas verblüfft darüber, wie viele Stimmen diese Antwort hat, da sie die ursprüngliche Frage nicht wirklich beantwortet. Es wird nicht mit der Liste gescrollt und es funktioniert nicht, wenn die Schaltfläche am unteren Rand der Ansicht platziert ist, wie in den obigen Kommentaren erwähnt.
Howettl
1
@howettl ändern Sie einfach fill_parent in wrap_content in ListView layout_height
Martin Ch
56

Ich weiß, dass dies etwas spät ist, aber ich habe gerade eine Lösung gefunden, die mir besser gefällt als Max 'gelobte Lösung.

Sie können der ListView von PreferenceActivity einfach eine Fußzeile (oder, wenn die Schaltfläche oben angezeigt werden soll, eine Kopfzeile) wie folgt hinzufügen:

public class MyActivity extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.preferences);
        ListView v = getListView();
        v.addFooterView(new Button(this));
    }
}

Ich hoffe das hilft jemandem.

jpihl
quelle
2
Zumindest fühlt sich dies als Max 'Lösung besser an, da es nicht auf Element-IDs beruht. Mal sehen, wie es sich in zukünftigen Versionen von Android verhält ...
Daniel F
@ DanielF. Überquere die Brücke nicht, bis du dazu kommst;)
jpihl
1
Ich kann das nicht ListViewmit PreferenceFragment bekommen :(
Michał K
1
Nein, es würde nicht so funktionieren (weil PreferenceFragmentes eine eigene Liste hat), aber ich habe es gelöst, indem ich einfach ein erstellt Preferenceund ein Intentdarauf gesetzt habe. Es war nicht nötig, eine Schaltfläche zu erstellen (zumindest in meinem Fall)
Michał K
1
Funktioniert nicht mit dem PreferenceFragmentCompat, da getListView tatsächlich eine RecyclerView
Mauker
11

In diesem Beispiel unten wird eine Schaltfläche am unteren Rand der Seite gerendert (falls noch jemand interessiert ist).

Im Falle eines LinearLayout können Sie auch Gewichte anwenden. Dies ist erforderlich, da die Listenansicht auf * fill_parent * gesetzt ist. Normalerweise füge ich dazu * android: layout_weight * hinzu:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
              android:orientation="vertical">
    <ListView android:id="@android:id/list"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent" android:layout_weight="10"/>
    <Button android:text="This is a button on top of all preferences."
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" android:layout_weight="1"/>
</LinearLayout>

Die folgende Erklärung ist wahrscheinlich nicht 100%, aber sie wird Ihnen helfen zu verstehen ...

+-- View Port (linear layout)
| +-- List View (this is where the preferences will go)
| |
| |
| +--
+--
  +--
  | Button (which was pushed out of view by the fillparent of ListView
  +--

Man könnte auch sagen, weil der Knopf kein Gewicht hat; Die Schaltfläche wird in einer Höhe von 0 dp gerendert.

Wenn nun die layout_weigths hinzugefügt werden, wird die Schaltfläche zum Rendern der Schaltfläche angezeigt

+-- View Port (linear layout)
| +-- List View (this is where the preferences will go)
| |
| |
| +--
| +--
| | Button (which was pushed out of view by the fillparent of ListView
| +--
+--
Ronnie
quelle
Entschuldigung, habe den Beitrag von @stealthcopter
Ronnie
7

Eigentlich gibt es eine Lösung. Hier ist ein Code, ich hoffe, dieser wird für jeden nützlich sein. Es sieht aus wie 3 Optionen und 2 Schaltflächen am unteren Bildschirmrand, unabhängig von der Bildschirmauflösung (wurde auf 240 als niedrigste Zielvorgabe festgelegt).

package com.myapplication.gui;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Bundle;
import android.preference.Preference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;
import android.view.Display;
import android.view.Gravity;
import android.view.WindowManager;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.ScrollView;
import com.myproject.general.HeightListView;

import com.myapplication.R;

public class FilterActivity extends PreferenceActivity {

    private LinearLayout rootView; 
    private LinearLayout buttonView; 
    private Button buttonDone;
    private Button buttonRevert;
    private ListView preferenceView; 
    private LinearLayout gradientView;
    private ScrollView scrollRoot;

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
        super.onCreate(savedInstanceState); 

        Display display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); 
        int height = display.getHeight();
        int width = height > 240 ? display.getWidth() : display.getWidth() - 4;

        scrollRoot = new ScrollView(this);
        scrollRoot.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

        rootView = new LinearLayout(this); 
        rootView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT)); 
        rootView.setOrientation(LinearLayout.VERTICAL);

        buttonView = new LinearLayout(this); 
        buttonView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
        buttonView.setOrientation(LinearLayout.HORIZONTAL);
        buttonView.setGravity(Gravity.BOTTOM);

        gradientView = new LinearLayout(this);
        gradientView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
        gradientView.setOrientation(LinearLayout.HORIZONTAL);
        gradientView.setBackgroundResource(R.drawable.gradient);
        gradientView.setPadding(0, 5, 0, 0);
        gradientView.setBackgroundResource(R.drawable.gradient);

        buttonDone = new Button(this); 
        buttonDone.setText(R.string.filterButton_Done); 
        buttonDone.setLayoutParams(new LayoutParams(width/2, LayoutParams.WRAP_CONTENT));
        gradientView.addView(buttonDone);

        buttonRevert = new Button(this); 
        buttonRevert.setText(R.string.filterButton_Revert);
        buttonRevert.setLayoutParams(new LayoutParams(width/2, LayoutParams.WRAP_CONTENT));
        gradientView.addView(buttonRevert);

        buttonView.addView(gradientView);

        preferenceView = new HeightListView(this); 
        preferenceView.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT)); 
        preferenceView.setId(android.R.id.list); 

        PreferenceScreen screen = createPreferenceHierarchy(); 
        screen.bind(preferenceView); 
        preferenceView.setAdapter(screen.getRootAdapter()); 
        rootView.addView(preferenceView);
        rootView.addView(buttonView);

        if (height > 240) {
            this.setContentView(rootView);
        }
        else {
            scrollRoot.addView(rootView);
            this.setContentView(scrollRoot);
        }

        setPreferenceScreen(screen); 
    } 

    private PreferenceScreen createPreferenceHierarchy() {        
        PreferenceScreen root = getPreferenceManager().createPreferenceScreen(this);

        PreferenceScreen pref1 = getPreferenceManager().createPreferenceScreen(this);
        pref1.setKey("pref1");
        pref1.setTitle("Title");
        pref1.setSummary("Summary");
        root.addPreference(pref1); 

        PreferenceScreen pref2 = getPreferenceManager().createPreferenceScreen(this);
        pref2.setKey("pref2");
        pref2.setTitle("Title");
        pref2.setSummary("Summary");
        root.addPreference(pref2); 

        PreferenceScreen pref3 = getPreferenceManager().createPreferenceScreen(this);
        pref3.setKey("pref3");
        pref3.setTitle("Title");
        pref3.setSummary("Summary");
        root.addPreference(pref3); 

        return root; 
    } 
}
vlaku
quelle
2

Sie müssen nur PreferenceFragment in der allgemeinen Aktivität verwenden und die Schaltfläche zum Aktivitätslayout hinzufügen.

public class SettingActivity extends Activity {

    UserProfileViewModel userProfileViewModel = null;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        setContentView(R.layout.activity_setting);
        getFragmentManager().beginTransaction()
                .replace(R.id.content, new SettingsFragment())
                .commit();

    }

    private class SettingsFragment extends PreferenceFragment {
        public SettingsFragment() {
        }

        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);

            // Load the preferences from an XML resource
            addPreferencesFromResource(R.xml.pref_main);

        }
    }
}

SettingActivity.java

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <FrameLayout
        android:id="@+id/content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_above="@+id/buttonSave"/>

    <Button
        android:id="@+id/buttonSave"
        android:text="Save"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />
</RelativeLayout>

activity_setting

Geben Sie hier die Bildbeschreibung ein

Albert
quelle
Ich habe diesen Vorschlag befolgt und er zeigt die Schaltfläche am unteren Rand der Ansicht an, sie wird jedoch über die Voreinstellungsliste gelegt und kann nicht angeklickt werden (dh durch Klicken auf die Schaltfläche wird nur das Einstellungselement darunter aktiviert).
iaindownie
Die Schaltfläche onClickListener wird mit dieser Lösung nicht ausgelöst
rdehuyss
@rdehuyss es, weil Sie onClickListener hinzufügen müssen buttonSave:)
Albert
1

So würde der Code in der Aktivität am Beispiel des Ronny aussehen. Meine Absicht war es, ein Menü am unteren Rand des Bildschirms einzufügen.

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.prefs);
    addPreferencesFromResource(R.xml.prefs);

   /* LayoutInflater CX = getLayoutInflater();
    CX.inflate(R.layout.main,null);*/
    // TODO Auto-generated method stub
}
user507410
quelle
1
 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <ListView
        android:id="@android:id/list"
        android:layout_width="match_parent"
        android:layout_height="@dimens/listview_height" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="This is a button on top of all preferences." />
</RelativeLayout>

Ich verweise auf @Ronnie, verwende RelativeLayout und lege eine Höhe für layout_height der Listenansicht fest und setze dann das layout_alignParentBottom = "true" der Schaltfläche. Es kann eine Schaltfläche am unteren Rand von PreferenceScreen rendern. Verwenden Sie dann den Weg von @Max. es funktioniert für meine Bedürfnisse.

Mejonzhan
quelle
Dies ist eine gute Lösung, aber Sie haben vergessen, die Listenansicht über der Schaltfläche festzulegen. Derzeit befinden sich möglicherweise Elemente der Listenansicht hinter der Schaltfläche. Dies wird nicht empfohlen, da das letzte Element niemals sichtbar und daher anklickbar ist.
Android-Entwickler
Oh ja, Sie haben Recht, ich habe diesen Fall vergessen, weil meine Listenansicht nur 5 Elemente enthält, danke.
Mejonzhan
Bitte aktualisieren Sie Ihre Antwort, damit andere dieses Verhalten nicht haben.
Android-Entwickler
Ich denke, Sie haben auch einige Attribute und das End-Tag des relativen Layouts vergessen.
Android-Entwickler
Tatsächlich kann das Einstellen der richtigen listview_height das von Ihnen angegebene Problem lösen.
Mejonzhan
1

Es ist auch möglich, Aktionsschaltflächen zur Aktionsleiste für einen Android-Standardansatz hinzuzufügen.

public class PrefActivity extends PreferenceActivity{

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
    }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu items for use in the action bar
      MenuInflater inflater = getMenuInflater();
      inflater.inflate(R.menu.preference_header_menu, menu);
      return super.onCreateOptionsMenu(menu);
  }

}


    <?xml version="1.0" encoding="utf-8"?>
       <menu xmlns:android="http://schemas.android.com/apk/res/android">
       <item android:id="@+id/action_add"
           android:icon="@drawable/ic_menu_add_dark"
           android:title="@string/menu_action_add_title"
           android:showAsAction="always"  />

   </menu>
redevill
quelle
0

Benutzerdefinierte Ansicht in Voreinstellungsaktivität Dies hilft beim Hinzufügen einer benutzerdefinierten Ansicht in Voreinstellungsaktivität in Android.

Erstellen Sie die Datei main.xml. Die einzige erforderliche Ansicht ist eine ListView mit der ID : android:id="@android:id/list".

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:orientation="vertical" android:layout_width="fill_parent"
        android:layout_height="fill_parent" android:weightSum="1">
        <ListView 
            android:id="@android:id/list" 
            android:layout_weight="1"
            android:layout_width="fill_parent"
                android:layout_height="0dp">
        </ListView>
        <TextView
        android:id="@+id/textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

Erstellen Sie CustomPreferenceActivity.java

public class CustomPreferenceActivity extends PreferenceActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
                super.onCreate(savedInstanceState);
                setContentView(R.layout.main);
                addPreferencesFromResource(R.xml.settings);

                //setup any other views that you have
                TextView textView = (TextView) findViewById(R.id.textView);
textView.setText("View Added");
        }
}
Ankit Singh
quelle
0

Das Folgende ist eine einfache Lösung, um Ihrem Einstellungsbildschirm eine anklickbare Schaltfläche hinzuzufügen. Dies wird vereinfacht, da die Einstellungen bereits den Platz im android: widgetLayout reservieren und die Schaltfläche Klicks mit android: onClick übergeben kann.

Erstellen Sie zunächst eine button.xml mit dem Inhalt

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
    android:text="BUTTON"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:id="@+id/button"
    android:onClick="onButtonClick"/>
</LinearLayout>

Fügen Sie nun in Ihrer Einstellungen.xml die Einstellungen hinzu

<Preference
    android:key="button"
    android:title="Title"
    android:summary="Summary"
    android:widgetLayout="@layout/button" />

Ihre PreferenceActivity muss jetzt nur noch ein onButtonClick-Mitglied enthalten

public class MainActivity extends PreferenceActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    addPreferencesFromResource(R.xml.main_preferences);


}

public void onButtonClick(View v) {
    Log.d("Button", "Yeah, button was clicked");
}
}
ppareit
quelle
0

Einstellungen.xml:

    <Preference
        android:key="clearAllData"
        android:title="@string/settings_clear_all_data">
    </Preference>

SettingsFragment.java:

public class SettingsFragment extends PreferenceFragment {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.xml.settings);

        Preference clearAllData = (Preference) findPreference("clearAllData");

        // setup buttons
        final Context context = getActivity();
        clearAllData.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {

            @Override
            public boolean onPreferenceClick(Preference preference) {
                ...
            }
    }

}
Dmitry
quelle
0

Ich fand alle oben genannten Antworten nicht verwendbar, da alle Layouts, die ich erstellt habe, um den PreferenceScreenContainer in benutzerdefinierte Layouts zu "verpacken" (und dann eine Schaltfläche unter dem hinzufügen ListView), nicht funktionierten.

Sie überlagerten nur das benutzerdefinierte Layout über der Voreinstellungsliste (schwebend), und wenn Sie auf eine neue benutzerdefinierte Schaltfläche klicken (z. B.), wird nur die Voreinstellung unter der Schaltfläche aufgerufen.

Ich habe jedoch diese Lösung gefunden , die bei der Verwendung eine Schaltfläche zum Hinzufügen einer Schaltfläche unter dem Voreinstellungslistencontainer verwendet PreferenceFragment.

iaindownie
quelle