Cómo administrar los separadores en una PreferenceFragment?

Empecé a tratar con las preferencias en una PreferenceFragment. He aquí lo que tengo:

my_preferences

Estoy tratando de:

  1. deshacerse de los divisores entre los elementos. Supongo que esto puede ser definido a partir de los estilos, pero no puedo averiguar cómo. Traté de conseguir el preferencia ListView en tiempo de ejecución de llamadas findViewById(android.R.id.list), como he leído en algún lugar, pero devuelve null.

  2. conjunto nuevo, ancho completo divisores en la parte superior derecha de los encabezados, como se ve aquí. Por ejemplo, en este caso quiero un ancho máximo divisor a la derecha por encima de "Statistiche", pero no por encima de "Generali", que está en la parte superior de la lista.

La única manera que se me viene a la mente es la configuración de los divisores como falso preferencias, como por ejemplo con:

<Preference
    android:layout="@layout/divider" //here I set width and a divider resource
    />

<PreferenceCategory ... />

El principal problema aquí es que mi PreferenceFragment (o el ActionBarActivity es en) tiene algunas izquierda/derecha relleno, que hacen que cualquier divisor puedo agregar en preferences.xml no cubrir todo el ancho.

Así que mi pregunta son:

  • ¿Cómo puedo deshacerme de forma predeterminada, el elemento-el elemento de divisores que se puede ver en la imagen?

  • ¿Cómo puedo establecer la anchura total de divisores de derecho por encima de los encabezados, o ¿cómo puedo deshacerme de los internos fragmento/actividad de relleno? Por supuesto, mi actividad de diseño no tiene (explícito) de relleno alguno.

  • Respuesta seleccionada
    natario
    3 de febrero de 2015

    Tenía totalmente olvidado acerca de esta cuestión, va a publicar una respuesta ahora a ayudar a los demás. He resuelto moviendo mi código en la onResume() método de la actividad que aloja mi PreferenceFragment. Creo que hay varios puntos en los que usted puede recordar un no-null ListView con findViewById(android.R.id.list).

    public boolean mListStyled;
    
    @Override
    public void onResume() {
        super.onResume();
        if (!mListStyled) {
            View rootView = getView();
            if (rootView != null) {
                ListView list = (ListView) rootView.findViewById(android.R.id.list);
                list.setPadding(0, 0, 0, 0);
                list.setDivider(null);
                //any other styling call
                mListStyled = true;
            }
        }
    }
    

    Probablemente, usted puede deshacerse de la rootView comprobar, pero al mismo tiempo, incluso es posible que desee comprobar list != null. Yo no se enfrentan a cualquier NPE esta manera, de todos modos.

    Así, setDivider(null) toma el elemento-el elemento de divisores. Me las arreglé para agregar separadores de sección cubrir el ancho completo de la pantalla:

    • Retirar el relleno de list;
    • La adición de un personalizado de preferencia en mi XML:

    n

     <Preference
         android:title="divider"
         android:selectable="false"
         android:layout="@layout/preference_divider"/>
    

8 Respuestas

  • SagiLow
    14 de enero de 2015

    Añadir este código en el PreferenceFragment :

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
    
            // remove dividers
            View rootView = getView();
            ListView list = (ListView) rootView.findViewById(android.R.id.list);
            list.setDivider(null);
    
        }
    
  • X3Btel
    24 de julio de 2015

    Aunque un poco tarde estoy teniendo el mismo problemas con divisores en preff pantalla y encontré esta solución: Personalizar el estilo de la celebración de la actividad y mejorar el estilo:

       <item name="android:listDivider">@null</item>
    

    De hecho es la misma que la de la configuración del comedero código, pero guarda un findById y creo que se ve más claro conjunto de comedero estilos

  • formatBCE
    14 de febrero de 2017

    Para PreferenceFragmentCompat, ListView no funciona. Pero esto funciona como un encanto:

    <style name="PrefsTheme" parent="PreferenceThemeOverlay.v14.Material">
        <item name="android:divider">@null</item>
        <item name="android:dividerHeight">0dp</item>
    </style>
    

    Agregar esto a tu aplicación tema:

    <item name="preferenceTheme">@style/PrefsTheme</item>
    
  • sadmonster
    12 de abril de 2017

    si utiliza un PreferenceFragment ,puede utilizar ListView.setDivider(null); si utiliza un PreferenceFragmentCompat ,puede utilizar PreferenceFragmentCompat.setDivider(Drawable divider) o setDividerHeight(int height);

  • dphans
    25 de diciembre de 2017

    Nueva solución para el nuevo android API 24 y superior (25 de diciembre de 2017).

    He encontrado después de probar muchas maneras en stackoverflow, pero no de trabajo, o sólo el trabajo, pero no trabajo en nestest PreferenceScreen.

    Primero, usted necesita encontrar listview actual de la visualización de un fragmento, y quitar el divisor:

    private fun removeDividerInCurrentFragment() {
        this@YourPreferenceActivity.fragmentManager.findFragmentById(android.R.id.content)?.let {
            it.view?.findViewById<ListView?>(android.R.id.list)?.let {
                it.divider = null
                it.dividerHeight = 0
            }
        }
    }
    

    Segundo, para eliminar el divisor cuando fragmento comprometidos, llame al método anterior (removeDividerInCurrentFragment) para quitar listview del divisor.

    Para asegurarse de que si usted tiene nestest PreferenceScreen. Registro de escucha cuando fragmento cambiado en su PreferenceActivity por implementar FragmentManager.OnBackStackChangedListener protocolo:

    class YourPreferenceActivity : PreferenceActivity(), FragmentManager.OnBackStackChangedListener {
        override fun onBackStackChanged() {
            this@YourPreferenceActivity.removeDividerInCurrentFragment()
        }
    }
    

    Por último, registrar backstack cambios detector de llamada fragmentManager.addOnBackStackChangedListener(this@ YourPreferenceActivity) en onCreate. Y quitar backstack cambios detector de llamada fragmentManager.removeOnBackStackChangedListener en onDestroyed método.

    Buena suerte!

  • The Finest Artist
    12 de febrero de 2018

    Usted puede volver a su estilo divisor utilizando este tema.

    <style name="PreferenceFragment.Material">
        <item name="android:divider">@drawable/preference_list_divider_material</item>
    </style>
    
  • doubleA
    14 de agosto de 2018

    Tuve este mismo problema y quería divisores entre categorías de preferencia, pero no entre los propios elementos. He encontrado que la solución aceptada satisfecho Pregunta 1 mediante la eliminación de los divisores de los elementos de preferencia, pero no soluciona la pregunta 2 y agregar los divisores entre categorías de preferencia.

    Revisión a continuación. Básicamente reemplazar el onCreateAdapter método de su PreferenceFragmentCompat y darle una costumbre PreferenceGroupAdapter que tiene una reemplazado onBindViewHolder método que utiliza la posición y cualquier otra cosa que usted necesita para establecer por encima y por debajo de los permisos para cada vista de titular. Un divisor será dibujado cuando ambos viewholders permitir un divisor entre ellos.

    Aquí está mi revisión

    public class SettingsFragment extends PreferenceFragmentCompat {
    
        @Override
        protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
            return new CustomPreferenceGroupAdapter(preferenceScreen);
        }
    
        static class CustomPreferenceGroupAdapter extends PreferenceGroupAdapter {
    
        @SuppressLint("RestrictedApi")
        public CustomPreferenceGroupAdapter(PreferenceGroup preferenceGroup) {
            super(preferenceGroup);
        }
    
        @SuppressLint("RestrictedApi")
        @Override
        public void onBindViewHolder(PreferenceViewHolder holder, int position) {
            super.onBindViewHolder(holder, position);
            Preference currentPreference = getItem(position);
            //For a preference category we want the divider shown above.
            if(position != 0 && currentPreference instanceof PreferenceCategory) {
                holder.setDividerAllowedAbove(true);
                holder.setDividerAllowedBelow(false);
            } else {
                //For other dividers we do not want to show divider above 
                //but allow dividers below for CategoryPreference dividers.
                holder.setDividerAllowedAbove(false);
                holder.setDividerAllowedBelow(true);
            }
        }
    }
    
  • Maksim Ivanov
    4 de mayo de 2019

    AndroidX hace que sea sencillo, pero me gustaría que fuera mejor documentados.

    En XML

    Para agregar o quitar los divisores entre las preferencias en el uso de XML en los siguientes atributos:

    <androidx.preference.PreferenceScreen
        xmlns:app="http://schemas.android.com/apk/res-auto">
    
        <Preference
            ...
            app:allowDividerAbove="true/false"
            app:allowDividerBelow="true/false"
            ... />
    
    </androidx.preference.PreferenceScreen>
    

    Nota, un divisor sólo se muestra entre dos preferencias si el divisor tiene allowDividerBelow conjunto de true y la siguiente divisor tiene allowDividerAbove conjunto de true.

    En El Código

    También puede cambiar/quitar divisores de programación utilizando los métodos siguientes en onActivityCreated de la PreferenceFragmentCompat:

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
    
        // To remove:
        setDivider(null);
    
        // To change:
        setDivider(ContextCompat.getDrawable(getActivity(), R.drawable.your_drawable));
        setDividerHeight(your_height);
    }