2012/03/14

Android:Preference項目のレイアウトファイル

Preference項目のレイアウトファイルと、参照までのシーケンスを調べてみました。
テーマによってレイアウトを変化させるテクニックを垣間見ることができます。


開始地点はPreference情報を注入するPreferenceFragment.addPreferencesFromResource
です。(PreferenceActivityも同じですが非推奨APIのため記載しません)

●android.preference.PreferenceFragment
public void addPreferencesFromResource(int preferencesResId) {
    requirePreferenceManager();

    setPreferenceScreen(mPreferenceManager.inflateFromResource(getActivity(),
            preferencesResId, getPreferenceScreen()));
}

PreferenceManagerのinflateFromResourceを使用してPreferenceを構築していきます。

●android.preference.PreferenceManager
public PreferenceScreen inflateFromResource(Context context, int resId,
        PreferenceScreen rootPreferences) {
    // Block commits
    setNoCommit(true);

    final PreferenceInflater inflater = new PreferenceInflater(context, this);
    rootPreferences = (PreferenceScreen) inflater.inflate(resId, rootPreferences, true);
    rootPreferences.onAttachedToHierarchy(this);

    // Unblock commits
    setNoCommit(false);

    return rootPreferences;
}


インフレートで生成されるPreferenceのコンストラクタを拝見。
なにやらcom.android.internal.R.attr.preferenceStyleのStyleを指定しています。

●android.preference.Preference
public Preference(Context context, AttributeSet attrs) {
    this(context, attrs, com.android.internal.R.attr.preferenceStyle);
}


参照先のpreferenceStyleの定義を拝見。
各テーマごとに定数定義されており、参照するstyleもそれぞれで異なります。

●framework/base/core/res/res/values/themes.xml
<style name="Theme">
    <item name="preferenceStyle">@android:style/Preference</item>

<style name="Theme.Holo">
    <item name="preferenceStyle">@android:style/Preference.Holo</item>


参照先のstyleの定義を拝見。
各スタイルが参照するレイアウトは下記の通り。

●framework/base/core/res/res/values/styles.xml
<style name="Preference">
    <item name="android:layout">@android:layout/preference</item>
</style>

<style name="Preference.Holo">
    <item name="android:layout">@android:layout/preference_holo</item>
</style>


各レイアウトはframework/base/core/res/res/layout配下に格納されています。
上記から、テーマによってPreferenceが参照するレイアウトが異なることがわかりました。
また、テーマによってレイアウトの参照先を変更可能であることもわかりました。

以上です。