ListView

Posted by muchag | Android,SQLite | 2011-03-31 (木) 1:20:06

ListView は、リストを表示する View。
まんまだ・・・。

コンテンツが多い場合は、自動的にスクロールバーが表示される。

Android Developers:ListView

表示の仕方は色々あるようだ。
 

準備

あれこれサイトを見て回ったが、現在のところ ListView を利用するためには
これを表示するための XML レイアウトファイルがどうしても必要みたい。
できれば、XML ファイルは触りたくなかったんだけどなぁ。

ただ、勘違いしないこと。
ListView はいつも通り、レイアウトファイルでも Java コードでもどちらでも配置できる。

main.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <ListView
  3.     xmlns:android="http://schemas.android.com/apk/res/android"
  4.     android:id="@+id/list"
  5.     android:layout_width="fill_parent"
  6.     android:layout_height="wrap_content" />

としてもいいし

hoge.java
  1. ListView list = new ListView(this);
  2. layout.addView(list, new LinearLayout.LayoutParams(FP, WC));

としてもいい。

と思っていたら大変な記事を発見してしまった・・・。

まず,view.xmlという表示用のレイアウトを作成する。
上のリスト1にあるようにListViewのidは@android:id/listに決まっている。
データが存在しないときに,表示するTextViewのidも@android:id/emptyに決まっている。
そこまで決めなくてもよいように思うのだが,違うidにするとエラーになる。

ITpro:こうしろうのMindStorms日記 第325話 お約束が多くないか

そのうち試してみよう。

しかし、私が今まで触れてきた多言語フレームワークと違い
ListView の中身は別個定義しなければならない(定義できる)ので
中身用の XML レイアウトファイルが必要となる というわけだ。

中身とは何か。
リスト1行毎の表示内容という意味。

FlexitemRenderer のイメージ。

ごく基本的なリストは、テキストが並ぶものであろうから
この場合は、TextView を必要な数だけ配置する。

もっともシンプルな1列のリストなら、これで事足りる。

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <TextView
  3.     xmlns:android="http://schemas.android.com/apk/res/android"
  4.     android:id="@+id/name"
  5.     android:layout_width="fill_parent"
  6.     android:layout_height="wrap_content" />

 
逆にテキストだけでなく、様々な View を利用したければ

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <RelativeLayout
  3.     xmlns:android="http://schemas.android.com/apk/res/android"
  4.     android:orientation="horizontal"
  5.     android:layout_width="fill_parent"
  6.     android:layout_height="fill_parent">
  7.  
  8.     <ImageView
  9.         android:id="@+id/image"
  10.         android:layout_width="100"
  11.         android:layout_height="100"/>
  12.  
  13.     <CheckBox
  14.         android:id="@+id/check"
  15.         android:layout_width="wrap_content"
  16.         android:layout_height="wrap_content"
  17.         android:layout_toRightOf="@+id/image"/>
  18.  
  19.     <TextView
  20.         android:id="@+id/name"
  21.         android:layout_width="wrap_content"
  22.         android:layout_height="wrap_content"
  23.         android:layout_below="@id/check"
  24.         android:layout_toRightOf="@+id/image"/>
  25. </RelativeLayout>

このように、多種類の View を利用し、レイアウトも自由にできる
それぞれの View に書式設定を加えてやれば、見た目も自由にできる

以上のようなわけで XML ファイルの追加 のようにして

res/layout

に XML ファイルを作成する。

ファイル名は自由。
ここでは例として list_item.xml と命名したことにする。

作成すると自動的に以下のファイルに登録され、コード内で使えるようになる。

gen/パッケージ名/R.java
  1. /* AUTO-GENERATED FILE.  DO NOT MODIFY.
  2.  *
  3.  * This class was automatically generated by the
  4.  * aapt tool from the resource data it found.  It
  5.  * should not be modified by hand.
  6.  */
  7.  
  8. package com.example.hoge;
  9.  
  10. public final class R {
  11.  
  12.     ******
  13.  
  14.     public static final class layout {
  15.         public static final int list_item=0x7f030000; /* ←注目 */
  16.         public static final int main=0x7f030001;
  17.     }
  18.  
  19.     ******
  20. }

 

データバインド

準備が終わったらいよいよ ListView にデータをバインドする。
この方法が色々あるっぽいので、見つけて確認しながらまとめていく。
 

ArrayAdapter

文字通り配列を利用してデータバインド。
Android Developers:ArrayAdapter

res/layout/list_item.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <TextView
  3.    xmlns:android="http://schemas.android.com/apk/res/android"
  4.    android:id="@+id/name"
  5.    android:layout_width="fill_parent"
  6.    android:layout_height="wrap_content"
  7. />

 

  1. //データ配列
  2. String[] data = {"中居", "木村", "稲垣", "草薙", "香取"};
  3.  
  4. //アダプタインスタンスを生成
  5. ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, data);
  6.  
  7. ListView list = new ListView(this);
  8. list setAdapter(adapter);
  9. layout.addView(list, new LinearLayout.LayoutParams(FP, WC));

 
またこんな手法もあった。

  1. //アダプタインスタンスを生成
  2. ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item);
  3. // アイテムを追加
  4. adapter.add("中居");
  5. adapter.add("木村");
  6. adapter.add("稲垣");
  7. adapter.add("草薙");
  8. adapter.add("香取");
  9.  
  10. ListView list = new ListView(this);
  11. list setAdapter(adapter);
  12. layout.addView(list, new LinearLayout.LayoutParams(FP, WC));

 
更に・・・下の SimpleCursorAdapter が上手くいかないので
DB からの取得結果を配列に入れて ArrayAdapter にてバインドする手法も成功した。

  1. //既存データの読み込み
  2. Cursor cursor = db.query(DB_TABLE, new String[]{"name"}, null, null, null, null, null);
  3. if (cursor.getCount() != 0) {
  4.  
  5.     //アダプタインスタンスを生成
  6.     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item);
  7.  
  8.     boolean isEof = cursor.moveToFirst();
  9.     while (isEof) {
  10.         adapter.add(cursor.getString(1));
  11.         isEof = cursor.moveToNext();
  12.     }
  13. }
  14.  
  15. ListView list = new ListView(this);
  16. list setAdapter(adapter);
  17. layout.addView(list, new LinearLayout.LayoutParams(FP, WC));

 

SimpleCursorAdapter

Android Developers:SimpleCursorAdapter

SimpleCursorAdapter を利用した手法はどうも上手くいかない。

よそ様のサイトにあるサンプルを動かすとちゃんと動くのだが
自作のは動かない・・・。

後々のためにいくつかメモ。

多くのサンプルが main.xml と list.xml を用いているが
自作品はできるだけ XML レイアウトファイルを使いたくないため list.xml のみ。
今のところ見つけられたサンプルは、こちらのみ。
愚鈍人:SQLiteでデータベース

こちらの真ん中辺りにある
CursorAdapterを使ってSQLiteの検索結果をListViewに表示する。

ListView は java で定義し、中身の TextView のみ XML レイアウトファイルを利用。
上記サンプルは正常に稼動。

サンプルと自作品の気になる相違点

  • サンプルはデータベース名がない
    → サンプルのデータベース名を設定するように変更しても無事稼動
  • サンプルのカラムは name, age のみで _id がない
    SQL 文内で rowid as _id としている
    自作品は _id, name, col1, col2, col3
  • データ取得が、サンプルは rawQuery、自作品は query
    自作品を rawQuery で試しても変化なし

注意点
ID カラムの名称を _id にしなけらばならない。 らしいがこれはしてある。

いつか解決しますように!

Android,SQLite | 2011-03-31 (木) 1:20:06 |

ID カラムのお約束

Posted by muchag | Android,SQLite | 2011-01-23 (日) 22:33:04

AndroidSQLite を利用する際
ID カラムのネーミングにはお約束があるようだ。

AndroidのSQLite関係のクラスでは、このIDを示す「_id」カラムがあるという前提で実装されているクラスがあります。

引用元:mucchinのAndroid戦記 Androidアプリで使用するSQLiteのテーブル作成時の注意点

 
というわけで、Android で SQLite を利用するときの ID カラムは
_id
と名づけるべし!
 

  1. create table hoge (_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, height REAL)
Android,SQLite | 2011-01-23 (日) 22:33:04 |

データ型

Posted by muchag | SQLite | 2011-01-23 (日) 22:09:57

SQLite では、カラムのデータ型は指定しなくていいらしい。
なんてアバウトな・・・。

  1. create table hoge (id, name, height)

 

カラムのデータ型指定(アフィニティ)

でもまぁ、もちろん指定してもいいわけで
その際に使えるのは以下の5種類。

  • TEXT
  • NUMERIC
  • INTEGER
  • REAL
  • NONE

 

  1. create table hoge (id INTEGER, name TEXT, height REAL)

なんていう風に記述。

あ、大文字小文字の区別はないっぽい。
 

PRIMARY KEY

このとき

  1. create table hoge (id INTEGER PRIMARY KEY, name TEXT, height REAL)

としてやると、id カラムへは 自動で ID 番号を追加 してくれる機能が付加される。

ただし、この場合の追加規則は ID 番号最大値 + 1 なので、
最終レコードを削除した後に新しいレコードを挿入すると
先ほど削除した ID 番号が追加 される。

参考元:DBOnline.JP INTEGER PRIMARY KEYが設定されたカラム
 

AUTOINCREMENT

同じ番号を2度と使いたくない場合は、以下のように記述すること。

  1. create table hoge (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT, height REAL)

参考元:DBOnline.JP AUTOINCREMENT
 

値のデータ型分類(ストレージクラス)

さて、ここからが今一よくわからない。

ストレージクラス とは、SQLite がそれぞれのデータをどう捉えるか、というものらしい。
上記のカラムのデータ型とは異なるらしい。。。
意味がよく分からない。。。そのうち。。。 🙄

その ストレージクラス とは、以下の5種類。

  • NULL – NULL値
  • INTEGER – 符号付整数。1, 2, 3, 4, 6, or 8 バイトで格納
  • REAL – 浮動小数点数。8バイトで格納
  • TEXT – テキスト。UTF-8, UTF-16BE or UTF-16-LEのいずれかで格納
  • BLOB – Binary Large OBject。入力データをそのまま格納

<参考引用元サイト>
DBOnline.JP:SQLiteで利用可能なデータ型
Third impact:SQLite Version 3 におけるデータ型

SQLite | 2011-01-23 (日) 22:09:57 |