Alternative a PreferenceFragment con android-support-v4


90

Mi sono fermato improvvisamente nello sviluppo della mia app quando mi sono reso conto che PreferenceFragments non erano supportati in questa libreria. Esistono alternative che uno sviluppatore Android principiante può utilizzare per superare questo ostacolo?

Questa è la mia finestra principale in questo momento

<?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">
<TabHost
    android:id="@android:id/tabhost"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <LinearLayout
        android:orientation="vertical"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        >

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="0dp"
            android:layout_height="0dp"
            android:layout_weight="0"/>

        <FrameLayout
            android:id="@+android:id/realtabcontent"
            android:layout_width="fill_parent"
            android:layout_height="0dp"
            android:layout_weight="1"/>
    </LinearLayout>

                <TabWidget
            android:id="@android:id/tabs"
            android:orientation="horizontal"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:layout_weight="0"
            />

</TabHost>
</LinearLayout>

Per il mio TabActivity sto usando qualcosa che ho trovato online. Ecco uno snippet:

public class TabControlActivity extends FragmentActivity implements TabHost.OnTabChangeListener 
{
public static final int INSERT_ID = Menu.FIRST;
public static TabControlActivity thisCtx;
private TabHost mTabHost;
private HashMap mapTabInfo = new HashMap();
private TabInfo mLastTab = null;

private class TabInfo {
     private String tag;
     private Class clss;
     private Bundle args;
     private Fragment fragment;
     TabInfo(String tag, Class clazz, Bundle args) {
         this.tag = tag;
         this.clss = clazz;
         this.args = args;
     }

}

class TabFactory implements TabContentFactory 
{

    private final Context mContext;

    /**
     * @param context
     */
    public TabFactory(Context context) {
        mContext = context;
    }

    /** (non-Javadoc)
     * @see android.widget.TabHost.TabContentFactory#createTabContent(java.lang.String)
     */
    public View createTabContent(String tag) {
        View v = new View(mContext);
        v.setMinimumWidth(0);
        v.setMinimumHeight(0);
        return v;
    }

}

...*snip*...

C'è qualcuno per implementare qualcosa che assomigli a un preferenzafragment (o preferenzaActivity) utilizzando la libreria di compatibilità android-support-v4?



Non proprio un duplicato in quanto mi trovo in una situazione in cui "ho bisogno" di queste preferenze da mostrare all'interno di un tabhost. Vedi la mia modifica
CodePrimate

Vedi la mia risposta aggiornata . PreferenceFragmentCompatè stato recentemente aggiunto alla libreria di supporto.
theblang

Risposte:


86

AGGIORNAMENTO - 6/11/2015

La libreria Support-v7 ora include PreferenceFragmentCompat. Quindi sarà un'idea migliore usarlo.


Aggiungi il seguente progetto come progetto di libreria alla tua applicazione.

https://github.com/kolavar/android-support-v4-preferencefragment

Puoi mantenere tutto, inclusa la transazione dei frammenti, così com'è. Quando importi la PreferenceFragmentclasse, assicurati che l'intestazione di importazione corretta sia user.

import android.support.v4.preference.PreferenceFragment;

invece di

import android.preference.PreferenceFragment;

4
Quel codice GitHub sembra avere problemi seri ... Non posso usarlo RingtonePreferencee inoltre OnSharedPreferenceChangeListenernon sembra avere alcuna modifica!
madlymad

2
Stavo pensando che fosse una buona idea usare questa libreria. Ma ho capito che non è così buono come pensavo. Il tentativo di sovrascrivere il onPrepareOptionMenumetodo mi mostra una strana firma (ritorni void) diversa da quella predefinita che tutti conosciamo (ritorni boolean) !!! un problema serio.
S.Thiongane

9
votato positivamente e hai diritto a una cena gratuita ogni volta che verrai a Madrid ... questo problema mi stava facendo impazzire!
rupps

7
@mansoulx onPrepareOptionsMenu ha sempre un tipo di ritorno void sui frammenti (a differenza di Activities, per cui è booleano), quindi questa firma è completamente come previsto.
Cumbayah

3
I problemi con la libreria dovrebbero probabilmente essere segnalati nel progetto github.
Mathijs Segers,

128

So che questa è una vecchia domanda, ma ora puoi usare PreferenceFragmentCompatdacom.android.support:preference-v7:23.3.0


4
Grande scoperta, questa è una delle risposte corrette ora.
Mythul

Per me funziona solo con com.android.support:preference-v7:23.0.1.
Felipe Mosso

1
Questo non sembra essere sui server di dipendenza quando si tenta di aggiungerlo da Android Studio. Devo aggiungere un repository per questo?
Brill Pappin

Non contiene quella classe
JJ Ab

1
Ho accidentalmente votato questa risposta e non posso annullarla ora, quindi invece mi limiterò a notare che PreferenceFragmentCompatha alcuni problemi importanti: vedi questo e questo rapporto di bug, ad esempio, e molti altri qui . Ho finito per usare PreferenceActivityinvece il deprecato . sigh
Vicky Chijwani

16

Aggiornamento importante: l' ultima revisione di v7 support librarynow ha un PreferenceFragmentCompat nativo .

Sto usando questa libreria , che ha un AARin mavenCentralcosì puoi facilmente includerla se stai usando Gradle.

compile 'com.github.machinarius:preferencefragment:0.1.1'


Potresti condividere come importi ed estendi il frammento di supporto? Grazie
Steven

1
@Steve Sure! Ho fatto un Gist .
theblang

@mattblang Grazie mille!
Steven

@mattblang Grazie mille ... Il tuo aiuto mi fa davvero risparmiare molto tempo
Asad Ullah Rafiq

Eccezione java.lang.RuntimeException: il contenuto ha una vista con l'attributo id 'android.R.id.list' che non è una classe ListView
Abdul Rahman

10

Puoi usare il mio PreferenceFragment.

È semplice e finora non ho avuto problemi con esso. Penso che tu possa visualizzarne solo uno alla volta in una singola attività, il che dovrebbe essere OK.


9

Libreria di supporto delle preferenze: frammenti di preferenze per API 7+, indipendentemente dall'attività

Una semplice implementazione includerebbe un PreferenceFragmentCompat come:

public class PreferencesFragment extends PreferenceFragmentCompat {
    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
        addPreferencesFromResource(R.xml.preferences);
    }
}

Dovrai anche impostare preferenzaTheme nel tuo tema:

<style name="AppTheme" parent="@style/Theme.AppCompat.Light">
  <item name="preferenceTheme">@style/PreferenceThemeOverlay</item>
</style>

E aggiungilo nelle dipendenze: http://developer.android.com/tools/support-library/features.html

com.android.support:preference-v14:23.1.0

7

Potresti forse usare un'attività reale e usare il frammento, ma non penso che sia una buona scelta. È necessario utilizzare la semplice PreferenceActivity e attendere i miglioramenti nelle librerie di compatibilità retro.


1
Non posso utilizzare PreferenceActivity poiché il resto della mia app è costituito da un tabwidget. Il frammento di preferenza dovrebbe essere mostrato sopra il tabwidget. Dovevo renderlo un'attività invece che occuperebbe l'intero schermo.
CodePrimate

2
Quindi utilizza un frammento di elenco personalizzato
zapl


0

Puoi invece estenderlo da PreferenceActivity e, se desideri avere una ActionBar, puoi aggiungerla utilizzando una barra degli strumenti come se fosse sopra ListView utilizzata per le preferenze.

Questo può essere fatto utilizzando un LinearLayout verticale che contiene la barra degli strumenti e un ListView con android: id = "@ android: id / list" .

Se lo desideri, puoi vedere la mia soluzione qui .


0

Come ha detto Lucius, puoi usare PreferenceFragmentCompat :

public class MyPreferenceFragment extends PreferenceFragmentCompat {
        @Override
        public void onCreatePreferences(Bundle bundle, String s) {               
            PreferenceManager.setDefaultValues(getActivity(), R.xml.preferences, false);
            addPreferencesFromResource(R.xml.preferences);
       }
}

Devi includere la sua dipendenza in gradle:

dependencies {
...
    compile 'com.android.support:preference-v7:23.1.X' (wherX = 0,1,...)
...
}

In questo modo puoi anche utilizzare FragmentTransaction di android.support.v4.app.FragmentTransaction e PrefernceFragment. Tuttavia, potresti avere problemi con i temi. Se è il caso, puoi risolverlo tenendo conto di questo post:

Soluzione per far funzionare la libreria su API 7+ mantenendo il tema del materiale su API 14+

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.