0

According to this question I am trying to create a custom layout and add it to my root PreferenceScreen XML, but I am facing some problems, first, the switch_preference_layout.xml looks corrupted when I add it inside the Preference tag

here's my custom layout for the switch to dark mode example

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@android:id/widget_frame"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal"
    android:padding="@dimen/_8sdp"
    android:weightSum="2">

    <LinearLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="2"
        android:orientation="vertical">

        <TextView
            android:id="@android:id/title"
            style="@style/TextAppearance.PreferenceTitle"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="16dp"
            android:text="Dark Mode"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@android:id/summary"
            style="@style/TextAppearance.PreferenceSummary"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginStart="16dp"
            android:layout_marginTop="8dp"
            android:text="Improve visibility and save energy" />

    </LinearLayout>

    <androidx.appcompat.widget.SwitchCompat
        android:id="@+id/switch1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="16dp"
        android:layout_marginEnd="16dp"
        android:layout_weight="1" />
</LinearLayout>

and it looks like the following

enter image description here

after adding it in root_prefernces.xml using android:widgetLayout="@layout/switch_preference_layout" it looks like that

enter image description here

it's almost invisible! , I tried also to use android:layout="@layout/switch_preference_layout" and it completely disappeared

enter image description here

the full code of root_prefernces.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen 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">

    <PreferenceCategory>
        <Preference
            android:defaultValue="false"
            android:key="switchToDarkMode"
            android:widgetLayout="@layout/switch_preference_layout">
        </Preference>

    </PreferenceCategory>

    <Preference
        android:title="Publisher info"
        app:key="aboutPublisher">

    </Preference>

    <Preference
        android:title="@string/about"
        app:key="@string/about">


    </Preference>

</PreferenceScreen>

Second Problem

When I try to extend `Preference` in `SettingsFragment` I see working and it's required to pass `context` in its constructor unlike the other `Preference` class in this [answer][5]

enter image description here

and it also needs to override some methods and the last one isVisible the android studio shows working message 'isVisible' in 'PreferenceFragmentCompat' is final and cannot be overridden and if I removed it's showing it's required to override it, I am not sure but it looks like a bug

enter image description here

1 Answers1

0

First problem:

The widgetLayout is the layout for the widget on the right only, not the title and subject. So in your case, your entire layout should contain solely a SwitchCompat.

Second problem:

The answer in the question you linked does include a Context parameter in its constructor. Note that it's written in Java, and its constructor signature is:

public ImageViewPreference(Context context, AttributeSet attrs)

There should be no reason to override isVisible since that is just for querying whether the preference is set to be visible in the hierarchy. If you want to customize when the preference should be visible, you can call visible = in the constructor.

From looking at your code so far, it seems to me like you should subclass SwitchPreferenceCompat instead of Preference so you won't have to deal with a layout at all or with programming how to persist the value. If the only logic you want to add is setting the visibility of the preference under certain conditions, personally, I wouldn't subclass it at all. Instead, I would just set its visibility at runtime. Depending on what the condition is, you might be able to set it in the XML preferences file directly by using a Boolean resource.


I'm suggesting to use the already existing SwitchPreferenceCompat:

<SwitchPreferenceCompat
    app:title="@string/darkModePreferenceTitle"
    app:summary="@string/darkModePreferenceSummary"
    app:defaultValue="false"
    app:key="switchToDarkMode" />

Where darkModePreferenceTitle and darkModePreferenceSummary are String resources for "Dark mode" and "Improve visibility and save energy".

<!-- In strings.xml -->
<string name="darkModePreferenceTitle">Dark mode</string>
<string name="darkModePreferenceSummary">Improve visibility and save energy</string>
Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • Sorry, I couldn't understand you, What should I do to add these three custom elements title, summary, and SwitchCompat in the preference tag? I tried to change from Preference to SwitchPreferenceCompat but there's no effect, only half of the layout appears including the switch widget itself. for the second problem the current layout `switch_preference_layout` is the first one on the PreferenceScreen page, and I'll add other custom views below it not only `SwitchPreferenceCompat` – Cody Correll Sep 20 '22 at 19:10
  • so I need to extend a general Preference class but I can't figure out which class should I extend the current one is the newest one an it's require the context, I found other Preference class that deprecated – Cody Correll Sep 20 '22 at 19:10
  • See the bottom of the my edited answer. I don't think you need a custom Preference subclass or layout file at all unless you're adding features that SwitchPreferenceCompat doesn't have. It is rare to need to subclass preferences, because a bunch of the most common ones are already included in the Jetpack Preferences library. If you do subclass a Preference, it should be one of the ones in the androidx.preferences package, not the deprecated ones. – Tenfour04 Sep 20 '22 at 19:56
  • @tenfour04the reason that I need to use a custom layout is to change font style and size, etc this cannot be done directly in `SwitchPreferenceCompat` or any other preferences widgets and after I did some search I didn't find a solution except this – Cody Correll Sep 20 '22 at 20:25
  • If you don’t need different fonts and colors for each individual preference, the easy way to do this is by using a theme for the whole Activity that is hosting the preferences fragment. – Tenfour04 Sep 20 '22 at 21:10