PreferenceFragmentCompat имеет отступы в PreferenceCategory, от которых я не могу избавиться

Итак, я пытался создать действие настроек с помощью androidx.preference.PreferenceFragmentCompat, и все работает нормально.

Однако по какой-то причине есть некоторые отступы как в категориях предпочтений, так и в самих предпочтениях. Мне удалось избавиться от отступов в настройках с помощью app: iconSpaceReserved = "false", но, похоже, это не работает с категориями.

Изображение

Я пробовал все различные темы, PreferenceThemeOverlay.v14.Material и т. д., Но они, похоже, не имеют значения

Вот мой код на все!

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>

Мои зависимости ...

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'

Это было исправлено и должно быть выпущено: Issuesetracker.google.com/issues/111662669

devrocca 03.08.2018 11:05

@devrocca: Но есть еще одна серьезная проблема с новой выпущенной версией androidx.preference.preference: 1.1.0-alpha01. Пожалуйста, прочтите этот комментарий.

Ganesh Mohan 14.11.2018 08:17
37
2
7 096
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Решил обходным путем со стилями. Работает с PreferenceCategory.

Для предпочтений просто используйте: 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] скопирован из "@ layout / preference_category_material".

Замените @ dimen / preference_category_padding_start на android: paddingLeft = "0dp". Добавьте собственный цвет @ 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>

При использовании androidx необходимо заменить android.support.v7.internal.widget.PreferenceImageView только на ImageView для кода для компиляции.

TROD 22.10.2018 11:24

это не работает, если вы используете android: iconSpaceReserved = "false" в XML. Но это работает, если вы используете setIconSpaceReserved (false)

qkx 12.03.2019 11:33

На самом деле есть лучший способ исправить это, в том числе с переопределением ресурсов:

Создайте 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>

<bool> фиксирует значение по умолчанию iconSpacePreserved для всех Preference; <dimen> исправляет PreferenceCategory.

Обновлено: Если вы используете androidx.preference:preference:1.1.0-alpha01 или выше, вам не понадобится исправление preference_category_padding_start, и будет достаточно только config_materialPreferenceIconSpaceReserved.

Лучшее решение, поскольку оно сразу исправляет настройки ВСЕ

and_dev 12.11.2018 11:09

Исправлен весь экран. Идеально!

Md Mohsin 07.11.2019 12:07

Это круто, он исправляет каждый экран настроек! Жаль, что даже если Google исправил проблему для AndroidX, официального исправления для библиотеки поддержки нет.

Balázs Gerlei 14.02.2020 14:29

почему мы здесь используем v13?

Bouh 11.04.2021 00:14

Новичок здесь - где именно вы используете values-preference.xml в PreferenceScreen, чтобы получить это исправление?

James Poulose 11.04.2021 04:06

@Bouh Поскольку исходное значение было установлено на true в разделе values-sw360dp-v13 в androidx.preference, поэтому мы сбрасываем его обратно на false в том же каталоге.

Hai Zhang 12.04.2021 01:30

@James Poulose Достаточно просто создать файл с указанным выше содержимым, он читается компилятором ресурсов Android и автоматически переопределяет конфигурацию.

Hai Zhang 12.04.2021 01:31

Исправление в настоящее время выпущено в альфа-версии. Ты можешь использовать

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

или последний выпущенный в вашем build.gradle

Если вы используете AndroidX, вы можете добавить / удалить дополнительные отступы, просто добавив следующий атрибут в свои предпочтения и категории предпочтений в XML:

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

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

</androidx.preference.PreferenceScreen>

true добавляет дополнительное заполнение, false удаляет его.

Ответ принят как подходящий

Эта ошибка была исправлена ​​в последней версии предпочтений androidx

Попробуйте следовать зависимостям в yout Build.Gradle

    implementation 'androidx.preference:preference:1.1.0'

Вместо того, чтобы возиться со стилями, мне было проще сделать это программно:

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

Другие вопросы по теме