PreferenceFragmentCompat has padding on PreferenceCategory that I can't get rid of
Asked Answered
K

7

39

So I've been trying to create a settings activity using androidx.preference.PreferenceFragmentCompat and it's all working fine.

However for some reason there is some padding present on both the preference categories and the preferences themselves. I managed to get rid of the padding on the preferences by using app:iconSpaceReserved="false" but this doesn't seem to work on the categories.

Image

I've tried all the various themes, PreferenceThemeOverlay.v14.Material etc but they don't seem to make a difference

Here is my code for everything!

SettingsActivity.java

import android.os.Bundle;

import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;

public class SettingsActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_settings);

        Toolbar toolbar = findViewById(R.id.settings_toolbar);
        setSupportActionBar(toolbar);
        ActionBar actionBar = getSupportActionBar();
        if (actionBar != null) {
            actionBar.setDisplayHomeAsUpEnabled(true);
            actionBar.setDisplayShowTitleEnabled(false);
        }

    }
}

activity_settings.xml

<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".SettingsActivity">

    <androidx.appcompat.widget.Toolbar
        android:id="@+id/settings_toolbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <TextView
            style="@style/ToolbarTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="@string/title_settings"
            android:textColor="@color/font_dark_primary" />

    </androidx.appcompat.widget.Toolbar>

    <fragment
        android:name="com.henrytwist8gmail.fullcart.SettingsTestFragment"
        android:tag="settings_fragment"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintTop_toBottomOf="@id/settings_toolbar" />

</androidx.constraintlayout.widget.ConstraintLayout>

SettingsTestFragment.java

import android.os.Bundle;

import androidx.preference.PreferenceFragmentCompat;

public class SettingsTestFragment extends PreferenceFragmentCompat {

    @Override
    public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {

        setPreferencesFromResource(R.xml.preferences_test, rootKey);
    }
}

preferences_test.xml

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

    <PreferenceCategory android:title="test" >

        <Preference android:title="testPref" />
    </PreferenceCategory>

</PreferenceScreen>

My dependencies are...

implementation 'com.google.android.material:material:1.0.0-beta01'
implementation 'androidx.preference:preference:1.0.0-beta01'
implementation 'androidx.constraintlayout:constraintlayout:1.1.2'
Kapoor answered 25/7, 2018 at 12:20 Comment(2)
This has been fixed and is due to be released: issuetracker.google.com/issues/111662669Im
@devrocca: But there's an another major issue with the new androidx.preference.preference:1.1.0-alpha01 released version. Please read this comment.Variometer
G
1

This Bug has been Fixed in Latest Release of androidx preference

Try Following Dependency in yout Build.Gradle

    implementation 'androidx.preference:preference:1.1.0'
Glazing answered 19/11, 2019 at 12:43 Comment(0)
S
85

Actually there is a better hack to fix this, also with resource overriding:

Create res/values-sw360dp-v13/values-preference.xml:

<?xml version="1.0" encoding="utf-8"?>

<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.0-alpha01 or above, you won't need the preference_category_padding_start fix and config_materialPreferenceIconSpaceReserved only will be enough.

Shaeffer answered 24/10, 2018 at 3:27 Comment(7)
Best solution as it fixes ALL preferences at onceRebound
Whole screen has been fixed. Perfect!Submerse
This is awesome, it does fix every Preference screen! It's a shame that even if Google did fix the issue for AndroidX, there is no official fix for Support Library.Pithecanthropus
why we use v13 here?Milling
Newbie here - where exactly do you use values-preference.xml in the PreferenceScreen to get this fix?Luxuriance
@Milling Because the original value was set to true under values-sw360dp-v13 in androidx.preference, so we reset it back to false under the same directory.Shaeffer
@James Poulose Just creating the file with the content above will be enough, it is read by Android resource compiler and overrides the configuration automatically.Shaeffer
R
6

I solved by a workaround with styles. It works with PreferenceCategory.

For Preference just use: app:iconSpaceReserved="false".

[styles.xml]

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

<style name="AppPreferenceTheme" parent="@style/PreferenceThemeOverlay.v14.Material">
    <item name="preferenceCategoryStyle">@style/FixForPreferenceCategoryStyle</item>

    <!-- <item name="android:textColor">#ffffffff</item> -->
    <!-- <item name="android:textColorSecondary">#b3ffffff</item> -->
    <!--when the check box is checked-->
    <!--<item name="colorControlNormal">#FF4081</item>-->
    <!--when the check box is unchecked -->
    <!--<item name="colorControlActivated">#81FF40</item>-->
</style>

<style name="FixForPreferenceCategoryStyle" parent="@style/Preference.Category.Material">
    <item name="android:layout">@layout/_preference_category_material</item>
</style>

<color name="_preference_fallback_accent_color">@color/colorAccent</color>

[_preference_category_material.xml] copied from "@layout/preference_category_material".

Replace @dimen/preference_category_padding_start with android:paddingLeft="0dp". Add custom color @color/_preference_fallback_accent_color.

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_marginBottom="8dp"
    android:layout_marginTop="8dp"
    android:layout_marginLeft="?android:attr/listPreferredItemPaddingLeft">

    <LinearLayout
        android:id="@+id/icon_frame"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="start|center_vertical"
        android:orientation="horizontal">
        <android.support.v7.internal.widget.PreferenceImageView
            android:id="@android:id/icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            app:maxHeight="18dp"
            app:maxWidth="18dp"/>
    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        android:paddingLeft="0dp"><!-- SET to 0dp -->
        <!--android:paddingLeft="@dimen/preference_category_padding_start"-->

        <TextView
            android:id="@android:id/title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="16dp"
            android:paddingRight="?android:attr/listPreferredItemPaddingRight"
            android:textAlignment="viewStart"
            android:textColor="@color/_preference_fallback_accent_color"/>
        <TextView
            android:id="@android:id/summary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="end"
            android:singleLine="true"
            android:textColor="?android:attr/textColorSecondary"/>
    </LinearLayout>

</FrameLayout>
Ruppert answered 30/9, 2018 at 0:19 Comment(2)
If using androidx, need to replace android.support.v7.internal.widget.PreferenceImageView with just ImageView for code to compileChagall
this doesnt work if you use android:iconSpaceReserved="false" in XML. But it works if you use setIconSpaceReserved (false)Threesquare
T
5

If using AndroidX, you can add/remove extra padding by simply adding the following attribute to your Preferences and Preference Categories in XML:

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

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

</androidx.preference.PreferenceScreen>

true adds extra padding, false removes it.

Tympanites answered 4/5, 2019 at 21:56 Comment(0)
E
3

The fix is currently released in alpha. You can use

implementation 'androidx.preference:preference:1.1.0-alpha01'

or the latest released one in your build.gradle

Eeg answered 13/11, 2018 at 16:43 Comment(0)
I
3

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

<Preference
...
app:iconSpaceReserved="false/true"
.../>
Inelegance answered 25/4, 2022 at 8:25 Comment(1)
Welcome to Stack Overflow! Thanks for your answer, but this is a near-exact copy of an answer above which was posted three years ago! https://mcmap.net/q/176921/-preferencefragmentcompat-has-padding-on-preferencecategory-that-i-can-39-t-get-rid-ofKapoor
G
1

This Bug has been Fixed in Latest Release of androidx preference

Try Following Dependency in yout Build.Gradle

    implementation 'androidx.preference:preference:1.1.0'
Glazing answered 19/11, 2019 at 12:43 Comment(0)
D
1

Rather than mucking with styles, I found it easier to just do it programmatically:

private fun Preference.removeIconSpace() {
    setIconSpaceReserved(false)
    if (this is PreferenceGroup) {
        for (i in 0 until preferenceCount) {
            getPreference(i).removeIconSpace()
        }
    }
}

override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
    setPreferencesFromResource(R.xml.settings, rootKey)
    …
    preferenceScreen.removeIconSpace()
}
Dukey answered 14/10, 2020 at 15:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.