Jak dodać przycisk do PreferenceScreen


Odpowiedzi:


249

Istnieje inne rozwiązanie umożliwiające dostosowanie wyglądu preferencji.

Zaprojektuj normalny układ XML z przyciskami lub czymkolwiek, co chcesz dodać do standardowych preferencji. Uwzględnij ListVieww swoim układzie i nadaj mu identyfikator @android:id/list.

Powiedzmy, że nazywamy plik układu res/layout/main.xml. Może to wyglądać mniej więcej tak:

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

W swoim PreferenceActivity, dodaj te dwie linie do onCreate:

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

W ListViewtwoim układzie zostaną wtedy zastąpione preferencjami zdefiniowanymi w zwykły sposób res/xml/preferences.xml.


10
Nie działa, gdy przycisk znajduje się poniżej widoku listy. Nie działa, gdy aktywność preferencji używa motywu okna dialogowego.
Greg Ennis

11
Najnowsza dokumentacja dotycząca korzystania z PreferenceActivity pod adresem developer.android.com/reference/android/preference/ ... wspomina, że ​​w przypadku wszystkich nowych programów preferowanym sposobem implementacji jest PreferenceFragment. Wydaje się, że dane rozwiązanie nie zadziała w takim scenariuszu.
Pankaj

4
Nadal nie przewija się wraz z listą.
Sudarshan Bhat,

7
Jestem trochę zaskoczony tym, ile głosów ma ta odpowiedź, ponieważ tak naprawdę nie odpowiada ona na pierwotne pytanie. Nie przewija się wraz z listą i nie działa, gdy przycisk jest umieszczony u dołu widoku, jak wspomniano w komentarzach powyżej.
howettl

1
@howettl po prostu zmień fill_parent na wrap_content w układzie ListView layout_height
Martin Ch

56

Wiem, że to trochę za późno, ale właśnie znalazłem rozwiązanie, które lubię bardziej niż chwalone rozwiązanie Maxa.

Możesz po prostu dodać stopkę (lub, jeśli chcesz, aby przycisk był na górze, nagłówek) do ListView PreferenceActivity w następujący sposób:

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

Mam nadzieję, że to komuś pomoże.


2
Przynajmniej wydaje się to lepsze jako rozwiązanie Maxa, ponieważ nie opiera się na identyfikatorach elementów. Zobaczmy, jak zachowa się w przyszłych wersjach Androida ...
Daniel F

@DanielF. nie przechodź przez most, dopóki do niego nie
dojdziesz

1
Nie mogę dostać ListViewz PreferenceFragment :(
Michał K

1
Nie, to by nie działało w ten sposób (ponieważ PreferenceFragmentma własną listę), ale rozwiązałem to, po prostu tworząc Preferencei ustawiając Intentna nim. Nie było potrzeby tworzenia guzika (przynajmniej w moim przypadku)
Michał K

1
Nie działa z PreferenceFragmentCompat, ponieważ getListView w rzeczywistości zwróci RecyclerView
Mauker

11

Poniższy przykład wyrenderuje przycisk u dołu strony (na wypadek, gdyby ktoś był nadal zainteresowany).

W przypadku LinearLayout można również zastosować wagi; jest to potrzebne, ponieważ Listview jest ustawiony na * fill_parent *. Zwykle robię to, dodając * android: layout_weight *:

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

Poniższe wyjaśnienie nie jest prawdopodobnie w 100%, ale pomoże ci zrozumieć ...

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

Można też powiedzieć, że Button nie ma wagi; przycisk jest renderowany z wysokością 0 dp.

Teraz po dodaniu layout_weigths pozwoli to renderować przycisk inview

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

Przepraszam, że przegapiłem wpis @stealthcopter
Ronnie

7

Właściwie jest rozwiązanie. Oto kod, mam nadzieję, że przyda się każdemu. Wygląda na to, że 3 opcje i 2 przyciski u dołu ekranu, niezależnie od rozdzielczości ekranu (było ustawione na 240 jako najniższą)

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

2

Wystarczy użyć PreferenceFragment w ramach ogólnego działania i dodać przycisk do układu działania.

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>

ustawienie_czynności

wprowadź opis obrazu tutaj


Postępowałem zgodnie z tą sugestią i faktycznie wyświetla przycisk u dołu widoku, ale jest nałożony na górę listy preferencji i nie można go kliknąć (tj. Kliknięcie przycisku aktywuje tylko element preferencji poniżej).
iaindownie

Przycisk onClickListener nie jest uruchamiany przy użyciu tego rozwiązania
rdehuyss

@rdehuyss to, ponieważ musisz dodać onClickListener do buttonSave:)
Albert

1

Tak będzie wyglądał kod w działaniu na przykładzie Ronny'ego. Moim zamiarem było umieszczenie menu w dolnej części ekranu.

/** 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
}

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>

Odwołuję się do @Ronnie, używam RelativeLayout i ustawiam wysokość dla layout_height widoku listy, a następnie ustawiam layout_alignParentBottom przycisku = "true". Może on renderować przycisk na dole PreferenceScreen; następnie użyj drogi @Max. działa na moje potrzeby.


To fajne rozwiązanie, ale zapomniałeś ustawić widok listy nad przyciskiem. obecnie elementy widoku listy mogą znajdować się za przyciskiem, co nie jest zalecane, ponieważ jeśli jest to ostatnia pozycja, nigdy nie będzie widoczna i dlatego można ją kliknąć.
programista Androida

o tak, masz rację, zapomniałem o tej sprawie, ponieważ mój listview tylko 5 pozycji, dzięki.
Mejonzhan

zaktualizuj swoją odpowiedź, aby inni nie mieli tego zachowania.
programista Androida

Myślę, że zapomniałeś również o niektórych atrybutach i tagu końcowym RelativeLayout.
programista Androida

W rzeczywistości ustawienie odpowiedniego parametru listview_height może rozwiązać problem, który powiedziałeś.
Mejonzhan

1

Możliwe jest również dodanie przycisków akcji do paska akcji w przypadku standardowego podejścia systemu Android.

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>

0

Widok niestandardowy w działaniu Preference pomoże to dodać widok niestandardowy w PreferenceActivity w systemie Android.

Tworzenie main.xml, jedyny widok to konieczne ListView, o identyfikatorze 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>

Utwórz 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");
        }
}

0

Poniżej przedstawiono proste rozwiązanie umożliwiające dodanie klikalnego przycisku do ekranu preferencji. Jest to łatwe, ponieważ preferencje już rezerwują miejsce w android: widgetLayout, a przycisk może przechodzić przez kliknięcia z android: onClick.

Najpierw utwórz plik button.xml z zawartością

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

Teraz w Twoim preferencjach.xml dodaj preferencję

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

Twoja PreferenceActivity musi teraz zawierać tylko element członkowski onButtonClick

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

0

preferencje.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) {
                ...
            }
    }

}

0

Zauważyłem, że wszystkie powyższe odpowiedzi są nie do użytku, ponieważ wszelkie układy, które utworzyłem w celu „zawinięcia” PreferenceScreenkontenera w niestandardowe układy (a następnie dodanie przycisku poniżej ListView) w rzeczywistości nie działały.

Nakładali tylko układ niestandardowy na górę listy preferencji (ruchomy), a kliknięcie (np.) Nowego przycisku niestandardowego wywołałoby tylko preferencję znajdującą się pod przyciskiem.

Jednak znalazłem to rozwiązanie, które działa świetnie, dodając przycisk poniżej kontenera listy preferencji podczas używania PreferenceFragment.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.