Java
Android
XML

標準の設定画面をカスタマイズしたい その1

More than 3 years have passed since last update.

標準の設定画面では、標準のテーマ(Holoとか)に沿った見た目になります。ある程度凝ったアプリを作っていると、設定画面だけが妙に浮いた感じに見えてしまって、統一感が失われてしまいます。

ここでは、設定画面の各項目のレイアウトに焦点を当てて、カスタマイズの方法を見ていきます。


Summary



  1. Preferenceの各要素(PreferenceCategoryとかPreferenceScreenとかCheckBoxPreferenceなど)は、カスタムのレイアウトを差し込むためのアトリビュートがある

  2. 自分で定義したレイアウトの XML が差し込めるので、カスタム View を作ればより凝った画面を作れる


How to customize


レイアウトの準備

まずはカスタマイズしたいレイアウトを用意します。

ベースとなるレイアウトはAOSPにあります。

気をつける点は、設定画面で表示する項目に使うidandroid.Rのものを使うようにすることです。


row_custom_preference.xml


<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<!-- Layout for a Preference in a PreferenceActivity. The
Preference is able to place a specific widget for its particular
type in the "widget_frame" layout. -->

<!-- このレイアウトが、一行分のレイアウトになります。Android Lint がいくつかの警告を出すので対応しておきます -->
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
android:gravity="center_vertical"
android:background="@drawable/my_background"
android:paddingStart="@dimen/preference_item_padding_side"
android:paddingLeft="@dimen/preference_item_padding_side"
android:paddingEnd="?android:attr/scrollbarSize"
android:paddingRight="?android:attr/scrollbarSize">

<LinearLayout
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:minWidth="@dimen/preference_icon_minWidth"
android:orientation="horizontal">
<!-- アイコン、タイトル、説明、widget の id は android:id のものを使ってしまうのが楽です。 -->
<ImageView
android:id="@android:id/icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:layout_gravity="center"
android:minWidth="48dp"
android:scaleType="centerInside"
android:layout_marginEnd="@dimen/preference_item_padding_inner"
android:layout_marginRight="@dimen/preference_item_padding_inner"/>
</LinearLayout>

<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:paddingEnd="@dimen/preference_item_padding_inner"
android:paddingRight="@dimen/preference_item_padding_inner"
android:paddingTop="6dip"
android:paddingBottom="6dip">

<TextView
android:id="@android:id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:singleLine="true"
android:textAppearance="?android:attr/textAppearanceMedium"
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:layout_alignLeft="@android:id/title"
android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?android:attr/textColorSecondary"
android:maxLines="10"
android:drawableLeft="@drawable/my_drawable"/>

</RelativeLayout>

<!-- Preference should place its actual preference widget here. -->
<LinearLayout
android:id="@android:id/widget_frame"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:minWidth="@dimen/preference_widget_width"
android:gravity="center"
android:orientation="vertical" />

</LinearLayout>


PreferenceCategoryのレイアウトをカスタムする場合は以下の XML にします。元のファイルはこちら

一部 public ではない dimen の値(コンパイルタイムでエラーになります)がありますが、エディタ上では解決できているので、定義に飛んで値をコピペしています。


row_preference_category.xml


<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2011 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->

<!-- Layout used for PreferenceCategory in a PreferenceActivity. -->
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
style="?android:attr/listSeparatorTextViewStyle"
android:id="@android:id/title"
android:paddingStart="8dp"
android:paddingLeft="8dp"
android:paddingEnd="8dp"
android:paddingRight="8dp"
android:drawableLeft="@drawable/my_drawable"/>



レイアウトを差し込む

あとは、好きなところにレイアウトを差し込むだけです。属性は、android:layoutです。


pref.xml

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

<PreferenceCategory
android:title="About"
android:layout="@layout/row_preference_category.xml">
<Preference
android:title="Version"
android:layout="@layout/row_custom_preference"/>
<CheckBoxPreference
android:title="Check it out!"
android:summaryOn="On"
android:summaryOff="Off"
android:layout="@layout/row_custom_preference"/>
</PreferenceCategory>
</PreferenceScreen>