Android: So entfernen Sie Ränder / Auffüllungen im Einstellungsbildschirm

79

Ich habe ein sehr seltsames Problem beim Entwerfen des Einstellungsbildschirms. Obwohl ich im Layout keinen Spielraum gebe, lässt es links etwas Platz.

Wie Sie im Bild unten sehen können: Geben Sie hier die Bildbeschreibung ein

XML:

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

Mache ich etwas falsch, wenn ich die Kontrollkästcheneinstellungen auf dem Bildschirm hinzufüge?

Dory
quelle
Sie können Ihre Antwort hier finden
Miral
Hey Miral, danke für die Antwort. Aber ich erstelle kein benutzerdefiniertes Layout für den Einstellungsbildschirm
Dory
Können Sie uns Ihre Layoutdatei zeigen?
Robin Dijkhof
<PreferenceScreen xmlns: android = " schemas.android.com/apk/res/android "> <CheckBoxPreference android: defaultValue = "false" android: key = "prefSync" android: title = "Auto Sync" /> </ PreferenceScreen> Hier ist Code
Dory
Schauen Sie sich [diese Antwort] an ( stackoverflow.com/a/41101859/1785516 ). Vielleicht würde es helfen, Ihren Fall zu beheben.
KLM

Antworten:

148

Aktualisierung für AndroidX.

Nach vielen Experimenten habe ich dieses Problem behoben, indem ich dies zu jeder Präferenz hinzugefügt habe , die die überschüssige Einrückung hatte:

app:iconSpaceReserved="false"

Natürlich müssen Sie dies auch zur PreferenceScreen-Deklaration oben in Ihrer XML-Datei hinzufügen:

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

Follow-up für benutzerdefinierte Einstellungen

Ich habe festgestellt, dass bei benutzerdefinierten Einstellungen, insbesondere bei älteren Geräten, diese Lösung nicht immer funktioniert. Eine solche Präferenz könnte beispielsweise immer noch eingerückt sein:

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"

Das Problem ist auf die Verwendung des dritten Konstruktorparameters in der benutzerdefinierten Voreinstellungsklasse zurückzuführen. Wenn Sie diesen dritten Parameter übergeben, wird das Listenelement eingerückt. Wenn Sie es weglassen, wird die Liste korrekt ausgerichtet:

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

Verwenden Sie stattdessen Folgendes:

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

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

Die Gutschrift dafür geht an @CommonsWare in diesem sehr alten Beitrag .

AndroidDev
quelle
11
Ich weiß nicht wer du bist, aber ich werde dich finden und es dir danken! :)
David
Dies ist der richtige Weg; Ich denke, es sind keine benutzerdefinierten Klassen erforderlich. Android reserviert jetzt standardmäßig einen Platz für Symbole.
Blogger
1
Dies funktioniert auch für die PreferenceFragmentCompatSupport-Bibliothek 28.0.0. Toll!
Jayeffkay
7
Was ist mit der Präferenzkategorie? Präferenzkategorie scheint nicht zu funktionieren
Jknair
1
Präferenzkategorie funktioniert gut in androidx.präferenz: Präferenz: 1.1.0
kalandar
53

Ich habe über dieses Thema berichtet hier (Sie können auch dort meine Abhilfe Projekt überprüfen), aber für jetzt, ich habe ein bisschen Hack-y, aber einfache Weise zu überwinden diese gefunden:

  • Für PreferenceCategorysetze ich den Start / Links-Abstand seiner Layouts auf 0.

  • Für andere Arten von Einstellungen habe ich mich entschieden, diese auszublenden, icon_framefalls sie kein Symbol haben.

Hier ist der Code. Verlängern Sie einfach diese Klasse und der Rest erfolgt automatisch:

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

Und das Ergebnis (XML-Beispiel finden Sie hier in diesem Google-Beispiel , das ich hier zum Auschecken erstellt habe ):

Geben Sie hier die Bildbeschreibung ein

Dieser Code ist etwas gefährlich. Stellen Sie daher sicher, dass Sie bei jedem Update der Bibliothek überprüfen, ob er ordnungsgemäß funktioniert.

Außerdem funktioniert es in einigen Sonderfällen möglicherweise nicht gut, z. B. wenn Sie android:layoutfür die Präferenz eine eigene Definition festlegen. Daher müssen Sie diese für diese Angelegenheit ändern.


Ich habe eine bessere, offiziellere Lösung:

Verwenden Sie für jede Präferenz app:iconSpaceReserved="false". Dies sollte gut funktionieren, aber aus irgendeinem Grund gibt es einen (bekannten) Fehler, der für PreferenceCategory nicht funktioniert. Es wurde hier berichtet und sollte in naher Zukunft behoben werden.

Im Moment können Sie also eine Mix-Version der von mir geschriebenen Problemumgehung und dieses Flag verwenden.


EDIT: Noch eine andere Lösung gefunden. Dieser wird alle Einstellungen überwinden und isIconSpaceReservedfür jede festlegen . Wie ich oben geschrieben habe, ruiniert es leider, wenn Sie PreferenceCategory verwenden, aber es sollte gut funktionieren, wenn Sie es nicht verwenden:

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

BEARBEITEN: Nachdem Google die Bibliothek endgültig repariert hat (Link hier ), können Sie das Flag für jede Voreinstellung setzen oder diese Lösung verwenden, die dies für alle erledigt:

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

Erweitern Sie es einfach, und Sie werden nicht die nutzlose Polsterung für Ihre Vorlieben haben. Beispielprojekt hier , bei dem ich anstelle dieser Tricks auch einen offiziellen Weg fordere, dies zu vermeiden. Bitte erwägen Sie, es zu markieren.

Android-Entwickler
quelle
Dies ist die EINZIGE Lösung, die funktioniert. Sowohl für v7- als auch für androidx-Bibliotheken. Gut gemacht!
Lior Iluz
2
Ich verstehe nicht einmal, warum das so ist. Was ist mit Google, das APIs ablehnt / entfernt / blockiert, wenn es entweder keinen Ersatz oder einen defekten gibt?
TheWanderer
1
@androiddeveloper Ich kann das verstehen, außer für PreferenceCategories. Diese sollten nicht ausgerichtet werden.
TheWanderer
@TheWanderer Nun, ich würde es vorziehen, wenn jeder den Platz benötigt, den er wirklich benötigt, und dass wir wählen könnten, welches Verhalten wir auf jeden Fall verwenden möchten.
Android-Entwickler
Der PreferenceCategory-Fehler wurde am 5. November 2018 unter AndroidX behoben. Ich habe nach der Migration getestet und es funktioniert jetzt wie erwartet. Siehe developer.android.com/jetpack/androidx/… . Wenn Sie nicht migrieren möchten und ein benutzerdefiniertes Layout verwenden, empfehle ich die Verwendung eines negativen Polsters von ca. 120, um die Lücke zu entfernen.
ET
28

Einfache Arbeitslösung von hier .
Es funktioniert über alle Einstellungen hinweg, ohne dass in alle Einstellungen geschrieben werden mussapp:iconSpaceReserved="false"

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

Das <bool>behebt den Standardwert von iconSpacePreservedfür alle Preference; Das <dimen>behebt die PreferenceCategory.

BEARBEITEN: Wenn Sie verwenden androidx.preference:preference:1.1.1, benötigen Sie das Maß nicht preference_category_padding_start. Getestet auf Android 6-10.

t0m
quelle
Funktioniert auch für mich. Vielen Dank. Aber ich verstehe nicht, warum es in einem Verzeichnis namens "values-sw360dp-v13" statt nur "values" sein muss. (Das Platzieren in "Werte" hat für mich keine Auswirkung.) Jemand weiß warum?
Gereon99
Perfekte Lösung für den gesamten Bildschirm. Automatisch alle Dinge behoben, aber nicht wissen wie?
Md Mohsin
7

Versuche dies:

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

Sie können die Polsterung wie folgt einstellen: setPadding();

Sanket Shah
quelle
1
Hey @ David, danke für die Antwort. Ich erstelle jedoch keine benutzerdefinierte Ansicht für den Einstellungsbildschirm. Ich verwende die Standardeinstellung.
Dory
Ich bin damit einverstanden, dass ich auch keine benutzerdefinierte Ansicht habe. Wäre schön dies für die Android Views einzustellen.
Verlorene Übersetzung
@lostintranslation Ich stimme zu, dass es nicht sehr logisch ist, eine benutzerdefinierte Ansicht nur für diesen Zweck zu erstellen. Ich habe sie jedoch getestet und sie funktioniert hervorragend.
defhlt
Leider ist dies bei der Verwendung PreferenceFragmentCompatnicht mehr der Grund. Das Auffüllen (oder nur ein Symbolrahmen) ist jetzt Teil der Ansichten der Einstellungen.
Android-Entwickler
5

Wenn Sie die com.android.support:preference-v7Bibliothek verwenden, stellen Sie sicher, dass für das Thema für die Aktivität, in der Ihre preferenceThemeEinstellungen gehostet werden, die Überlagerung des Themas für Materialeinstellungen v14 festgelegt ist:

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

mtrewartha
quelle
1
Gibt es eine ähnliche Lösung für die Verwendung der neuen PreferenceFragmentCompatKlasse?
Android-Entwickler
1
Ich habe es damit noch nicht versucht, sorry ... Ich benutze es PreferenceFragmentCompatjetzt auch, aber seitdem habe ich meinen Einstellungsbildschirm neu gestaltet und es enthält Symbole, die dieses Auffüllen für mich jetzt wünschenswert machen (es hilft, die linke Ausrichtung konsistent zu halten).
Mtrewartha
Vielen Dank an @mtrewartha. Am Ende habe ich für jedes meiner Einstellungsfelder nur einige halb passende Materialsymbole ausgewählt, um diesen linken Abstand zu verwenden, anstatt zu versuchen, einen Weg zu finden, ihn loszuwerden
Gregdev,
Kein Problem, ich bin froh, dass ich @gregdev helfen konnte!
Mtrewartha
4

Leider hat bei mir nichts von oben funktioniert.

Kurze Antwort :

Ich habe dies gelöst, indem ich einen negativen Rand für den obersten Container des benutzerdefinierten Einstellungslayouts verwendet habe.

Schritte:

  • Erstellen Sie ein benutzerdefiniertes Layout für die Voreinstellung (z. B. priority_category.xml).
  • Geben Sie an, dass Ihre Präferenz das benutzerdefinierte Layout verwendet, indem Sie einem Präferenz-Tag in XML den Parameter android: layout hinzufügen
  • Wenden Sie negative Ränder an

Detaillierte Antwort:

Die Präferenz 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>

Das benutzerdefinierte Layout für die Voreinstellungszeile, mit dem unnötige linke und rechte Ränder entfernt werden:

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

Das benutzerdefinierte Layout für die Einstellungskategorie, mit dem unnötige linke und rechte Ränder entfernt werden:

<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
quelle
toll, du hast mein Leben gerettet! : D
K. Kempski
Dies erfordert ein Layout für alle Arten von Einstellungen. Wo hast du sie gefunden? Hast du eine Bibliothek dafür? Ich habe hier eine Hack-y- Problemumgehung vorgenommen : stackoverflow.com/a/51568782/878126 , aber ich denke, Ihre Lösung ist sicherer. Benötigt nur viel Arbeit beim Kopieren von Dingen ...
Android-Entwickler
Sie finden es auf dem GitHub-Spiegel von AOSP: Überprüfen Sie die XML-Dateien mit dem Präfix priority_. github.com/aosp-mirror/platform_frameworks_base/tree/…
Gord
3

Die Polsterung wird von den Eltern verursacht ListViewin den PreferenceScreenEinstellungen enthält. Wenn Sie PreferenceFragmentzum Erstellen Ihrer Einstellungen ein verwenden, gehen Sie einfach zur onActivityCreatedFunktion von PreferenceFragementund gehen Sie wie folgt vor, um die Polsterung zu entfernen:

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
quelle
Bei der Verwendung PreferenceFragmentCompatist dies nicht mehr der Grund. Das Auffüllen (oder nur ein Symbolrahmen) ist jetzt Teil der Ansichten der Einstellungen.
Android-Entwickler
3

Ändern Sie das Präferenzthema wie folgt. Stellen Sie sicher, dass Sie die neueste Version der Einstellungsbibliothek verwendenandroidx.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
quelle
2
Leider habe ich einen kritischen Fehler von gefunden androidx.preference:preference:1.1.0-alpha01. Die Gerätedrehung auf einem zweiten Fragmentstapel in der App führt zu einem Absturz. Ich hoffe, dass es in späteren Versionen behoben wird. Ich gehe zurück zu androidx.preference:preference:1.0.0.
Joonsoo
2
@Joonsoo: Kann bestätigen. Es wurde ein vager Fehler "Fragment Save State Failure" angezeigt. Bleiben Sie also auf Version 1.0.0, bis sie behoben ist, und folgen Sie dieser Lösung in der Zwischenzeit, um die Ränder zu bewältigen.
Ganesh Mohan
iconSpaceReserved ist nur für Version 26 und höher verfügbar.
Realpranav
2

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

Verwenden Sie PreferenceFragmentCompat, um dies zu tun:

1.Definieren Sie einen 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.Überschreiben Sie die onCreateAdapter-Methode von PreferenceFragmentCompat:

   @Override
   protected Adapter onCreateAdapter(PreferenceScreen preferenceScreen) {

      return new CustomAdapter(preferenceScreen);
   }

Verwenden Sie style.xml, um dies zu tun:

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
quelle
Funktioniert dies für alle Einstellungen? Hast du eine Bibliothek dafür?
Android-Entwickler
1

Keines der oben genannten Antwort gearbeitet, ich hatte das kopieren Präferenz Layout eine neue Layout - Datei wie custom_preference.xml erstellen, überschreibe das Layout Inhalt durch die Einstellung Sichtbarkeit des Symbol Rahmen GONE . Legen Sie dann in der Datei pref.xml das Layout fest, damit dieses benutzerdefinierte Layout bevorzugt verwendet wird.

<?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>
Rangierer
quelle
0

Das 'Auffüllen' wird eingeleitet 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();
}

Wenn Sie wissen, wie Sie von Android definierte Stile überschreiben, können Sie dies wahrscheinlich lösen. Es ist jedoch nicht sehr einfach.

jayeffkay
quelle
Dies ist eine schreckliche Antwort: "Hier ist der Code, aber ich bin nicht sicher, wie ich das machen soll." Ist keine Antwort.
Verlorene Übersetzung
Ich bin damit einverstanden, dass dies keine Antwort ist, bin mir jedoch nicht sicher, wie ich diese relevanten Informationen anderweitig weitergeben soll. Der in der Frage angezeigte Speicherplatz wird wie oben dargestellt vom Framework hinzugefügt, und anscheinend gibt es keine Möglichkeit, ihn zu entfernen. Dh wenn es nicht möglich ist, "com.android.internal.R.styleable.PreferenceFrameLayout" zu überschreiben. Und das weiß ich nicht.
Jayeffkay
Können Sie bitte eine bessere Antwort geben? Vielleicht Github, um zu zeigen, wie man es für alle Vorlieben benutzt?
Android-Entwickler
0

Ich versuche es mit

android:icon="@null"

mit CheckBoxPreferencein Android 4.4, kann aber nicht von links auffüllen. Ich habe versucht, ein kleines transparentes Symbol zu verwenden und hinzuzufügen

android:icon="@drawable/transparent_icon" 

und es scheint Arbeit für mich. Ich hoffe es kann helfen. Vielen Dank.

Bao Doan
quelle
Was ist im "transparent_icon"? Ich habe versucht, ein leeres Drawable, aber es hat nicht geholfen ...
Android-Entwickler
0

Ich weiß nicht, ob es für eine Antwort zu spät ist, aber heute hatte ich das gleiche Problem und nichts von diesen Antworten hilft mir.

Also habe ich diese Lösung verwendet:

In meinem DisclaimerPreferencedass extends Preference, ovveride ich das onBindView(View view)Verfahren auf diese Weise:

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

Der Schlüssel ist, die RelativeLayoutInnenansicht als festzulegen GONE. Bitte lassen Sie mich wissen, wenn etwas nicht stimmt :)

Francesco Florio
quelle
1
Leider onBindViewist im neuen nicht mehr verfügbar PreferenceFragmentCompat. Stattdessen können Sie verwenden onCreateAdapterund onBindViewHolder, wie ich hier schrieb: stackoverflow.com/a/51568782/878126
Android-Entwickler
0

Anscheinend android:layout="@null"würde das Hinzufügen zu Ihrer Präferenz in XML den Trick tun. Infolgedessen wird der Titel jedoch auch größer.

John
quelle
Einfach zu bedienen, aber wie Sie geschrieben haben, ruiniert es den Stil aller Einstellungen
Android-Entwickler
0

Fügen Sie diese Einstellung einfach in das Präferenz-Tag ein

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

Vor einiger Zeit gefragt, aber was mir bei der Lösung dieses Problems geholfen hat, waren negative Ränder, keine benutzerdefinierten Dateien erforderlich.

Wenn Sie Ihre SettingsActivity-Klasse erstellen (in der sich das PreferenceFragment befindet), legen Sie das Layout einfach als Fragment fest und fügen einen negativen Rand hinzu.

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>
Kerl
quelle
-5

In android:defaultValue="false"zu Ihrem <PreferenceScreen [...]Tag:

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

MDXDave
quelle