2011/07/04

ListViewやSpinnerを使ってみる1

今回はListViewやSpinnerに表示する項目にデータを渡すAdapterに関する記事です。

AndroidでListViewやSpinnerを利用するには標準でSimpleAdapterやArrayAdapter(他にもCursorAdapter等)が用意されています。そしてこれらAdapterはBaseAdapterというものを継承して作成されています。

とりあえずはSimpleAdapterとArrayAdapterについて簡単に解説します。

まずSimpleAdapterとArrayAdapterについて違う部分を先に説明すると、前者は渡すデータがMap<String, ?>で後者がStringやCharSequenceになります。また前者は渡した後のデータをAdapter内で変更することが出来ませんが、後者は足したり引いたりソートしたり出来ます。



まずはSimpleAdapterについて
SimpleAdapterのコンストラクターでは
  • 内包するMapデータ
  • ListViewで表示するレイアウトxml
  • Mapデータのキーと対応するレイアウトのID
を渡す必要があります。

表示できる内容はTextView、CheckedTextView、ImageView、CheckBox?
ImageViewに表示できる内容はリソースIDを渡せる画像のみです。
私自身はこの記事を書いている時点でアプリにSimpleAdapterを利用したことがありません。

そんな私が作ったSimpleAdapterのサンプルコードです。
レイアウトXML(simpleadapter_layout1.xml)





次にArrayAdapterの簡単な使い方です。
ArrayAdapterでは基本的に1つのTextView(CheckedTextView)だけを表示することが出来ます。
コンストラクターは
  • 内包するテキストデータ
  • ListViewで表示するレイアウトxml
  • レイアウトxml上のTextViewのID
を渡す必要があります。
私自身はこの記事を書いている時点でアプリにArrayAdapterを利用したことがありません。

レイアウトxml(arrayadapter_layout1.xml)





おまけ
SimpleAdapterで内容を動的に変えてみる場合。
Adapterと同期するData(SimpleAdapterの場合はList<Map>)を別に管理することで、中身の追加・削除が容易に行えます。

(レイアウトxmlは上のSimpleAdapter例と同じ)



ListViewは覚えてしまえば非常に簡単で使いやすいと思います。
次回は適度にSpinnerについて。

2011/05/03

SQLiteDatabaseをSDカードに構築する方法2

ちょっと気になったので色々と調べてみた。


まず、SQLiteOpenHelperのソースコードからgetWritableDatabaseを見てみると

やっていること自体はWeatherNowで実装している方法と一緒なのですが、データベース作成の部分が
・Context#openOrCreateDatabase
・SQLiteDatabase#openOrCreateDatabase
と違います。

Context#openOrCreateDatabaseでは第二因数に
・Context.MODE_PRIVATE(このアプリしか読み書きできない)
・Context.MODE_WORLD_READABLE(他のアプリから読めるけど書き込みは出来ない)
・Context.MODE_WORLD_WRITABLE(他のアプリから書き込みも出来る)
を指定。SQLiteOpenHelperでは0(Context.MODE_PRIVATE)が指定されています。


で、Context#openOrCreateDatabaseの影響範囲に付いてちろっと調べてみました。



結論だけ言うと、SQLoteOpenHelperを利用して
・API7(2.1)の端末ではSDカード上のDB読み書きできない
・API8(2.2)の端末ではSDカード上でもDB読み書きできる

でした。API8からはアプリのSDカード移動があるので、その関係で動作が変わったのかも?

ちなみに第二因数のファイルモードですが、アプリ専用領域(/data/data/******/)でしか機能しない様で、SD上の任意の場所にMODE_PRIVATEなデータベースは作成できないらしい。


まぁあれですよ
Android2.1のSDのDBアクセスに対応するには、SQLiteOpenHelperのmContext.openOrCreateDatabaseの部分をSQLiteDatabase.openOrCreateDatabaseに書き換えてしまえば問題ない。。。と思う。

2011/04/27

ホームウィジェットの中身を入れ子にする方法

おはこんばんにちは、noxiです。読み方は「のぃ」ではなくて「のくしー」です。
ホームウィジェットって使う側からは便利なんですけど、設計する側からすれば凄く面倒くさいですよね。事前にappwidget-providerなるxmlを作成し画面に貼るレイアウトxmlを定義しないといけないですし、使える画面パーツも限られています。

Android1.6(API4)までは、複雑なレイアウトを形成するにあたって、全てのパーツを記述する必要がありました(多分。少なくともWeatherNowのウィジェットは全て書いてる)。

Android2.1(API7)からはそんなことは必要無い! 中に入れるxmlを別々に定義できる! 凄く楽! マジ便利! WeatherNowでも早く使いたい!
そんな方法をちろちろ紹介してみようと思います。

非常に簡単なサンプルコードを紹介します。
・Provider.java(AppWidgetProviderクラス)
・provider.xml(appwidget-provider xml)
・main.xml(appwidget-provider xmlに記載するメインビューxml)
・content.xml(実際に表示するxml)
・content2.xml(実際に表示するxml)
(Manifest.xmlは略)

まずはxmlファイルから順に
・provider.xml

非常に単純な内容の、ホーム1x1占有、自動更新無し、レイアウトxmlはmain.xmlと定義しているだけのappwidget-providerなxmlです。

・main.xml

こちらも非常に単純で、中身は全くありません。ルートとなるFrameLayoutにIDが付いてるだけです。

・content.xml

content.xmlは実際にウィジェットに表示する中身です。テキスト1つ、画像1つ、そして余った領域にLinearLayoutがあります。

・content2.xml

content2.xmlはcontent.xmlのLinearLayout部分に入れてみようかなと思っているレイアウトです。テキスト1つ。

・Provider.java(AppWidgetProviderのonUpdateのところだけ)

非常に簡単なコードですが、ビューを入れ子にしています。Android2.1からRemoteViews#addViewが使えるようになったので、Viewを使い回すことが可能になり、大変便利になりました。includeタグが使えないホームウィジェットにおいて、Viewの使い回しが出来るって凄く素敵だと思います(天気ウィジェットを作っている身としては。今日の天気も明日の天気も同じレイアウトなので)。
xmlメンテナンスの面から、1.6対応を切りたくなりますよね。


WeatherNowは以前にも書きました通り、Android2.3の次のスマートフォン向けOS発表、またはAndroid1.6ユーザーが全体の0.5%を切った時点で1.6サポートを打ち切りますので予めご了承下さい。