Xamarin.Android ListView
1 基本的なListView
ArrayAdapter生成時のリソースIDの指定が、Resourceではなく、Android.Resourceであることに注意が必要です。
なお、行の移動は、ListViewのSetSelection/SetSelectionFromTopで行います。
var listView = FindViewById<ListView>(Resource.Id.listView1); var adapter = new ArrayAdapter(this, Android.Resource.Layout.SimpleListItem1); for (var i = 0; i < 10; i++){ adapter.Add("item_"+i); } listView.Adapter = adapter; //行の移動 listView.SetSelection(10); //10番目の行(item_10)を一番上に表示する //listView.SetSelectionFromTop(10,100); //10番目の行(item_10)を一番上から100ピクセルの位置に移動する
選択は、ItemClickイベントで処理できます。第2パラメータで受け取れる、ItemClickEventArgsのPositionが選択されたインデックスです。
listView.ItemClick += (s, a) =>{ var str = String.Format("ItemClick : {0}",adapter.GetItem(a.Position)); Toast.MakeText(this,str,ToastLength.Short).Show(); };
ここでは、イベントの処理をラムダで記述しているので、特にメリットは無いのですが・・・
第2パラメータの、ItemClickEventArgsのParentは、ListViewですので、キャストして利用することも可能です。
listView.ItemClick += (s, a) =>{ var parent = (ListView) a.Parent; var str = String.Format("ItemClick : {0}", parent.GetItemAtPosition(a.Position)); Toast.MakeText(this, str, ToastLength.Short).Show(); };
ListViewのクリックに関するイベントは、ItemClickの他にも、ItemLongClick,Click,LongClickの4種類がインテリセンスで見て取れます。この辺が学習曲線を上げるんですよね・・・
2 表示内容のカスタマイズ
表示内容をカスタマイズするには、ArrayAdapterを継承したクラスを作成し、getView()メソッドをoverrideします。
最初に、1つのアイテムのデータ型(ListItem)を設計します。
public class ListItem{
public Bitmap Image; //画像
public string Name; //名前
public string Comment; //コメント
}
続いてArrayAdapterを継承した、Adapter用のクラスです。
getView()では、1アイテムの表示Viewを作成していますが、引数で受け取ったpositionで当該データを取り出し、Viewを構築しています。
public class MyAdapter : ArrayAdapter<ListItem>{
private readonly LayoutInflater _layoutInflater;
public MyAdapter(Context context, int rid, IList<ListItem> list)
: base(context, rid, list){
_layoutInflater = (LayoutInflater) context.GetSystemService(Context.LayoutInflaterService);
}
public override View GetView(int position, View convertView, ViewGroup parent){
//データを取り出す
var item = GetItem(position);
//レイアウトファイルからViewを作成
var view = _layoutInflater.Inflate(Resource.Layout.list_item, null);
//画像
var image = view.FindViewById<ImageView>(Resource.Id.imageView);
image.SetImageBitmap(item.Image);
//名前
var textViewName = view.FindViewById<TextView>(Resource.Id.textViewName);
textViewName.Text = item.Name;
//コメント
var textViewComment = view.FindViewById<TextView>(Resource.Id.textViewComment);
textViewComment.Text = item.Comment;
return view;
}
}
1アイテム用のaxmlです。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageView
android:layout_width="80dip"
android:layout_height="80dip"
android:id="@+id/imageView" />
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="@+id/linearLayout1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textViewName" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textViewComment" />
</LinearLayout>
</LinearLayout>
最後に使用方法です。
//アイコン用画像の生成
var bmp = BitmapFactory.DecodeResource(Resources,Resource.Drawable.Xamarin);
//データの作成
var list = new List<ListItem>();
for (var i = 0; i < 50; i++){
list.Add(new ListItem() { Image = bmp, Name = "Name"+i, Comment = "MESSAGE"+i });
}
//ListViewのAdapterに作成したMyAdapterをセットする。データは、MyAdapterのコンストラクタに渡します。
var listView = FindViewById<ListView>(Resource.Id.listView1);
listView.Adapter = new MyAdapter(this, 0, list);
最初に、1つのアイテムのデータ型(ListItem)を設計します。
public class ListItem{ public Bitmap Image; //画像 public string Name; //名前 public string Comment; //コメント }
続いてArrayAdapter
getView()では、1アイテムの表示Viewを作成していますが、引数で受け取ったpositionで当該データを取り出し、Viewを構築しています。
public class MyAdapter : ArrayAdapter<ListItem>{ private readonly LayoutInflater _layoutInflater; public MyAdapter(Context context, int rid, IList<ListItem> list) : base(context, rid, list){ _layoutInflater = (LayoutInflater) context.GetSystemService(Context.LayoutInflaterService); } public override View GetView(int position, View convertView, ViewGroup parent){ //データを取り出す var item = GetItem(position); //レイアウトファイルからViewを作成 var view = _layoutInflater.Inflate(Resource.Layout.list_item, null); //画像 var image = view.FindViewById<ImageView>(Resource.Id.imageView); image.SetImageBitmap(item.Image); //名前 var textViewName = view.FindViewById<TextView>(Resource.Id.textViewName); textViewName.Text = item.Name; //コメント var textViewComment = view.FindViewById<TextView>(Resource.Id.textViewComment); textViewComment.Text = item.Comment; return view; } }
1アイテム用のaxmlです。
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="fill_parent" android:layout_height="fill_parent"> <ImageView android:layout_width="80dip" android:layout_height="80dip" android:id="@+id/imageView" /> <LinearLayout android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/linearLayout1"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textViewName" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/textViewComment" /> </LinearLayout> </LinearLayout>
最後に使用方法です。
//アイコン用画像の生成 var bmp = BitmapFactory.DecodeResource(Resources,Resource.Drawable.Xamarin); //データの作成 var list = new List<ListItem>(); for (var i = 0; i < 50; i++){ list.Add(new ListItem() { Image = bmp, Name = "Name"+i, Comment = "MESSAGE"+i }); } //ListViewのAdapterに作成したMyAdapterをセットする。データは、MyAdapterのコンストラクタに渡します。 var listView = FindViewById<ListView>(Resource.Id.listView1); listView.Adapter = new MyAdapter(this, 0, list);