[Android] オリジナルのPreferenceを作ってみる


どうも、hide92795です
Androidの設定画面はPreferenceを使えば簡単にできるのですが、

・現在の設定値がわかりづらい
・単位をつけて表示させたい(EditTextPreference)

というのが気にくわないのですww
(まぁ、はじめのはサマリーや別のPreferenceに表示すればいいだけですが、説明文が表示できなくなったり縦に伸びるのは自分的に×なんですよねw)
というわけで、オリジナルのPreferenceを作ってしまおうじゃないかというわけなのです(`・ω・´)
参考サイト:
EditTextPreferenceの拡張2 – HaseLab

http://www.haselab.com/androidpj/?p=370

XML でカスタムView – Android 奔走記
http://weide-dev.blogspot.com/2010/04/xml-customview.html


①PreferenceScreenに表示される方を改造する
original_preference_1

original_preference_2
こんなかんじ
これを改造するのは、これのレイアウトxmlを新しく作って、それを使うように新しく独自のクラスを作成すればおkです
デフォルトのレイアウトxmlは、androidSDKのフォルダの
「\platforms\android-*\data\res\layout\preference_child.xml」
です。
改造するときは、すでにあるViewのIdをいじらないようにしてください
自分が改造したxmlは、追記のほうに書いておきますw(結構長いのでw)


②DialogPreferenceを継承したオリジナルのダイアログを表示するレイアウト&クラスを作成する
・EditTextPreferenceの場合

original_preference_3
こんな感じ

この場合だと、入力するEditTextの横に単位をつける必要があるので、ダイアログ用のレイアウトxmlを作成します。
(とはいっても、EditTextとTextViewを横に並べるだけなんですけどねw)

custom_edittext_preference.xml

EditTextのIDは「text」、TextViewのIDは「unit」になっています

次は、↑のxmlを読み込むようにし、さらに色々と機能を追加させたオリジナルのDialogPreferenceを作ります

CustomEditTextPreference

メソッドの説明

・コンストラクター
xmlで指定された値を各変数に格納します
・onCreateView(ViewGroup parent)
①が生成されるときに呼ばれます
これをオーバーライドして、①で作ったxmlが呼ばれるようにし、設定値を表示させるTextViewを変数に格納します。
layoutInflater.inflate(unitPosition, null)のunitPositionは、コンストラクターで設定されたxmlのリソースIDです。
・onBindView(View view)
①が表示される直前に呼ばれる?
保存されている値を取得し、変数に格納します。
・onCreateDialogView()
ダイアログが生成されるときに呼び出されます。
EditTextは、値を保存する際に使用するので、変数に格納します。
この時に、onBindViewで読み込んだ値を設定します。
他にも、コンストラクターで読み込んだ設定を各部品に割り当てていきます。
・onDialogClosed(boolean positiveResult)
ダイアログが閉じられる時に呼び出されます。
positiveResult = true なら、値を保存します。
・updateInputValue()
①の現在の設定値に表示させる値を更新します。
コンストラクターでxmlで指定された値を~と書きましたが、この部分では

のように書いています。ここで値を指定しています。
見た方はわかると思いますが、普通なら「android:****=”….”」みたいなのだけのはずが、「hide92795:****=”….”」というのが追加されています。
次は、これのやり方です


③xmlに独自の属性を追加する
まず、「\res\values\」フォルダ内に「attrs.xml」を作成します。

attrs.xml

書式としては、declare-styleable name=”名前”で名前に好きな文字を(別のサイトでは、クラス名にとありましたが、クラス名じゃなくても正常に動作しました(;^ω^))
attr format=”種類” name=”名前”で種類に使用できるリソースの種類、名前にxmlで使用する属性の名前を設定します。
この種類のところには、文字列→string 色→color リソース(xmlで指定するやつ)→reference みたいなのを入力します。複数個ある場合は、「|」で区切ってください。
これを作ったあとに、Preferenceのレイアウトxmlのはじめの部分を

のように
xmlns:(:の前につくやつ)=”http://schemas.android.com/apk/res/(パッケージ名)”
を追加します。
これによって、「hide92795:inputType=”number”」みたいなのを追加してもエラーが起こらないようになります。
ここで設定した値を取得するには、さっきの②のCustomEditTextPreference.javaのコンストラクターであった

を使用します。
context.obtainStyledAttributes() の第2引数は、R.styleable.(attrs.xmlのはじめの部分で指定した名前)となります。
R.~なので、クラスが自動生成されるので、eclipseを使っていれば補完機能でわかると思いますww
取得は、TypedArrayクラスにあるget****()メソッドを使用します。
http://developer.android.com/reference/android/content/res/TypedArray.html
引数のint型は、R.styleable.(attrs.xmlのはじめの部分で指定した名前)_(name = “…”で入力した名前) となっています
これもeclipseの補完機能でどれがどれかわかると思いますww


だいぶ長くなりましたねww
久々と言うかここまで長くなったのは初めてかな?w
実は、ListPreferenceも設定値を表示できるように改造したクラスを作ってありますw
ここに書いたものを少しいじればできるようになるので、ここでは省略させて頂きます
コツと言うかヒントと言うか答えと言うか、独自のListPreferenceを作るときに注意する点は
・ListPreferenceを継承させる(単位を追加することはまずないと思うので、ダイアログの部分はそのまま使います)
・↑のおかげで、ダイアログの生成をオーバーライドしなくて済み、自分で値を保存・読み出ししなくておk
・リストで選択されている文字を取得するには、getEntry()
これらをちゃんとソースに反映させれば現在の選択している値がちゃんと表示されるようになるはずです。
一応、これで動いてはいますが、間違っている部分を見つけたら教えて下さいww
ではノシ


以下、①の部分で省略したxmlです
①PreferenceScreenに表示される方を改造する
設定値を下に表示させるxmlレイアウト

custom_preference_bottom.xml

設定値を下に表示させるxmlレイアウト

custom_preference_right.xml

設定値を表示させるTextViewのIDは「inputValue」、色はxmlで定義済みのAQUA_BLUE(#00BFFF)になっています

  1. コメントはまだありません。

  1. トラックバックはまだありません。

*