Android Preference allow overriding 2 type of layout:
- android:layout: The layout for the entire Preference (include title, summary and widget)
- android:widgetLayout: The layout for the controllable widget portion of a Preference (e.g. a checkbox preference would specify a custom layout consisting of just the CheckBox here)
Custom layout
Technically you can overide the entire layout of Preference, but I think you should treat this approach as the last resort. Reason being your layout might different in style (size, margin, etc.) from other preference.
If possible, you should create a custom layout without overriding the layout (e.g. Android Preference With Icon On Right Side of Title )
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<CheckBoxPreference
android:layout="@layout/preference_pro_switch"
android:defaultValue="true"
android:key="test"
android:title="Test"
/>
</PreferenceScreen>
Content of R.layout.preference_pro_switch
.
Example of Preference layout
- https://android.googlesource.com/platform/frameworks/support/+/master/v7/preference/res/layout/preference.xml
- http://androidxref.com/8.0.0_r4/xref/frameworks/support/v7/preference/res/layout/preference.xml
- http://omapzoom.org/?p=platform/frameworks/support.git;a=blob;f=v7/preference/res/layout/preference.xml;h=f75bc683435d567d5016f461d06074985b117d44;hb=HEAD
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="?android:attr/selectableItemBackground"
android:baselineAligned="false"
android:clipToPadding="false"
android:gravity="center_vertical"
android:minHeight="?android:attr/listPreferredItemHeightSmall"
android:paddingLeft="?android:attr/listPreferredItemPaddingLeft"
android:paddingRight="?android:attr/listPreferredItemPaddingRight">
<RelativeLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingBottom="16dp"
android:paddingTop="16dp"
>
<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceListItem"
android:textSize="16sp"
tools:text="Title" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toEndOf="@android:id/title"
android:layout_toRightOf="@android:id/title"
android:layout_marginLeft="8dp"
android:tint="@color/icon_tint"
app:srcCompat="@drawable/ic_delete_black_24dp"
/>
<TextView
android:id="@android:id/summary"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignLeft="@android:id/title"
android:layout_alignStart="@android:id/title"
android:layout_below="@android:id/title"
android:maxLines="2"
android:paddingTop="6dp"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:textSize="14sp"
tools:text="Summary" />
</RelativeLayout>
<Switch
android:id="@android:id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@null"
android:clickable="false"
android:focusable="false"
/>
</LinearLayout>
Widget layout
You can replace the widget portion of a Preference with a View, such as a Button or ImageView.
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>
<Preference
android:layout="@layout/preference_button_widget"
android:defaultValue="123"
android:key="test"
android:title="Test"
/>
</PreferenceScreen>
Content of R.layout.preference_button_widget
.
<?xml version="1.0" encoding="utf-8"?>
<Button xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/button"
android:text="My Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
If you need to access the button (custom widget), you would need to create a custom Preference
class (Refer to Android Preference With Icon On Right Side of Title as an example).
class CustomPreference : Preference { ... override fun onBindView(view: View) { super.onBindView(view) val button = view.findViewById(R.id.button) as Button }}
References: