SIN@SAPPOROWORKSの覚書

C#を中心に、夜な夜な試行錯誤したコードの記録です。

Xamarin.Android ListView

【 Xamarin 記事一覧 】

1 基本的なListView

001

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ピクセルの位置に移動する

002

選択は、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種類がインテリセンスで見て取れます。この辺が学習曲線を上げるんですよね・・・
003

2 表示内容のカスタマイズ

004
表示内容をカスタマイズするには、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);

【 Xamarin 記事一覧 】