99

I am facing very weird problem in designing preference screen. Though I am not giving any margin in layout,it is leaving some space in left.

As you can see in image below: enter image description here

XML:

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

Am I doing something wrong in adding check-box preference in screen?

android developer
  • 114,585
  • 152
  • 739
  • 1,270
Dory
  • 7,462
  • 7
  • 33
  • 55

17 Answers17

181

Updating this for androidx.

After a lot of experimentation, I resolved this issue by adding this to each preference that had the excess indentation:

app:iconSpaceReserved="false"

Of course, you'll also need to add this to the PreferenceScreen declaration itself at the top of your xml:

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

Follow Up For Custom Preferences

I noticed that in the case of custom preferences, particularly on older devices, this solution wasn't always working. For example, a preference like this could still be indented:

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"

The problem traces to the usage of the third constructor parameter in the custom preference class. If you pass that third parameter, the list item will be indented. If you omit it, the list will be aligned correctly:

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

Instead of that, use this:

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

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

Credit for this goes to @CommonsWare in this very old post.

AndroidDev
  • 20,466
  • 42
  • 148
  • 239
  • 13
    i don't know who are you but i'll find you and thank it for you! :) – David Dec 06 '18 at 10:54
  • This is the correct way to go; no need of custom classes I guess. Android is reserving a space for icons by default now it seems. – Padmal Dec 15 '18 at 19:01
  • 1
    This also works for `PreferenceFragmentCompat` of support lib `28.0.0`. Great! – jayeffkay Jan 03 '19 at 12:08
  • 7
    What about preference category? Preference category doesn't seem to be working – jknair0 Jun 03 '19 at 06:39
  • Even not available in older version from 26. – Pranav P Aug 21 '19 at 09:51
  • 1
    Preference Category working fine in androidx.preference:preference:1.1.0 – kalandar Oct 18 '19 at 09:24
  • @PranavPatel Your namespace should be `app` instead of `android`, it is compatible with older versions. – zeleven Feb 07 '20 at 01:11
  • In order for this to work for me, I had to also explicitly set my icon to null in my xml file. `android:icon="@null"`. My preferences were getting a default icon from somewhere else. – Dave May 11 '20 at 19:55
54

I've reported about this issue here (you can also check my workaround project there), but for now, I've found a bit hack-y, yet easy way to overcome this:

  • For PreferenceCategory, I set the start/left padding of its layouts to 0.

  • For other types of preferences, I choose to hide the icon_frame in case they don't have an icon.

Here's the code. Just extend from this class and the rest is automatic :

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

And the result (XML sample can be found here of this Google sample, which I've created here to check out) :

enter image description here

This code is a bit dangerous, so make sure that upon each update of the library, you check that it works fine.

Also, it might not work well on some special cases, such as when you define android:layout of your own for the preference, so you will have to modify it for this matter.


Got a better, more official solution:

For each preference, use app:iconSpaceReserved="false" . This should work fine, but for some reason there is a (known) bug that it doesn't work for PreferenceCategory. It was reported here, and should be fixed in the near future.

So for now you can use a mix version of the workaround I wrote and this flag.


EDIT: Found yet another solution. This one will get over all of the preferences, and set isIconSpaceReserved for each. Sadly, as I've written above, if you use PreferenceCategory, it ruins it, but it should work fine if you don't use it:

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

EDIT: after Google finally fixed the library (link here), you can set the flag for each preference, or use this solution which does it for all, for you :

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

Just extend from it, and you won't have the useless padding for your preferences. Sample project here, where I also request to have an official way to avoid it, instead of those tricks. Please consider starring it.

android developer
  • 114,585
  • 152
  • 739
  • 1,270
  • This is the ONLY solution that works. Both for v7 and androidx libraries. Job well done! – Lior Iluz Aug 23 '18 at 07:29
  • 2
    I don't even understand why this is a thing. What's with Google deprecating/removing/blocking APIs when there's either no replacement or a broken one? – TheWanderer Oct 28 '18 at 14:50
  • 1
    @androiddeveloper I can understand that, except for PreferenceCategories. Those shouldn't align. – TheWanderer Oct 28 '18 at 17:55
  • @TheWanderer Well I would prefer if each would take the space it really needs, and that we could choose which behavior to use in any case. – android developer Oct 28 '18 at 18:57
  • The PreferenceCategory bug has been fixed as of November 5th, 2018 on AndroidX. I've tested after migrating and it now works as expected. See https://developer.android.com/jetpack/androidx/androidx-rn#2018-nov-preference. If you do not wish to migrate and are using a custom layout, I recommend using a negative padding of around 120 to remove the gap. – E.T. Nov 26 '18 at 17:49
  • @E.T. That's correct. Added a new solution based on it, to be able to set it for all preferences. – android developer Nov 26 '18 at 20:35
  • how to override `onPreferenceHierarchyChange` on java – Emmanuel Mtali Aug 27 '19 at 16:10
  • @EmmanuelMtali Just write it with the same way it's declared on Java. I think it should work. – android developer Aug 27 '19 at 18:48
  • why override onCreateAdapter? does this cover the creation of preferences created via code vs xml? – ShellDude Dec 31 '19 at 20:03
  • @ShellDude I don't remember. In my code I don't use this part, so I think it's for the case of dynamically adding/removing them – android developer Dec 31 '19 at 22:41
  • @androiddeveloper is there a way or have you tested something without the use of the library group restricted API `PreferenceGroupAdapter` in Java? – Bruno Bieri Jul 15 '20 at 12:03
  • @BrunoBieri Yes. Use the other solutions I wrote. Set isIconSpaceReserved for each, or extend each preference and set it there (not sure if possible, so start from a simple one). You can also star the requests from Google to make it easier: https://issuetracker.google.com/issues/161381698 https://issuetracker.google.com/issues/116170936. Maybe you could extend from PreferenceGroup to have it set this value for each of its children, too. – android developer Jul 16 '20 at 06:55
37

Simple working solution from here.
It works across all preferences without need write to all preferences app:iconSpaceReserved="false"

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

The <bool> fixes the default value of iconSpacePreserved for all Preference; The <dimen> fixes the PreferenceCategory.

EDIT: If you are using androidx.preference:preference:1.1.1, you won't need the dimen preference_category_padding_start. Tested on Android 6-10.

t0m
  • 3,004
  • 31
  • 53
  • 1
    Works for me as well. Thank you very much. But I don't understand why it has to be in a directory called "values-sw360dp-v13" instead of just "values". (Placing it in "values" has no effect for me.) Someone knows why? – Gereon99 Sep 17 '19 at 08:22
  • Perfect solution for whole screen. Automatically all things fixed but don't know how? – Md Mohsin Nov 07 '19 at 11:08
5

Unfortunately, nothing from above worked for me.

Short answer:

I solved this by using a negative margins on the uppermost container of the custom preference layout.

Steps:

  • Create a custom layout for the preference (e.g. preference_category.xml)
  • specify that your preference uses the custom layout by adding android:layout param to a preference tag in XML
  • Apply negative margins

Detailed answer:

The preference XML:

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

The custom layout for preference row which removes unnecessary left and right margins:

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

The custom layout for preference category which removes unnecessary left and right margins:

<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
  • 161
  • 2
  • 6
  • This requires having a layout for all types of preferences. Where did you find them? Do you have a library for this? I've made a hack-y workaround here: https://stackoverflow.com/a/51568782/878126, but I think your solution is safer. Just needs a lot of work copying things... – android developer Jul 28 '18 at 07:09
  • You can find it on GitHub mirror of AOSP: check the xml files with preference_ prefix. https://github.com/aosp-mirror/platform_frameworks_base/tree/82834baa358f55acb542e17da828b2d497cf8332/core/res/res/layout – Gord Jul 30 '18 at 14:47
5

If you're using the com.android.support:preference-v7 library, make sure the theme for the activity that's hosting your preferences has a preferenceTheme set to the v14 Material preference theme overlay:

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

mtrewartha
  • 761
  • 7
  • 18
  • 1
    Any similar solution for when using the new `PreferenceFragmentCompat` class ? – android developer Jul 28 '18 at 07:09
  • 1
    Haven't tried it with that, sorry... I use `PreferenceFragmentCompat` now as well, but I've since restyled my settings screen and it includes icons, which make this padding desirable for me now (it helps keep left alignment consistent). – mtrewartha Jul 30 '18 at 18:46
  • Thanks @mtrewartha, I ended up just choosing some semi-appropriate Material icons for each of my setting fields to put this left spacing to use rather than trying to find a way to get rid of it – gregdev Feb 10 '19 at 01:08
  • No prob, glad I could help @gregdev! – mtrewartha Feb 18 '19 at 15:33
4

Change the preference theme like this . Make sure to use the latest version of the preference library androidx.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>
Joonsoo
  • 788
  • 1
  • 13
  • 15
Libin
  • 16,967
  • 7
  • 61
  • 83
  • 2
    Unfortunately, I found a critical bug of `androidx.preference:preference:1.1.0-alpha01`. Device rotation on any second fragment stack in the app will cause a crash. I hope it will be fixed in later versions. I go back to `androidx.preference:preference:1.0.0`. – Joonsoo Nov 12 '18 at 07:50
  • 2
    @Joonsoo: Can confirm. Was getting some vague "fragment saving state failure" error. So staying on version 1.0.0 until it gets fixed and following [this solution](https://stackoverflow.com/a/52960668) in the meantime to handle the margins. – Ganesh Mohan Nov 14 '18 at 07:11
  • 1
    iconSpaceReserved only available for version26 and more. – Pranav P Aug 21 '19 at 09:51
3

The padding is caused by the parent ListView in the PreferenceScreen containing your settings. If you are using a PreferenceFragment to create your Preferences, just go to the onActivityCreated function of the PreferenceFragement and do the following to remove the padding:

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);
}
  • When using `PreferenceFragmentCompat`, this is not the reason anymore. The padding (or just an icon frame) now is a part of the views of the preferences. – android developer Jul 28 '18 at 07:10
2

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

Use PreferenceFragmentCompat can do this:

1.Define a 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 PreferenceFragmentCompat's onCreateAdapter method:

   @Override
   protected Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {

      return new CustomAdapter(preferenceScreen);
   }

Use style.xml can do this:

1.values/styles.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.values-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.value/styles.xml:

  <style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
    <!-- Customize your theme here. -->
    ... ...
    <item name="preferenceTheme">@style/customPreferenceThemeOverlay</item>
  </style>
zonda
  • 850
  • 7
  • 14
2

Just add this attirubte in the preference tag

app:iconSpaceReserved="false"
Lasitha Lakmal
  • 486
  • 4
  • 17
1

None of the above answer worked, I had to copy the preference layout, create a new layout file such as custom_preference.xml, override the layout content by setting the visibility of the icon frame to GONE. And then in the pref.xml, set the layout for the preference to use this custom layout.

<?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>
s-hunter
  • 24,172
  • 16
  • 88
  • 130
0

The 'padding' is initiated in 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();
}

If you know how to override styles defined by Android, you could probably solve this. It is not very straight forward however.

jayeffkay
  • 1,229
  • 1
  • 16
  • 22
  • This is a horrible answer, 'here is the code, but I am not sure how to do it' is not an answer. – lostintranslation Mar 24 '14 at 15:14
  • I agree this is not an answer, but I am unsure on how to otherwise share this relevant information. The space seen in the question is added by the framework, as seen above, and apparently there is no option to remove it. I.e. if it is not possible to override "com.android.internal.R.styleable.PreferenceFrameLayout". And that I don't know how to. – jayeffkay Mar 25 '14 at 13:12
  • Can you please provide a better answer? Maybe Github to show how to use it for all preferences? – android developer Jul 28 '18 at 07:11
0

I try using

android:icon="@null"

with CheckBoxPreference in Android 4.4 but can't padding from left. I tricked use a small transparent icon and add

android:icon="@drawable/transparent_icon" 

and it seems work for me. I hope it can help. Thanks.

Uniruddh
  • 4,427
  • 3
  • 52
  • 86
Bao Doan
  • 126
  • 1
  • 9
0

I don't know if it's too late for an answer but today I had the same problem and nothing of this answers help me.

So I used this solution:

In my DisclaimerPreference that extends Preference, I ovveride the onBindView(View view) method in this way:

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

The key is to set the RelativeLayout inside the main View as GONE. Please let me know if something is wrong :)

Francesco Florio
  • 1,184
  • 14
  • 16
  • 1
    Sadly , `onBindView` isn't available anymore in the new `PreferenceFragmentCompat` . Instead, you can use `onCreateAdapter` and `onBindViewHolder`, as I wrote here: https://stackoverflow.com/a/51568782/878126 – android developer Jul 28 '18 at 07:05
0

Apparently, adding android:layout="@null"to your preference in xml would do the trick. But consequently, it will also make title size larger..

John
  • 941
  • 8
  • 17
  • Easy to use this, but as you wrote, it ruins the style of all preferences... :( . Maybe try my hack-y workaround : https://stackoverflow.com/a/51568782/878126 – android developer Jul 28 '18 at 07:06
0

Asked quite a while ago, but what helped me solve this was negative margins, no need for custom files.

When you create your SettingsActivity class (which has the PreferenceFragment inside), you simply set it's layout to be a fragment and add a negative margin.

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>
Guy
  • 145
  • 3
  • 12
0

If you are using AndroidX, you can add/remove extra padding by simply adding the following attribute.

 <Preference
    ...
    app:iconSpaceReserved="false/true"
    .../>
-5

Add android:defaultValue="false" to your <PreferenceScreen [...] Tag:

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

MDXDave
  • 181
  • 1
  • 13