これはActivityのように思えますが、実際にはダイアログが表示されています。
このタイトル部分のスタイルを変えようと思ったのですが、最初の画面だけが変更され、PreferenceScreenで遷移した先の画面のタイトルバーを変えられず、苦労したので記録しておきます。
結論から言うと、PreferenceScreenのタイトルバーはカスタマイズできず、同じような見た目・挙動になる別の方法をとりました。
まず該当部分をカスタマイズできるのか、Androidのソースコードを見てみたところ、android.preference.PreferenceScreenに以下のような記述がありました。
private void showDialog(Bundle state) { Context context = getContext(); if (mListView != null) { mListView.setAdapter(null); } mListView = new ListView(context); bind(mListView); // Set the title bar if title is available, else no title bar final CharSequence title = getTitle(); Dialog dialog = mDialog = new Dialog(context, TextUtils.isEmpty(title) ? com.android.internal.R.style.Theme_NoTitleBar : com.android.internal.R.style.Theme); dialog.setContentView(mListView); if (!TextUtils.isEmpty(title)) { dialog.setTitle(title); } dialog.setOnDismissListener(this); if (state != null) { dialog.onRestoreInstanceState(state); } // Add the screen to the list of preferences screens opened as dialogs getPreferenceManager().addPreferencesScreen(dialog); dialog.show(); }これを見ると、Dialogに適用されるテーマは
デフォルトのThemeかTheme_NoTitleBarとなっていて、外から変えられません。
ではこのdialogを操作できるかというと、ローカル変数なので操作できません。
それならshowDialog()の呼び出し元をオーバーライドして書き換えてしまえば…と思いましたが、これもダメです。
PreferenceScreenはfinalなので継承できません。
つまり、PreferenceScreenのスタイルを変えたい場合は、この部分だけ変更可能にしたカスタムPreferenceScreenを作成しなくてはなりません。
これはあまり良い方法に思えませんでしたので、別の方法を探りました。
他にも方法はあるかもしれませんが、Activityを分ける方法でうまくいきました。
PreferenceActivityの本体のタイトルバーは変更できるので、PreferenceScreenの代わりにPreferenceを使い、
そのPreferenceにOnClickListenerを設定して、クリック時に次の画面のPreferenceActivityを呼び出すという方式です。
以下、具体的な方法です。(BasicWallに適用しています。)
ソースコードは重要な部分を抜粋・改変したものなので、そのままでは動かないかもしれません。
- ベースとなるPreferenceActivityを作成します(FirstPreferenceActivityとします)。
- 通常PreferenceScreenとして作成する画面を別のPreferenceActivityとして作成します(SecondPreferenceActivityとします)。
- プリファレンスのXMLを定義します(res/xml/preferences.xmlとします)。PreferenceScreenだった部分は単純なPreferenceとして定義します。
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen ...> <Preference android:key="pref_second" android:title="..." android:summary="..." /> : </PreferenceScreen>
- PreferenceScreenの中に含めていたPreferenceの定義を別のXMLに移します(preferences_second.xmlとします)。
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen ...> <ListPreference : </PreferenceScreen>
- FirstPreferenceActivityのPreference(キーはpref_second)をクリックしたときに、SecondPreferenceActivityを起動するようにします。
protected final void onCreate(final Bundle savedState) { : addPreferencesFromResource(R.xml.preferences); Preference pref = findPreference("pref_second"); pref.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { @Override public boolean onPreferenceClick(final Preference preference) { startActivity(new Intent(FirstPreferenceActivity.this, SecondPreferenceActivity.class)); return true; } }); }
- SecondPreferenceActivityでは、普通のPreferenceActivityと同様にXMLからプリファレンスを読み込みます。
protected final void onCreate(final Bundle savedState) { : addPreferencesFromResource(R.xml.preferences_second); : }
- 各アクティビティをAndroidManifest.xmlに登録します。
<application ..> <activity android:label="First preferences" android:name=".FirstPreferenceActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <activity android:label="Second preferences" android:name=".SecondPreferenceActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> :
- 各PreferenceActivityに適用するタイトルバーのスタイルを、テーマとして定義します。例えば、res/values/styles.xmlに以下のように書きます。
<?xml version="1.0" encoding="utf-8"?> <resources> <style name="CustomTheme.Black" parent="@android:style/Theme.Black"> <item name="android:windowTitleBackgroundStyle">@style/WindowTitleBackground</item> <item name="android:windowTitleStyle">@style/WindowTitle</item> <item name="android:windowTitleSize">45dip</item> </style> <style name="WindowTitleBackground"> <item name="android:background">@drawable/title_background</item> </style> <style name="WindowTitle"> <item name="android:singleLine">true</item> <item name="android:textAppearance">@style/TextAppearance.WindowTitle</item> <item name="android:shadowColor">#BB000000</item> <item name="android:shadowRadius">2.75</item> <item name="android:paddingLeft">10dip</item> <item name="android:typeface">sans</item> </style> <style name="TextAppearance.WindowTitle" parent="@android:style/TextAppearance.WindowTitle"> <item name="android:textColor">#fff</item> <item name="android:textSize">18sp</item> <item name="android:textStyle">bold</item> </style> </resources>
- 上記のようにスタイルを定義しているときは、グラデーションをDrawableとして作成する必要があります。上記に合わせるとres/drawable/title_background.xmlです。
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#FF444444" android:endColor="#FF222222" android:angle="270" /> </shape>
- テーマをアプリケーション全体もしくはアクティビティに適用します。
アプリケーション全体なら以下のようにします。
<application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@style/CustomTheme.Black">
(もちろん、この方法ならタイトルバー以外もカスタマイズできるはずです。)
(完成版のイメージは、BasicWallをダウンロードしてご確認いただけると嬉しいです。)
0 件のコメント:
コメントを投稿