2011-02 << 2011-03 >> 2011-04

2011-03-19 (土)

そろそろやらないといけないことを片付けようと思いつつ,面倒なので後回しに.

住所変更の手続きをいくつかした.まだ免許証とか残ってるけどまたしばらく放置しよう.

*[Android] AdMob

思ったよりもまともに広告収入が得られそうなので,AdMobの広告収入の受け取り方法を調べる.

ちなみに初日の収益は$5.96でした.今日は$10くらいにはなりそう.多いのか少ないのか分からないですが,とりあえず満足.

PayPalと銀行振込が選べるけど,どちらの方が良いのだろう.

色々調べると,振込手数料に関しては銀行振込でもPAYPALでもどちらでもAdMobが負担してくれているっぽい.(銀行振込手数料に関しては明記してあるが,PAYPALは見あたらない)

ただ,為替手数料や着金手数料までは出してくれないはずなので,銀行は選んだほうが良さそう.というか候補はシティバンクくらいしか知らない.

小額ならばPayPalで良いと思いますが,為替手数料を考えると,シティバンクに口座つくるのが良いのかなぁ.

高額になりそうなら,為替手数料が低い銀行にするべきなのか.

とりあえずPayPalが楽そうだし,銀行口座増やしたくないのでひとまずはPayPalで様子見することにします.手数料は,為替レートに上乗せされてる2.5%と,銀行口座への引き出し時の250円(5000円以上で無料)くらいでいいのかな.

あまり詳しくないので,誰か教えて欲しいところです.

*ニコニコPlayer(仮)

ちょっとビクビクしながら広告入れましたが,大きな問題は無さそう.暫くは様子を見ます.

次のバージョンではそろそろ再生履歴機能とか入れたい.

アプリUIからは呼び出せないのでアレなのですが,SearchManagerが入ってます.

Googleの検索ウィジェットなどの設定でニコニコPlayerを追加してやると,動画が検索できて便利です.キーワード検索専用ですが.

アプリから呼び出せないといいつつ,実は呼び出せて,ランキングの画面で検索ボタンを二回押すと,Android標準の検索UIが出てきて,音声検索とかできます.殆どバグみたいな機能なので,たぶん無くなります.

*[Android] ListViewをちゃんと使おう

Androidアプリを作る上で,ListViewは色々な場面で使える便利なViewですが,いざ使い方を調べてみると変な使い方をしている例がとても多いです.AndroidのSDKをよく読んで,設計意図を汲んであげましょう.

基本的な部分

基本的には,このあたりを読んでおくと良いです.

特に,view.setTag()とview.findViewWithTag()はViewに任意のデータを持たせることが可能で,しかも検索できるという便利なものなので,使うと綺麗に書けることが多いです.

内容の更新

リスト内のデータが変わったときは,表示内容を更新する必要があります.

notifyDataSetChanged()を使う

AdapterのnotifyDataSetChanged()等を呼び出すとListViewの表示を更新することが出来ます.

ただ気をつけなければいけないのは,このメソッドを呼び出すと表示されている要素を全て再表示します.このときgetView()が画面に表示されている要素数分だけ呼び出されます.

リストの要素数が変わったときなどは仕方がないことが多いですが,ひとつの要素の画像やテキストを変更したいという場合もあると思います.例えば,画像をAsyncTaskで読んでいて,読み終わったら反映したいという場合です.

画像ひとつ表示したいだけなのに,全てのViewの内容をセットしなおすのはコストが高すぎます.そもそも,変更したい要素が画面内に無いのに,notifyDataSetChanged()を呼ぶのは完全に無駄になります.

view.setTag()とview.findViewWithTag()を使う

特定の要素を書き換えたい場合,view.setTag()とview.findViewWithTag()の出番です.

例えば,getView()の中で,まだ読み込まれていない画像のImageViewに対して,

    tumbnailImage.setTag(position);

として,positionをタグとしてセットします.

画像が複数ある場合などは,リストの要素自体のViewにセットするか,position以外の識別子をつけましょう.比較可能ならInteger以外でも何でも良いです.

あとは画像の読み込みが完了したときにfindViewWithTag()を使ってListViewから探します.

    ImageView tumbnailImage = (ImageView) mListView.findViewWithTag(pos);
    if (tumbnailImage != null) {
        tumbnailImage.setImageBitmap(img);
    }

画像が画面内に表示されていない(正確にはListViewが保持していない)場合は,見つからずにnullが返ってくるので更新の必要はありません.

読み込んだ画像は,改めて表示されたときにgetView()で使うことになるので,キャッシュにでも入れておけばよいでしょう.

ヘッダとフッタをつける

ListViewの最初や最後に,特別な要素を加えたい場合があると思います.例えば,リストの最後に続きを表示するためのボタンを設置したい場合などです.

ダメな例

最初に見たときはびっくりしましたが,下のコードのように,positionを見て生成するlayoutを分けるというコードを見ることが多いです.

    public View getView(int position, View convertView, ViewGroup parent) {
        View v = null;

        if (position == 0) {
            v = inflater.inflate(R.layout.list_header, null);
            // 色々
        } else if (position == mArray.size()-1) {
            v = inflater.inflate(R.layout.list_footer, null);
            // 色々
        } else {
            v = inflater.inflate(R.layout.list_row, null);
            // 色々
        }

        return v;
    }

こういうことをすると,viewの再利用が出来ないのでパフォーマンスが落ちますし,体感的には気にならなくても,スマートフォンの場合は,CPUパワー使うことはバッテリーの持続時間に直結するのでやめてもらいたいです.

WrapperListAdapterを使う

リストの先頭や末尾に指定した要素を入れてくれる,WrapperListAdapterというものがるので,これを使うのがまともな方法です.

WrapperListAdapterは自分で生成しても良いですが,少し面倒なのと,ListView自体が,渡されたAdapterをWrapperListAdapterでラッピングしてくれる機能を提供しているので,ListViewに任せます.

使い方は簡単で,ListViewに対して,addHeaderView()やaddFooterView()でヘッダやフッタを追加してやると,自動的にWrapperListAdapterが内部で生成されてよしなにやってくれます.ただし,setAdapter()を呼び出す前にやる必要があるので気をつけます.

        TextView tv = new TextView(this);
        tv.setText("This is footer");
        getListView().addFooterView(tv, null, false);

ここでは単なるTextViewにしましたが,お好きなlayoutをinflateしてください.

あと,getAdapter()で取得できるアダプタは自分で設定したものではなく,WrapperListAdapterになっているので気をつけましょう.

フッタやヘッダを選択不可にしたいときには,addHeaderView()等を呼ぶときに指定できます.ただ,選択不可にすると区切り線が消えてしまったりするので,自分で解決する必要がありそうです.

動的に選択不可・可を切り替えたいときは,WrapperListAdapterのisEnable()をオーバーライドする必要が出てきて,そうなるとListViewが勝手にやってくれなくなるので,ArrayAdapter等を使うのをやめて,WrapperListAdapter相当の機能を持ったAdapterを実装したほうが楽かもしれません.

基本は選択不可でフッタ上にボタンを置いてそれの有効無効を切り替えるのが楽で良い気がします.