覚え書き 主にPreference絡み

PreferenceActivityというかPreferenceFragmentについては終わりと思い先に進もうと
思っていたが、ふとSeekBarを用いるPreferenceが欲しいなと思いぐぐる。
いっぱいヒットする(・∀・) ドレガエエンジャロウカ…

適当にAndroid 設定画面を簡単に作成する (ANDROID HACKS)のエントリのコードを
試してみる。上手く行った。これの中身を読んでベースにする方向でヽ( ・∀・)ノ

そう言えばpreference_widget_seekbar.xml内のSeekBar要素内で
xmlns:android=”http://schemas.android.com/apk/res/android”が指定されていて
eclipseだとエラーになった。これは一回だけ指定すればいいらしい属性みたいだが、
その辺のことはよくわからないので取り敢えず削ったらエラーが消えた。
問題がなさそうなので気にしないでおくか( ・´ω・`) イイノカ、ソレデ?

Preferenceの内部の動きを余り理解出来ていないと思い、Preferenceのカスタマイズに
ついて更にぐぐる。


三択プリファレンスがあった。コントローラのポジションはわざわざダイアログを出す
よりもこういった形で変更出来るようにしておいた方がいいのかな?
Preference(4)-Preferenceのカスタマイズ

三択プリファレンスは試したが、ダイアログの方は試していない。
うちがWindowsだからなのかSyntaxHighlighterのコピーを使うと
 が中に混ざってちょっとめどかった(´・ω・`)
もしかしてうちのコードも他所の人がコピペしたらこうなってるのかな?

あとコード的には一致してるので問題はないが、なせcustom_prefernce.xmlなんだヽ(`Д´)ノと
eが抜けているのが気になったw すごくどうでもいいw


ダイアログの方はフルコードで載っているDialogPreferenceをカスタマイズするの方を試した。
パッケージ名を適当につけたのに、setting.xmlファイル内でのフルパス指定を
修正しなくてちょっとハマったのは内緒(*´・ω・)

[Android] オリジナルのPreferenceを作ってみるのサンプルはプリファレンスアクティビティの
表示は変更されたけど、ダイアログは普通の物と同じだったような。
Androidのバージョンの違いかなんかか、何か間違えてるのかな(ノ∀`)
内容を読んでみたがよくわからないので、取り敢えず必要になった時に
また読んでみよう。


Androidの設定画面で使うカスタムPreferenceを作るのサンプルは
名前空間名は適当(hoge)でいいみたいだけど、

xmlns:hoge="http://schemas.android.com/apk/res/hoge"

って

xmlns:hoge="http://schemas.android.com/apk/res/info.loadlimits.android.preference"

じゃないと動かないのではなかろうか。というかうちの環境では動かなかった。
ここもパッケージ名をきちんと指定しないと駄目なのか。


そう言えば、他のサンプルはattrs.xmlなのにこのサンプルはattr.xmlだなぁ、
なんで問題なく動くんだろ、違いはなんだろと思いぐぐった。特にそれに関する
記述は見つからない。ソース等を見てもattr(s).xmlを指定している部分はない。
xmlファイルを開き<resources>を眺めていて

( ゚Д゚)ピコーンッ! と閃く。

ファイル名をa.xmlにして実行してみる。動く。理解した(`・ω・´)

valuesフォルダのファイルって人間が理解しやすいように分けているだけであって、
実際はシステムが全xmlファイル内にある<resources>要素以下を調べて
<string>や<dimen>等のリソースを収集して一括管理してるんだなw

試しにdimens.xmlにattr.xmlやstrings.xmlの内容を移植してもちゃんと動いた。

xmlもxmlフォルダを掘らずにlayoutフォルダに入れてR.layout.~で指定しても
いいみたいだから、結構自由なんだな。まあお作法に従って作るべきなんだろうけど。

どうでもいいことだけど、謎が解けて面白かったw


サンプルは有難いが、基本的に判る人向けのためか断片的なコードまたは
ファイルのみということが多いので初心者である俺氏は試すのに苦労した(ヽ’ω`)

新規のAndroidプロジェクトをデフォルトで作成して(最小必須SDKだけ4.0.3にした)、
その他のファイル等を作成したりコピーして、MainActivityに

import android.os.Bundle;
import android.preference.PreferenceActivity;
import android.preference.PreferenceScreen;

public class MainActivity extends PreferenceActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
		PreferenceScreen pScreen = getPreferenceManager()
				.createPreferenceScreen(this);
		pScreen.setTitle("Custom Preference");
		setPreferenceScreen(pScreen);

		addPreferencesFromResource(R.xml.[プリファレンス用のxml]);
    }
}

を貼っつけて、プリファレンス用のxml(通常xmlフォルダ以下に作ったxmlファイル)を
指定すれば簡単に試せる…と思う。 多分。

途中までわざわざPreferenceActivityを作って試していたのでめどかった(´・ω・`)


全然関係ないけど、なんでeclipseはアクティビティを新規作成した時に
マニフェストに自動追加してくれないんだろうか?マニフェストに記載しないと
アクティビティはシステムから認識されないのだから、アクティビティを作成した
段階で自動追加されるか、追加されていないことに対してのエラーが表示される
べきなのではなかろうかと思ったり。

ついでに新規Androidプロジェクトの作成ダイアログにxmlフォルダやdrawableフォルダ、
attrs.xml,colors.xml等の作成チェックボックスとかもついていれば更に良いのに。


サンプルコードを書いてる人達は何気なくTypedArrayを使ってるけど、TypedArrayって
なんだべ(´・ω・`)?

TypedArray
obtainStyledAttributes(AttributeSet, int[], int, int)またはobtainAttributes(AttributeSet, int[])を用いて取得される値の配列用のコンテナ。それらが完了した時には必ずrecycle()を呼んで下さい。この機構から値を取得する為に使用されるインデックス群はobtainStyledAttributesへ指定される属性の位置に対応しています。

TypedArray

へぇ…(´・ω・`)

で、サンプルによってはrecycle()を呼んでるんだけども、
なんでrecycle()を呼ばないといけないのかなと思ってぐぐる。

android – what is the use of recycle() method in TypedArrayでVinayさんは、

それはC言語のポインタのクリアの考えに似てるよ。それが必要ない時にメモリ/データが”a”に非効率的にバインドされないように”a”に関連付けられたデータがガベージコレクションされるようにするために使われるよ。ここを読んで見て(Bitmap#recycle()へのリンク)。あなたが実際に”a”を再利用しないなら、これは実際には必要がないということに注意することが重要だよ。GCはそのオブジェクトが再び使用されないのなら、あなたの為にこのデータを自動的にクリーンアップするはずだよ。しかしながらTypedArrayが異なる理由は以降での使用の為にTypedArrayへ戻さなければならない他の内部データ(StyledAttributes)をTypedArrayを持っているからです。

みたいなことを言っているけどなんかよくわからないw
関係ないけどVinayさんはアフロだね(・∀・)

Bitmap#recycle()では明示的にGCが可能であるとマークするみたいなことを書いてあり、
TypedArray#recycle()は

以降の呼び出し元によって再利用されるためにTypedArrayをリサイクルします。この機能の呼び出しの後、あなたは再びこの型付けされた配列に触れてはいけません。

という感じなので、明示的な破棄の指示をしてるのかどうかよくわからない。
他の人とのやり取りで

TypedArrayに関連付けられたメモリは以降の呼び出し元によって再利用されることが出来るよ、あなたのプログラムのインスタンスじゃなくてね。

みたいなことを言っているのでメモリのアロケーションを保持するってこと(´・ω・`)?
なんか違う?

StyledAttributesを持ってるとあるけどTypedArrayにstaticメンバは居ないような。
staticメソッド TypedArray.obtain()で

final TypedArray attrs = res.mTypedArrayPool.acquire();

して
TypedArray.recycle()で

mResources.mTypedArrayPool.release(this);

してるけど、これのこと?

userSeven7sさんの回答では

recycle()はアロケートされたメモリが直接利用可能なプールへ返されるようにし、ガベージコレクションまで留まりません。このメソッドはまたBitmapでも利用可能です。

とあった。

なんかようわからんヽ( ´・ω・)ノ


他にもサンプルはあったがもう疲れたのでいいや…_| ̄|○

まあ結局のところ、カスタムプリファレンスの作成手順は

  1. 必要ならばattrs.xmlを作って属性を作る
  2. カスタムプリファレンス用のレイアウトを作る
  3. カスタムプリファレンス用のクラスを作る(Preferenceクラスまたはそのサブクラスを拡張)

ということか。

なんかまた横道に逸れて時間を浪費したような気がする…(ヽ’ω`)