Android: Cómo eliminar margen / relleno en la pantalla de preferencias

83

Estoy enfrentando un problema muy extraño al diseñar la pantalla de preferencias. Aunque no estoy dando ningún margen en el diseño, deja algo de espacio a la izquierda.

Como puede ver en la imagen a continuación: ingrese la descripción de la imagen aquí

XML:

   <PreferenceScreen android:title="demo" >
       <CheckBoxPreference
           android:defaultValue="false"
            android:key="prefSync"`
            android:title="Auto Sync" />
    </PreferenceScreen>

¿Estoy haciendo algo mal al agregar la preferencia de casilla de verificación en la pantalla?

Gallo
fuente
Puede encontrar su respuesta aquí
Miral
Hola Miral, gracias por la respuesta. Pero no estoy creando un diseño personalizado para la pantalla de preferencias
Dory
¿Puede mostrarnos su archivo de diseño?
Robin Dijkhof
<PreferenceScreen xmlns: android = " schemas.android.com/apk/res/android "> <CheckBoxPreference android: defaultValue = "false" android: key = "prefSync" android: title = "Auto Sync" /> </PreferenceScreen> aquí está el código
Dory
Mire [esta respuesta] ( stackoverflow.com/a/41101859/1785516 ) tal vez le ayude a solucionar su caso.
KLM

Respuestas:

153

Actualizando esto para androidx.

Después de mucha experimentación, resolví este problema agregando esto a cada preferencia que tenía el exceso de sangría:

app:iconSpaceReserved="false"

Por supuesto, también deberá agregar esto a la declaración PreferenceScreen en la parte superior de su xml:

xmlns:app="http://schemas.android.com/apk/res-auto"

Seguimiento de preferencias personalizadas

Noté que en el caso de las preferencias personalizadas, particularmente en dispositivos más antiguos, esta solución no siempre funcionaba. Por ejemplo, una preferencia como esta aún podría tener sangría:

com.example.preference.SomeCustomPreference
    android:id="@+id/some_custom_preference"
    android:name="Custom Preference"
    android:key="@string/custom_pref_key"
    android:summary="@string/custom_pref_summary"
    android:title="@string/preference_custom_title"
    app:iconSpaceReserved="false"

El problema se debe al uso del tercer parámetro de constructor en la clase de preferencia personalizada. Si pasa ese tercer parámetro, el elemento de la lista se sangrará. Si lo omite, la lista se alineará correctamente:

class SomeCustomPreference
@JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyle: Int = android.R.attr.someCustomPreferenceStyle
) : DialogPreference(context, attrs, defStyle) {

    override fun getDialogLayoutResource(): Int {
        return R.layout.my_layout
    }
}

En lugar de eso, usa esto:

class SomeCustomPreference
@JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null
) : DialogPreference(context, attrs) {

    override fun getDialogLayoutResource(): Int {
        return R.layout.my_layout
    }
}

El crédito por esto es para @CommonsWare en esta publicación muy antigua .

AndroidDev
fuente
11
¡No sé quién eres, pero te encontraré y te lo agradeceré! :)
David
Ésta es la forma correcta de hacerlo; no hay necesidad de clases personalizadas, supongo. Android está reservando un espacio para los íconos de forma predeterminada ahora, parece.
Blogger
1
Esto también funciona para el PreferenceFragmentCompatsoporte lib 28.0.0. ¡Excelente!
jayeffkay
7
¿Qué pasa con la categoría de preferencia? La categoría de preferencia no parece estar funcionando
jknair
1
La categoría de preferencia funciona bien en androidx.preference: preferencia: 1.1.0
kalandar
53

He informado sobre este problema aquí (también puede consultar mi proyecto de solución allí), pero por ahora, he encontrado una manera un poco hack-y, pero fácil de superar esto:

  • Para PreferenceCategory, configuré el relleno inicial / izquierdo de sus diseños en 0.

  • Para otros tipos de preferencias, elijo ocultar las icon_frameen caso de que no tengan un icono.

Aquí está el código. Simplemente extiéndase de esta clase y el resto es automático:

Kotlin

abstract class BasePreferenceFragment : PreferenceFragmentCompat() {

    override fun onCreateAdapter(preferenceScreen: PreferenceScreen?): RecyclerView.Adapter<*> {
        return object : PreferenceGroupAdapter(preferenceScreen) {
            override fun onBindViewHolder(holder: PreferenceViewHolder, position: Int) {
                super.onBindViewHolder(holder, position)
                val preference = getItem(position)
                if (preference is PreferenceCategory)
                    setZeroPaddingToLayoutChildren(holder.itemView)
                else
                    holder.itemView.findViewById<View?>(R.id.icon_frame)?.visibility = if (preference.icon == null) View.GONE else View.VISIBLE
            }
        }
    }

    private fun setZeroPaddingToLayoutChildren(view: View) {
        if (view !is ViewGroup)
            return
        val childCount = view.childCount
        for (i in 0 until childCount) {
            setZeroPaddingToLayoutChildren(view.getChildAt(i))
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
                view.setPaddingRelative(0, view.paddingTop, view.paddingEnd, view.paddingBottom)
            else
                view.setPadding(0, view.paddingTop, view.paddingRight, view.paddingBottom)
        }
    }
}

Java

public abstract class BasePreferenceFragmentCompat extends PreferenceFragmentCompat {
    @Override
    protected RecyclerView.Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {
        return new PreferenceGroupAdapter(preferenceScreen) {
            @SuppressLint("RestrictedApi")
            @Override
            public void onBindViewHolder(PreferenceViewHolder holder, int position) {
                super.onBindViewHolder(holder, position);
                Preference preference = getItem(position);
                if (preference instanceof PreferenceCategory)
                    setZeroPaddingToLayoutChildren(holder.itemView);
                else {
                    View iconFrame = holder.itemView.findViewById(R.id.icon_frame);
                    if (iconFrame != null) {
                        iconFrame.setVisibility(preference.getIcon() == null ? View.GONE : View.VISIBLE);
                    }
                }
            }
        };
    }

    private void setZeroPaddingToLayoutChildren(View view) {
        if (!(view instanceof ViewGroup))
            return;
        ViewGroup viewGroup = (ViewGroup) view;
        int childCount = viewGroup.getChildCount();
        for (int i = 0; i < childCount; i++) {
            setZeroPaddingToLayoutChildren(viewGroup.getChildAt(i));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1)
                viewGroup.setPaddingRelative(0, viewGroup.getPaddingTop(), viewGroup.getPaddingEnd(), viewGroup.getPaddingBottom());
            else
                viewGroup.setPadding(0, viewGroup.getPaddingTop(), viewGroup.getPaddingRight(), viewGroup.getPaddingBottom());
        }
    }
}

Y el resultado (la muestra XML se puede encontrar aquí de esta muestra de Google , que he creado aquí para consultar):

ingrese la descripción de la imagen aquí

Este código es un poco peligroso, así que asegúrese de que en cada actualización de la biblioteca, verifique que funciona bien.

Además, es posible que no funcione bien en algunos casos especiales, como cuando define android:layoutsu propia preferencia, por lo que tendrá que modificarlo para este asunto.


Obtuve una solución mejor y más oficial:

Para cada preferencia, use app:iconSpaceReserved="false". Esto debería funcionar bien, pero por alguna razón hay un error (conocido) que no funciona para PreferenceCategory. Se informó aquí y debería corregirse en un futuro próximo.

Entonces, por ahora, puede usar una versión mixta de la solución alternativa que escribí y esta bandera.


EDITAR: Encontré otra solución. Este superará todas las preferencias y se establecerá isIconSpaceReservedpara cada una. Lamentablemente, como escribí anteriormente, si usa PreferenceCategory, lo arruina, pero debería funcionar bien si no lo usa:

Kotlin

abstract class BasePreferenceFragment : PreferenceFragmentCompat() {

    override fun setPreferenceScreen(preferenceScreen: PreferenceScreen?) {
        super.setPreferenceScreen(preferenceScreen)
        if (preferenceScreen != null) {
            val count = preferenceScreen.preferenceCount
            for (i in 0 until count)
                preferenceScreen.getPreference(i)!!.isIconSpaceReserved = false
        }
    }

Java

public class BasePreferenceFragment extends PreferenceFragmentCompat {

    @Override
    public void setPreferenceScreen(PreferenceScreen preferenceScreen) {
        super.setPreferenceScreen(preferenceScreen);
        if (preferenceScreen != null) {
            int count = preferenceScreen.getPreferenceCount();
            for (int i = 0; i < count; i++)
                preferenceScreen.getPreference(i).setIconSpaceReserved(false);
        }
    }
}

EDITAR: después de que Google finalmente arregló la biblioteca (enlace aquí ), puede establecer la bandera para cada preferencia, o usar esta solución que lo hace para todos, para usted:

abstract class BasePreferenceFragment : PreferenceFragmentCompat() {
    private fun setAllPreferencesToAvoidHavingExtraSpace(preference: Preference) {
        preference.isIconSpaceReserved = false
        if (preference is PreferenceGroup)
            for (i in 0 until preference.preferenceCount)
                setAllPreferencesToAvoidHavingExtraSpace(preference.getPreference(i))
    }

    override fun setPreferenceScreen(preferenceScreen: PreferenceScreen?) {
        if (preferenceScreen != null)
            setAllPreferencesToAvoidHavingExtraSpace(preferenceScreen)
        super.setPreferenceScreen(preferenceScreen)

    }

    override fun onCreateAdapter(preferenceScreen: PreferenceScreen?): RecyclerView.Adapter<*> =
            object : PreferenceGroupAdapter(preferenceScreen) {
                @SuppressLint("RestrictedApi")
                override fun onPreferenceHierarchyChange(preference: Preference?) {
                    if (preference != null)
                        setAllPreferencesToAvoidHavingExtraSpace(preference)
                    super.onPreferenceHierarchyChange(preference)
                }
            }
}

Simplemente extiéndalo y no tendrá el relleno inútil para sus preferencias. Proyecto de muestra aquí , donde también solicito tener una forma oficial de evitarlo, en lugar de esos trucos. Considere protagonizarlo.

desarrollador de Android
fuente
Esta es la ÚNICA solución que funciona. Tanto para bibliotecas v7 como androidx. ¡Trabajo bien hecho!
Lior Iluz
2
Ni siquiera entiendo por qué esto es una cosa. ¿Qué pasa con Google que desaprueba / elimina / bloquea API cuando no hay reemplazo o hay uno roto?
TheWanderer
1
@androiddeveloper Puedo entender eso, excepto por PreferenceCategories. Esos no deberían alinearse.
TheWanderer
@TheWanderer Bueno, preferiría que cada uno ocupara el espacio que realmente necesita, y que pudiéramos elegir qué comportamiento usar en cualquier caso.
desarrollador de Android
El error PreferenceCategory se ha corregido a partir del 5 de noviembre de 2018 en AndroidX. Lo probé después de migrar y ahora funciona como se esperaba. Consulte developer.android.com/jetpack/androidx/… . Si no desea migrar y está usando un diseño personalizado, le recomiendo usar un relleno negativo de alrededor de 120 para eliminar el espacio.
ET del
32

Solución de trabajo simple desde aquí .
Funciona en todas las preferencias sin necesidad de escribir en todas las preferencias.app:iconSpaceReserved="false"

Crear res/values-sw360dp/values-preference.xml:

<resources xmlns:tools="http://schemas.android.com/tools">
    <bool name="config_materialPreferenceIconSpaceReserved" tools:ignore="MissingDefaultResource,PrivateResource">false</bool>
    <dimen name="preference_category_padding_start" tools:ignore="MissingDefaultResource,PrivateResource">0dp</dimen>
</resources>

Las <bool>correcciones del valor por defecto de iconSpacePreservedpara todos Preference; La <dimen>fija el PreferenceCategory.

EDITAR: Si está usando androidx.preference:preference:1.1.1, no necesitará la dimensión preference_category_padding_start. Probado en Android 6-10.

t0m
fuente
Funciona para mí también. Muchas gracias. Pero no entiendo por qué tiene que estar en un directorio llamado "valores-sw360dp-v13" en lugar de solo "valores". (Ponerlo en "valores" no tiene ningún efecto para mí.) Alguien sabe por qué?
Gereon99
Solución perfecta para pantalla completa. ¿Automáticamente todo arreglado pero no sabe cómo?
Md Mohsin
7

Prueba esto:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View v = super.onCreateView(inflater, container, savedInstanceState);
    if(v != null) {
        ListView lv = (ListView) v.findViewById(android.R.id.list);
        lv.setPadding(10, 10, 10, 10);
    }
    return v;
}

Puede configurar el relleno usando: setPadding();

Sanket Shah
fuente
1
Hola @ David, gracias por la respuesta. Pero no estoy creando ninguna vista personalizada para la pantalla de preferencias. Estoy usando el predeterminado.
Dory
De acuerdo, tampoco tengo una vista personalizada. Sería bueno configurar esto para las vistas de Android.
lostintranslation
@lostintranslation Estoy de acuerdo en que no es muy lógico crear una vista personalizada solo para ese propósito, sin embargo, lo he probado y funciona muy bien.
defhlt
Lamentablemente, cuando se usa PreferenceFragmentCompat, esta ya no es la razón. El relleno (o simplemente un marco de icono) ahora es parte de las vistas de las preferencias.
desarrollador de Android
5

Si está utilizando la com.android.support:preference-v7biblioteca, asegúrese de que el tema de la actividad que aloja sus preferencias tenga un preferenceThemeconjunto para la superposición de tema de preferencia de material v14:

<item name="preferenceTheme">@style/PreferenceThemeOverlay.v14.Material</item>

mtrewartha
fuente
1
¿Alguna solución similar para cuando se usa la nueva PreferenceFragmentCompatclase?
desarrollador de Android
1
No lo he probado con eso, lo siento ... También lo uso PreferenceFragmentCompatahora, pero desde entonces he rediseñado mi pantalla de configuración e incluye íconos, lo que hace que este relleno sea deseable para mí ahora (ayuda a mantener la alineación izquierda consistente).
mtrewartha
Gracias @mtrewartha, terminé eligiendo algunos íconos de Material semi-apropiados para cada uno de mis campos de configuración para usar este espacio izquierdo en lugar de tratar de encontrar una manera de deshacerme de él
gregdev
No hay problema, ¡me alegro de haber podido ayudar a @gregdev!
mtrewartha
4

Desafortunadamente, nada de lo anterior funcionó para mí.

Respuesta corta :

Resolví esto usando márgenes negativos en el contenedor superior del diseño de preferencias personalizado.

Pasos:

  • Cree un diseño personalizado para la preferencia (por ejemplo, preferencia_categoría.xml)
  • especifique que su preferencia usa el diseño personalizado agregando android: layout param a una etiqueta de preferencia en XML
  • Aplicar márgenes negativos

Respuesta detallada:

El XML de preferencia:

    <android.support.v7.preference.PreferenceScreen
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:title="@string/settings_title" >

    <android.support.v7.preference.PreferenceCategory
        android:layout="@layout/preference_category"
        android:key="settings_list"
        android:title="@string/pref_category_settings" />
    <android.support.v7.preference.SwitchPreferenceCompat
        android:layout="@layout/preference_row"
        android:icon="@drawable/ic_nav_switch"
        android:key="pref_switch"
        android:title="@string/pref_switch_title" />

    </android.support.v7.preference.PreferenceScreen>

El diseño personalizado para la fila de preferencias que elimina los márgenes izquierdo y derecho innecesarios:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginStart="-12dp"
    android:layout_marginEnd="-8dp"
    android:minHeight="?android:attr/listPreferredItemHeight"
    android:gravity="center_vertical">

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">

        <ImageView
            android:id="@android:id/icon"
            android:layout_width="58dp"
            android:layout_height="58dp"
            android:padding="8dp"
            android:layout_gravity="center"
            android:visibility="visible" />

    </RelativeLayout>

    <RelativeLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="15dp"
        android:layout_marginEnd="6dp"
        android:layout_marginTop="6dp"
        android:layout_marginBottom="6dp"
        android:layout_weight="1">

        <TextView
            android:id="@android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:singleLine="true"
            android:textAppearance="?android:attr/textAppearanceListItem"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal" />

        <TextView
            android:id="@android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_below="@android:id/title"
            android:layout_alignStart="@android:id/title"
            android:textAppearance="?android:attr/textAppearanceListItemSecondary"
            android:textColor="?android:attr/textColorSecondary"
            android:maxLines="2"/>

    </RelativeLayout>

    <LinearLayout
        android:id="@android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="end|center_vertical"
        android:orientation="vertical">

    </LinearLayout>
</LinearLayout>

El diseño personalizado para la categoría de preferencias que elimina los márgenes izquierdo y derecho innecesarios:

<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:textColor="@color/colorAccent"
    android:textStyle="bold"
    android:textSize="12sp"
    android:gravity="center_vertical"
    android:textAllCaps="true"
    android:layout_marginStart="-4dp"
    android:layout_marginEnd="-8dp"
    android:id="@+android:id/title" />
Gord
fuente
genial, me salvaste la vida! : D
K. Kempski
Esto requiere tener un diseño para todo tipo de preferencias. ¿Dónde los encontraste? ¿Tiene una biblioteca para esto? Hice una solución alternativa aquí: stackoverflow.com/a/51568782/878126 , pero creo que su solución es más segura. Solo necesita mucho trabajo para copiar cosas ...
desarrollador de Android
Puede encontrarlo en el espejo de GitHub de AOSP: verifique los archivos xml con el prefijo preferencia_. github.com/aosp-mirror/platform_frameworks_base/tree/…
Gord
3

El relleno es causado por el padre ListViewen el que PreferenceScreencontiene su configuración. Si está utilizando a PreferenceFragmentpara crear sus Preferencias, simplemente vaya a la onActivityCreatedfunción de PreferenceFragementy haga lo siguiente para eliminar el relleno:

public void onActivityCreated(Bundle savedInstanceState) {
  super.onActivityCreated(savedInstanceState);

  View lv = getView().findViewById(android.R.id.list);
  if (lv != null) lv.setPadding(0, 0, 0, 0);
}
Helmut Schottmüller
fuente
Cuando se usa PreferenceFragmentCompat, esta ya no es la razón. El relleno (o simplemente un marco de icono) ahora es parte de las vistas de las preferencias.
desarrollador de Android
3

Cambie el tema de preferencias de esta manera. Asegúrese de utilizar la última versión de la biblioteca de preferenciasandroidx.preference 1.1.0-alpha01

<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    <item name="preferenceTheme">@style/CustomPreferenceTheme</item>
</style>

<style name="CustomPreferenceTheme" parent="@style/PreferenceThemeOverlay">
    <item name="preferenceFragmentCompatStyle">@style/CustomPreferenceFragmentCompatStyle</item>
    <item name="preferenceCategoryStyle">@style/CustomPreferenceCategory</item>
    <item name="preferenceStyle">@style/CustomPreference</item>
    <item name="checkBoxPreferenceStyle">@style/CustomCheckBoxPreference</item>
    <item name="dialogPreferenceStyle">@style/CustomDialogPreference</item>
    <item name="switchPreferenceCompatStyle">@style/CustomSwitchPreferenceCompat</item>  <!-- for pre lollipop(v21) -->
    <item name="switchPreferenceStyle">@style/CustomSwitchPreference</item>
</style>

 <style name="CustomPreferenceFragmentCompatStyle" parent="@style/PreferenceFragment.Material">
    <item name="android:layout">@layout/fragment_settings</item>
</style>

<style name="CustomPreferenceCategory" parent="Preference.Category.Material">
    <item name="iconSpaceReserved">false</item>
</style>

<style name="CustomPreference" parent="Preference.Material">
    <item name="iconSpaceReserved">false</item>
</style>

<style name="CustomCheckBoxPreference" parent="Preference.CheckBoxPreference.Material">
    <item name="iconSpaceReserved">false</item>
</style>

<style name="CustomDialogPreference" parent="Preference.DialogPreference.Material">
    <item name="iconSpaceReserved">false</item>
</style>

<style name="CustomSwitchPreferenceCompat" parent="Preference.SwitchPreferenceCompat.Material">
    <item name="iconSpaceReserved">false</item>
</style>

<style name="CustomSwitchPreference" parent="Preference.SwitchPreference.Material">
    <item name="iconSpaceReserved">false</item>
</style>
Libin
fuente
2
Desafortunadamente, encontré un error crítico de androidx.preference:preference:1.1.0-alpha01. La rotación del dispositivo en cualquier segunda pila de fragmentos de la aplicación provocará un bloqueo. Espero que se solucione en versiones posteriores. Vuelvo a androidx.preference:preference:1.0.0.
Joonsoo
2
@Joonsoo: Puedo confirmar. Recibía un vago error de "fallo de estado al guardar fragmentos". Por lo tanto, permanezca en la versión 1.0.0 hasta que se solucione y, mientras tanto, siga esta solución para manejar los márgenes.
Ganesh Mohan
iconSpaceReserved solo disponible para la versión 26 y más.
realpranav
2

compilar 'com.android.support:preference-v7:24.2.1'

Use PreferenceFragmentCompat puede hacer esto:

1.Defina un PreferenceGroupAdapter:

    static class CustomAdapter extends PreferenceGroupAdapter {

    public CustomAdapter(PreferenceGroup preferenceGroup) {
      super(preferenceGroup);
    }

    @Override
    public PreferenceViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
      PreferenceViewHolder preferenceViewHolder = super.onCreateViewHolder(parent, viewType);
      parent.setPadding(0, 0, 0, 0);
      preferenceViewHolder.itemView.setPadding(20, 5, 20, 5);
      return preferenceViewHolder;
    }
  }

2.Override el método onCreateAdapter de PreferenceFragmentCompat:

   @Override
   protected Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {

      return new CustomAdapter(preferenceScreen);
   }

Use style.xml puede hacer esto:

1.valores / estilos.xml:

  <style name="customPreferenceThemeOverlay" parent="@style/PreferenceThemeOverlay">
    <item name="preferenceFragmentListStyle">@style/customPreferenceFragmentList</item>
  </style>
  <style name="customPreferenceFragmentList">
    <item name="android:paddingLeft">0dp</item>
    <item name="android:paddingRight">0dp</item>
  </style>

2.valores-v17 / styles.xml:

  <style name="customPreferenceFragmentList">
    <item name="android:paddingLeft">0dp</item>
    <item name="android:paddingRight">0dp</item>
    <item name="android:paddingStart">0dp</item>
    <item name="android:paddingEnd">0dp</item>
  </style>

3.valor / styles.xml:

  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    ... ...
    <item name="preferenceTheme">@style/customPreferenceThemeOverlay</item>
  </style>
zonda
fuente
¿Funciona esto para todas las preferencias? ¿Tiene una biblioteca para esto?
desarrollador de Android
1

Ninguna de las respuestas anteriores funcionó, tuve que copiar el diseño de preferencias , crear un nuevo archivo de diseño como custom_preference.xml, anular el contenido del diseño configurando la visibilidad del marco del icono en GONE . Y luego, en pref.xml, configure el diseño para la preferencia para usar este diseño personalizado.

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    >
    <android.support.v7.preference.EditTextPreference
        android:title="@string/pref_label"
        android:hint="@string/pref_hint"
        android:key="@string/pref_key"
        android:inputType="text"
        android:singleLine="true"
        android:layout="@layout/custom_preference_layout"
        />
</PreferenceScreen>
guardagujas
fuente
0

El 'relleno' se inicia en PreferenceFrameLayout.java:

public PreferenceFrameLayout(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    TypedArray a = context.obtainStyledAttributes(attrs,
            com.android.internal.R.styleable.PreferenceFrameLayout, defStyle, 0);

    float density = context.getResources().getDisplayMetrics().density;
    int defaultBorderTop = (int) (density * DEFAULT_BORDER_TOP + 0.5f);
    int defaultBottomPadding = (int) (density * DEFAULT_BORDER_BOTTOM + 0.5f);
    int defaultLeftPadding = (int) (density * DEFAULT_BORDER_LEFT + 0.5f);
    int defaultRightPadding = (int) (density * DEFAULT_BORDER_RIGHT + 0.5f);

    mBorderTop = a.getDimensionPixelSize(
            com.android.internal.R.styleable.PreferenceFrameLayout_borderTop,
            defaultBorderTop);
    mBorderBottom = a.getDimensionPixelSize(
            com.android.internal.R.styleable.PreferenceFrameLayout_borderBottom,
            defaultBottomPadding);
    mBorderLeft = a.getDimensionPixelSize(
            com.android.internal.R.styleable.PreferenceFrameLayout_borderLeft,
            defaultLeftPadding);
    mBorderRight = a.getDimensionPixelSize(
            com.android.internal.R.styleable.PreferenceFrameLayout_borderRight,
            defaultRightPadding);

    a.recycle();
}

Si sabe cómo anular los estilos definidos por Android, probablemente pueda resolver esto. Sin embargo, no es muy sencillo.

Jayeffkay
fuente
Esta es una respuesta horrible, 'aquí está el código, pero no estoy seguro de cómo hacerlo' no es una respuesta.
lostintranslation
Estoy de acuerdo en que esto no es una respuesta, pero no estoy seguro de cómo compartir esta información relevante. El espacio que se ve en la pregunta es agregado por el marco, como se ve arriba, y aparentemente no hay opción para eliminarlo. Es decir, si no es posible anular "com.android.internal.R.styleable.PreferenceFrameLayout". Y eso no sé cómo.
jayeffkay
¿Puede dar una mejor respuesta? ¿Quizás Github para mostrar cómo usarlo para todas las preferencias?
desarrollador de Android
0

Intento usar

android:icon="@null"

con CheckBoxPreferenceen Android 4.4 pero no puede rellenar desde la izquierda. Engañé usar un pequeño ícono transparente y agregar

android:icon="@drawable/transparent_icon" 

y me parece que funciona. Espero que pueda ayudar. Gracias.

Bao Doan
fuente
¿Qué hay en el "icono_transparente"? Probé un dibujable vacío, pero no ayudó ...
desarrollador de Android
0

No sé si es demasiado tarde para una respuesta, pero hoy tuve el mismo problema y ninguna de estas respuestas me ayuda.

Entonces usé esta solución:

En mi DisclaimerPreferenceeso extends Preference, anulo el onBindView(View view)método de esta manera:

    @Override protected void onBindView(View view) {
        super.onBindView(view);
        if(view instanceof ViewGroup){
            ViewGroup vg = (ViewGroup)view;
            View currView;
            for(int i=0; i<vg.getChildCount(); i++){
               currView = vg.getChildAt(i);
               if (currView instanceof RelativeLayout)
                   currView.setVisibility(View.GONE);
            }
         }
    }

La clave es establecer el RelativeLayoutinterior de la Vista principal como GONE. Por favor avíseme si algo anda mal :)

Francesco Florio
fuente
1
Lamentablemente, onBindViewya no está disponible en el nuevo PreferenceFragmentCompat. En su lugar, puede usar onCreateAdaptery onBindViewHolder, como escribí aquí: stackoverflow.com/a/51568782/878126
desarrollador de Android
0

Aparentemente, agregar android:layout="@null"a su preferencia en xml haría el truco. Pero en consecuencia, también aumentará el tamaño del título.

John
fuente
Fácil de usar, pero como escribió, arruina el estilo de todas las preferencias ... :(. Tal vez pruebe mi solución alternativa de hack-y: stackoverflow.com/a/51568782/878126
desarrollador de Android
0

Simplemente agregue este attirubte en la etiqueta de preferencia

app:iconSpaceReserved="false"
Lasitha Lakmal
fuente
-1

Pregunté hace bastante tiempo, pero lo que me ayudó a resolver esto fueron los márgenes negativos, sin necesidad de archivos personalizados.

Cuando crea su clase SettingsActivity (que tiene el PreferenceFragment adentro), simplemente configura su diseño para que sea un fragmento y agregue un margen negativo.

settings_activity:

<?xml version="1.0" encoding="utf-8"?>
<fragment
    android:layout_marginLeft="-40dp"
    android:name="com.example.USER.APPNAME.SettingsActivity$PrefsFragment"
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.USER.APPNAME.SettingsActivity">
</fragment>
Chico
fuente
-5

Agregar android:defaultValue="false"a su <PreferenceScreen [...]etiqueta:

<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:defaultValue="false">

MDXDave
fuente