【Android Studio】Settings Activityのレイアウトをいじってみる

Androidアプリの設定画面のレイアウトをカスタマイズする方法についてまとめました。

はじめに

Androidアプリの設定画面を作るにあたって便利なのが、テンプレートとして用意されているSettings Activityですが、これをそのまま使うだけだと下のようなつまらないシンプルなレイアウトにしかできないので、アプリのテーマに合わせてカスタマイズする方法をまとめました。

f:id:danook:20201112115717j:plain
前に作ったアプリのやつですね。。。

1. バックグラウンド部分をカスタマイズする

デフォルトのSettings Activityでは、

  • settings_activity.xml
  • root_preferences.xml

という二つのXMLファイルが生成されて、前者の中の"settings" (LinearLayout(vertical))の部分に、(root_)preferencesが入る、という形になります。そのことを踏まえた上で、settings_activityのレイアウトをカスタマイズします。

2. XMLファイル×2を作る

  • Preference用
  • Preference Category用

にそれぞれXMLファイルを作ります。

3. Preference用のXMLを編集する

デフォルトのXMLは以下から見ることができます。

platform_frameworks_base/preference.xml at master · aosp-mirror/platform_frameworks_base · GitHub

これを構成している要素について解説していきます。

  • LinearLayout
    一番外側にあたるレイアウトです。デフォルトはLinearLayoutですが、使いづらかったらConstraintLayoutにしても動きます。

    • @+android:id/icon
      ここにアイコン画像が入ります。最新のOSでは反映されないし、なくしても別に問題ないと思います。

    • RelativeLayout
      ここに設定項目のTitleとSummaryが入っています。この二つはフォントをいじる程度。

    • @+android:id/widget_frame
      空っぽのレイアウトで一見要らなそうですが、ここにSwitch Preferenceのスイッチなどが入ってくるので重要です。消さずにそっとしておきましょう。(by 要らないと思って消した人)

もちろんこのコードをいじってもいいですし(その方が楽ですね)、

が用意できていれば、一から自作でもOKです。

参考までに自分が作ったものを載せておきます。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
    android:id="@+id/linearLayout2"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:background="@color/colorLightTransParent"
    android:gravity="center_vertical"
    android:minHeight="64dp">

    <!-- タイトル -->
    <TextView
        android:id="@android:id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="64dp"
        android:layout_marginTop="8dp"
        android:ellipsize="marquee"
        android:fadingEdge="horizontal"
        android:singleLine="true"
        android:text="TITLE"
        android:textAppearance="?android:attr/textAppearanceMedium"
        android:textColor="@color/colorPrimaryDark"
        app:layout_constraintBottom_toTopOf="@android:id/summary"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_chainStyle="spread"
        tools:layout_conversion_absoluteHeight="24dp"
        tools:layout_conversion_absoluteWidth="45dp" />


    <!-- 概要 -->
    <TextView
        android:id="@android:id/summary"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="64dp"
        android:layout_marginBottom="8dp"
        android:maxLines="10"
        android:text="Summary"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:textColor="@color/colorPrimaryDark"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@android:id/title"
        tools:layout_conversion_absoluteHeight="19dp"
        tools:layout_conversion_absoluteWidth="60dp" />

    <!-- ここにウィジェットが入るよ -->
    <LinearLayout
        android:id="@android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginEnd="16dp"
        android:gravity="center"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <!-- 区切り線。@style/Dividerは別に定義してある -->
    <View
        android:id="@+id/view"
        style="@style/Divider"
        android:layout_width="0dp"
        android:layout_height="2dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

4. Preference Category用のXMLを編集する

これもPreferenceの方と同様。以下のコードをもとに編集しましょう。

platform_frameworks_base/preference_category.xml at master · aosp-mirror/platform_frameworks_base · GitHub

こちらはシンプルに@+android:id/titleのみなので、そこさえ作れば割と自由にレイアウトできます。こんな感じにしてみました。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="40dp"
    android:background="@color/colorPrimaryDark"
    android:gravity="center_vertical">

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center"
        android:minWidth="16dp"
        android:orientation="horizontal">
    </LinearLayout>

    <RelativeLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_weight="1"
        android:paddingTop="6dip"
        android:paddingBottom="6dip">

        <!-- タイトル -->
        <TextView
            android:id="@android:id/title"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:ellipsize="marquee"
            android:fadingEdge="horizontal"
            android:singleLine="true"
            android:text="TITLE"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:textColor="@color/colorLight" />

        <!-- これは多分なくてもOK -->
        <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:maxLines="10"
            android:textAppearance="?android:attr/textAppearanceSmall"
            android:textColor="?android:attr/textColorSecondary" />

    </RelativeLayout>

    <!-- これもなくてよい気がするけど -->
    <LinearLayout
        android:id="@android:id/widget_frame"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:gravity="center"
        android:orientation="vertical" />

</LinearLayout>  

5. 作成したXMLをレイアウトに反映する

preferences.xmlに移動して、Preference, PreferenceCategoryのlayout属性を、それぞれ先ほど用意したXMLに設定します。たとえばこんな感じ↓

<Preference
            android:id="@+id/privacyPolicy"
            android:key="privacy_policy"
            android:title="@string/privacy_policy"
            app:layout="@layout/settings_item" />

6. 完成!

こんな感じになりました↓

f:id:danook:20201112115508j:plain
まだまだ工夫次第でいろいろとカスタマイズできそうですね!