Come aggiungere un pulsante a PreferenceScreen


106

C'è un modo per aggiungere un pulsante nella parte inferiore della schermata delle preferenze e farle funzionare correttamente durante lo scorrimento?


2
Hai esaminato la creazione di una preferenza personalizzata?
Prashast

2
Per i futuri visitatori, mentre la soluzione di Max funziona, c'è una soluzione alternativa: stackoverflow.com/a/7251575/802469
Reed

Risposte:


249

C'è un'altra soluzione per personalizzare l'aspetto delle preferenze.

Progetta un normale layout XML con pulsanti o qualsiasi altra cosa desideri aggiungere alle preferenze standard. Includere un ListViewnel layout e assegnargli l'ID @android:id/list.

Diciamo che chiamiamo il file di layout res/layout/main.xml. Potrebbe assomigliare a questo:

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

Nel tuo PreferenceActivity, aggiungi queste due righe a onCreate:

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

Il ListViewnel tuo layout verrà quindi sostituito dalle preferenze definite nel solito modo res/xml/preferences.xml.


10
Non funziona quando il pulsante è posizionato sotto la visualizzazione elenco. Non funziona quando l'attività relativa alle preferenze utilizza il tema della finestra di dialogo.
Greg Ennis

11
L'ultima documentazione sull'utilizzo di PreferenceActivity su developer.android.com/reference/android/preference/… menziona che per tutti i nuovi sviluppi PreferenceFragment è il modo preferito per l'implementazione. Sembra che la soluzione data non funzionerà in tale scenario.
Pankaj

4
Continua a non scorrere con l'elenco.
Sudarshan Bhat

7
Sono un po 'sconcertato da quanti voti ha questa risposta poiché in realtà non risponde alla domanda originale. Non scorre con l'elenco e non funziona quando il pulsante è posizionato nella parte inferiore della vista, come menzionato nei commenti sopra.
howettl

1
@howettl cambia semplicemente fill_parent in wrap_content in ListView layout_height
Martin Ch

56

So che è un po 'tardi, ma ho appena trovato una soluzione che mi piace di più rispetto alla soluzione lodata di Max.

Puoi semplicemente aggiungere un piè di pagina (o se desideri che il pulsante sia in alto, un'intestazione) al ListView di PreferenceActivity in questo modo:

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

Spero che questo aiuti qualcuno.


2
Almeno questo sembra migliore come soluzione di Max in quanto non si basa sugli ID degli elementi. Vediamo come si comporta nelle future versioni di Android ...
Daniel F

@DanielF. non attraversare il ponte finché non ci arrivi;)
jpihl

1
Non riesco a ottenere il ListViewcon PreferenceFragment :(
Michał K

1
No, non funzionerebbe in questo modo (perché PreferenceFragmentha il suo elenco), ma l'ho risolto semplicemente creando un Preferencee impostando un Intentsu di esso. Non c'era bisogno di creare un pulsante (almeno nel mio caso)
Michał K

1
Non funziona con PreferenceFragmentCompat, poiché getListView restituirà effettivamente RecyclerView
Mauker

11

Questo esempio sotto mostrerà un pulsante nella parte inferiore della pagina (nel caso qualcuno sia ancora interessato).

In caso di LinearLayout potresti anche applicare pesi; questo è necessario perché Listview è impostato su * fill_parent *. Di solito lo faccio aggiungendo * 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>

La spiegazione di seguito non è probabilmente al 100% ma ti aiuterà a capire ...

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

Si potrebbe anche dire, perché il Button non ha peso; il pulsante è renderizzato all'altezza di 0dp.

Ora con layout_weigths aggiunto, il pulsante visualizzerà la visualizzazione

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

Mi dispiace perdere il post di @stealthcopter
Ronnie

7

In realtà, c'è una soluzione. Ecco un codice, spero, sarà utile per chiunque. Sembra che 3 opzioni e 2 pulsanti nella parte inferiore dello schermo, indipendentemente dalla risoluzione dello schermo (era mirato a 240 come minimo)

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

Devi solo usare PreferenceFragment all'interno di attività generale e aggiungere il pulsante nel layout dell'attività.

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

inserisci qui la descrizione dell'immagine


Ho seguito questo suggerimento e visualizza il pulsante nella parte inferiore della vista, ma è sovrapposto in cima all'elenco delle preferenze e non è possibile fare clic (ovvero, facendo clic sul pulsante si attiva solo l'elemento di preferenza sottostante).
iaindownie

Il pulsante su ClickListener non viene attivato utilizzando questa soluzione
rdehuyss

@rdehuyss perché è necessario aggiungere onClickListener a buttonSave:)
Albert

1

Questo sarebbe l'aspetto del codice nell'attività nell'esempio di Ronny. Il mio intento era quello di mettere un menu nella parte inferiore dello schermo.

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

Faccio riferimento a @Ronnie, uso RelativeLayout e imposto un'altezza per layout_height di listview, quindi imposto layout_alignParentBottom = "true" del pulsante, può eseguire il rendering di un pulsante nella parte inferiore di PreferenceScreen; quindi usa il modo di @Max. funziona per le mie esigenze.


Questa è una bella soluzione, ma ti sei dimenticato di impostare la listview sopra il pulsante. attualmente, gli elementi della listview potrebbero trovarsi dietro il pulsante, il che non è consigliato poiché se è l'ultimo elemento, non sarà mai visibile e quindi cliccabile.
sviluppatore Android

oh, sì, hai ragione, ho dimenticato questo caso, perché la mia lista visualizza solo 5 elementi, grazie.
Mejonzhan

aggiorna la tua risposta, così gli altri non avranno questo comportamento.
sviluppatore Android

Penso che tu abbia anche dimenticato alcuni attributi e il tag di fine del relativeLayout.
sviluppatore Android

In effetti, impostare il listview_height corretto può risolvere il problema che hai detto.
Mejonzhan

1

È anche possibile aggiungere pulsanti di azione alla barra delle azioni per un approccio standard 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

Visualizzazione personalizzata in Preference Activity questo aiuterà ad aggiungere una visualizzazione personalizzata in PreferenceActivity in Android.

Creare main.xml, la vista unica necessaria è un ListView, con 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>

Crea 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

Quella che segue è una semplice soluzione per aggiungere un pulsante cliccabile alla schermata delle preferenze. Ciò è reso facile perché le preferenze riservano già lo spazio in android: widgetLayout e il pulsante può passare i clic con android: onClick.

Per prima cosa crea un button.xml con il contenuto

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

Ora nel tuo Preferences.xml, aggiungi la preferenza

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

La tua PreferenceActivity ora deve contenere solo un membro 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

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

Ho trovato tutte le risposte precedenti non utilizzabili poiché tutti i layout che ho creato per "avvolgere" il PreferenceScreencontenitore all'interno di layout personalizzati (quindi aggiungere un pulsante sotto ListView) non funzionavano effettivamente.

Si sovrapponevano solo al layout personalizzato in cima all'elenco delle preferenze (mobile) e facendo clic (ad es.) Su un nuovo pulsante personalizzato si richiamava solo la preferenza sotto il pulsante.

Tuttavia, ho trovato questa soluzione che funziona a meraviglia per l'aggiunta di un pulsante sotto il contenitore dell'elenco delle preferenze, durante l'utilizzo PreferenceFragment.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.