Alternativas a PreferenceFragment con android-support-v4

90

Me detuve repentinamente en el desarrollo de mi aplicación cuando me di cuenta de que PreferenceFragments no era compatible con esta biblioteca. ¿Existe alguna alternativa que un desarrollador de Android novato pueda utilizar para superar este obstáculo?

Esta es mi ventana principal a partir de ahora

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

Para mi TabActivity, estoy usando algo que encontré en línea. Aquí hay un fragmento:

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

¿Hay alguno para implementar algo que se parezca a un fragmento de preferencia (o actividad de preferencia) usando la biblioteca de compatibilidad android-support-v4?

CodePrimate
fuente
No es realmente un duplicado ya que estoy en una situación en la que "necesito" que estas preferencias se muestren dentro de un tabhost. Ver mi edición
CodePrimate
Vea mi respuesta actualizada . PreferenceFragmentCompatse agregó recientemente a la biblioteca de soporte.
theblang

Respuestas:

86

ACTUALIZACIÓN - 6/11/2015

La biblioteca Support-v7 ahora incluye archivos PreferenceFragmentCompat. Entonces será una mejor idea usarlo.


Agregue el siguiente proyecto como un proyecto de biblioteca a su aplicación.

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

Puede mantener todo, incluida la transacción de fragmentos, tal como está. Al importar la PreferenceFragmentclase, asegúrese de que el encabezado de importación correcto sea user.

import android.support.v4.preference.PreferenceFragment;

en vez de

import android.preference.PreferenceFragment;
Sebastián subin
fuente
4
Ese código de github parece tener problemas graves ... ¡No puedo usarlo RingtonePreferencey OnSharedPreferenceChangeListenertampoco parece recibir ningún cambio!
madlymad
2
Estaba pensando que es una buena idea usar esta biblioteca. Pero me di cuenta de que no es tan bueno como pensaba. ¡Intentar anular el onPrepareOptionMenumétodo me muestra una firma extraña (devuelve void) diferente a la predeterminada que todos conocemos (devuelve boolean)! un problema serio.
S.Thiongane
9
upvoted, y tienes derecho a una cena gratis siempre que vengas a Madrid ... ¡este tema me estaba volviendo loco!
Ruptura el
7
@mansoulx onPrepareOptionsMenu siempre tiene un tipo de retorno vacío en los fragmentos (a diferencia de Actividades, para las que es booleano), por lo que esta firma es completamente la esperada.
Cumbayah
3
Los problemas con la biblioteca probablemente deberían informarse en el proyecto github.
Mathijs Segers
128

Sé que esta es una pregunta antigua, pero ahora puedes usar PreferenceFragmentCompatdecom.android.support:preference-v7:23.3.0

Lucius
fuente
4
Gran hallazgo, esta es una de las respuestas correctas ahora.
Mythul
Para mí, solo funciona con com.android.support:preference-v7:23.0.1.
Felipe Mosso
1
Esto no parece estar en los servidores de dependencia al intentar agregarlo desde Android Studio. ¿Necesito agregar un repositorio?
Brill Pappin
No contiene esa clase
JJ Ab
1
Accidentalmente voté a favor de esta respuesta y no puedo deshacerla ahora, así que en su lugar solo señalaré que PreferenceFragmentCompattiene algunos problemas importantes: vea este y este informe de error, por ejemplo, y muchos más aquí . Terminé usando el obsoleto en su PreferenceActivitylugar. suspiro
Vicky Chijwani
16

Actualización importante: la última revisión de v7 support libraryahora tiene un PreferenceFragmentCompat nativo .

Estoy utilizando esta biblioteca , que tiene una AARen mavenCentrallo que puede incluir fácilmente si está utilizando Gradle.

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

theblang
fuente
¿Podrías compartir cómo importas y extiendes el fragmento de soporte? Gracias
Steven
1
@Steve ¡Seguro! Hice un Gist .
theblang
@mattblang ¡Muchas gracias!
Steven
@mattblang Muchas gracias ... Tu ayuda realmente me ahorra mucho tiempo
Asad Ullah Rafiq
Excepción java.lang.RuntimeException: el contenido tiene una vista con el atributo de id 'android.R.id.list' que no es una clase ListView
Abdul Rahman
10

Puedes usar el mío PreferenceFragment.

Es simple y no he tenido problemas con él hasta ahora. Creo que solo puede mostrar uno de ellos a la vez en una sola actividad, lo que debería estar bien.

BladeCoder
fuente
9

Biblioteca de soporte de preferencias: fragmentos de preferencias para API 7+, sin importar la actividad

Una implementación simple incluiría un PreferenceFragmentCompat como:

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

También necesitará establecer preferenciaTheme en su tema:

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

Y agregue esto en dependencias: http://developer.android.com/tools/support-library/features.html

com.android.support:preference-v14:23.1.0
li2
fuente
7

Quizás puedas usar una actividad real y usar un fragmento, pero no creo que sea una buena opción. Debe usar PreferenceActivity simple y esperar mejoras en las bibliotecas de compatibilidad retro.

Snicolas
fuente
1
No puedo usar PreferenceActivity ya que el resto de mi aplicación consiste en un tabwidget. Se supone que el fragmento de preferencias se muestra encima del widget de pestaña. Tenía que convertirlo en una actividad en su lugar, ocuparía toda la pantalla.
CodePrimate
2
Luego use algún fragmento de lista personalizado
zapl
2

Puede utilizar bibliotecas de terceros, como UnifiedPreferences, para utilizar una única API para todas las versiones de Android.

MarcoDuff
fuente
0

En su lugar, puede extender desde PreferenceActivity , y si desea tener una ActionBar, puede agregarla usando una barra de herramientas por encima de ListView usado para las preferencias.

Esto se puede hacer usando un LinearLayout vertical que contiene la barra de herramientas y un ListView con android: id = "@ android: id / list" .

Si lo desea, puede ver mi solución aquí .

desarrollador de Android
fuente
0

Como dijo Lucius, puede usar 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);
       }
}

Debes incluir su dependencia en gradle:

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

De esta forma, también puede utilizar FragmentTransaction de android.support.v4.app.FragmentTransaction y PrefernceFragment. Sin embargo, es posible que tenga problemas con los temas. Si es el caso, puedes solucionarlo teniendo en cuenta este post:

Solución para hacer que la biblioteca funcione en API 7+ mientras se mantiene el tema del material en API 14+

vicasdia
fuente