Custom Layout For Android Preference
April 6, 2018Android 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:
- algo-trading
- algolia
- analytics
- android
- android-ktx
- android-permission
- android-studio
- apps-script
- bash
- binance
- bootstrap
- bootstrapvue
- chartjs
- chrome
- cloud-functions
- coding-interview
- contentresolver
- coroutines
- crashlytics
- crypto
- css
- dagger2
- datastore
- datetime
- docker
- eslint
- firebase
- firebase-auth
- firebase-hosting
- firestore
- firestore-security-rules
- flask
- fontawesome
- fresco
- git
- github
- glide
- godot
- google-app-engine
- google-cloud-storage
- google-colab
- google-drive
- google-maps
- google-places
- google-play
- google-sheets
- gradle
- html
- hugo
- inkscape
- java
- java-time
- javascript
- jetpack-compose
- jetson-nano
- kotlin
- kotlin-serialization
- layout
- lets-encrypt
- lifecycle
- linux
- logging
- lubuntu
- markdown
- mate
- material-design
- matplotlib
- md5
- mongodb
- moshi
- mplfinance
- mysql
- navigation
- nginx
- nodejs
- npm
- nuxtjs
- nvm
- pandas
- payment
- pip
- pwa
- pyenv
- python
- recylerview
- regex
- room
- rxjava
- scoped-storage
- selenium
- social-media
- ssh
- ssl
- static-site-generator
- static-website-hosting
- sublime-text
- ubuntu
- unit-test
- uwsgi
- viewmodel
- viewpager2
- virtualbox
- vue-chartjs
- vue-cli
- vue-router
- vuejs
- vuelidate
- vuepress
- web-development
- web-hosting
- webpack
- windows
- workmanager
- wsl
- yarn