こんにちは。エクセルソフトの田淵です。
先日はまずは一番シンプルな単一行の SimpleListItem1 をセルにした ListView にデータを追加したり削除したりしました。
ytabuchi.hatenablog.com
今回は独自のセルを用意してデータ追加、削除を行ってみます。こんな感じです。
サンプルは以下に置いておきました。
github.com
セルの CustomView を作成
Android の ListView には Adapter とセルの View が必要です。公式ページ の Sample Code「CustomRowView」をベースにしています。
最初に View を用意します。
View は普通に Layout axml です。新規にレイアウトを作成し、任意のレイアウトを組んでください。今回は左に ImageView、右に縦に TextView を2つ並べ、一番右側に iOS っぽい矢印を入れてます。
こんな感じ。RelativeLayout
で最初に ImageView
を配置。2つの TextView
を layout_toRightOf="@+id/Image"
や layout_below="@id/NameText"
を使って並べていきます。
xml version="1.0" encoding="utf-8"
<RelativeLayout xmlnsp1="http://schemas.android.com/apk/res/android"
p1layout_width="match_parent"
p1layout_height="match_parent"
p1id="@+id/relativeLayout1">
<ImageView
p1src="@drawable/Icon"
p1layout_width="64dp"
p1layout_height="64dp"
p1paddingRight="8dp"
p1paddingLeft="8dp"
p1id="@+id/Image" />
<TextView
p1text="Name"
p1textAppearance="?android:attr/textAppearanceLarge"
p1layout_width="match_parent"
p1layout_height="wrap_content"
p1id="@+id/NameText"
p1layout_toRightOf="@+id/Image"
p1paddingTop="8dp"
p1paddingRight="32dp" />
<TextView
p1text="Age"
p1textAppearance="?android:attr/textAppearanceMedium"
p1layout_width="match_parent"
p1layout_height="wrap_content"
p1layout_toRightOf="@+id/Image"
p1layout_below="@id/NameText"
p1id="@+id/AgeText"
p1paddingRight="32dp" />
<TextView
p1text=">"
p1textAppearance="?android:attr/textAppearanceMedium"
p1layout_width="wrap_content"
p1layout_height="wrap_content"
p1id="@+id/RightArrow"
p1layout_alignParentRight="true"
p1layout_centerVertical="true"
p1padding="16dp" />
</RelativeLayout>
RelativeLayout については こちらの記事 が詳しいです。
BaseAdapter のクラスを作成
CustomAdapter は BaseAdapter<T>
を継承して作成しますので、先ほど作成した CustomView の各項目に割り当てる型を用意します。今回は Image 1、string *2 なので次の TableItem.cs
を用意しました。
public class TableItem
{
public string Name { get; set; }
public string Description { get; set; }
public int ImageResourceId { get; set; }
}
Image は今回 Xamarin のサンプルに習い .SetImageResource(int resId)
を使用したので int
で用意しましたが、.SetImageBitmap(Android.Graphic.Bitmap bm)
や .SetImageURI(Android.Net.Uri uri)
を使用する場合は適切な型を指定します(すみません。Android.Net.Uri
はまだ使い方が良く分かってなく…)。
CustomAdapter を作成
クラスを作成し、BaseAdapter<TableItem>
を継承します。
Visual Studio であれば、必要なメソッドを用意してくれますので、それぞれに実装します。Xamarin のサンプルに習い次のように実装しました。
public class CustomListAdapter : BaseAdapter<TableItem>
{
List<TableItem> items;
Activity context;
public CustomListAdapter(Activity context, List<TableItem> items)
{
this.context = context;
this.items = items;
}
public override long GetItemId(int position)
{
return position;
}
public override TableItem this[int position]
{
get { return items[position]; }
}
public override int Count
{
get { return items.Count; }
}
public override View GetView(int position, View convertView, ViewGroup parent)
{
var item = items[position];
View view = convertView;
if (view == null)
view = context.LayoutInflater.Inflate(Resource.Layout.CustomView, null);
view.FindViewById<TextView>(Resource.Id.NameText).Text = item.Name;
view.FindViewById<TextView>(Resource.Id.AgeText).Text = item.Description.ToString();
view.FindViewById<ImageView>(Resource.Id.Image).SetImageResource(item.ImageResourceId);
return view;
}
}
GetView
メソッド内で、TableItem
のプロパティをそれぞれ割り当てます。
Activity で CustomAdapter を使う
ソースの List
を用意して先ほど作った CustomListAdapter(Activity context, List<TableItem> items)
をインスタンス化して ListView
の Adapter に指定します。
tableItem.Insert(0, new TableItem()
{
Name = "item_1",
Description = "Description_1",
ImageResourceId = images[4]
});
var customAdapter = new CustomListAdapter(this, tableItem);
listView.Adapter = customAdapter;
データの追加、削除は、ソースの List に対して行い、Adapter に変更を通知してあげると良いそうです。(@Santea3173 さん、ありがとう!!)
ボタンをタップするとデータを追加したり削除したりする部分はこんな感じです。
var addButton = FindViewById<Button>(Resource.Id.customListViewAddButton);
addButton.Click += (sender, e) =>
{
var rdm = new Random();
tableItem.Insert(0, new TableItem()
{
Name = "item_" + rdm.Next(),
Description = "Description_" + rdm.Next(),
ImageResourceId = images[rdm.Next(0, 8)]
});
customAdapter.NotifyDataSetChanged();
};
var deleteButton = FindViewById<Button>(Resource.Id.customListViewDeleteButton);
deleteButton.Click += (sender, e) =>
{
if (tableItem.Count > 0)
{
tableItem.Remove(tableItem[tableItem.Count - 1]);
customAdapter.NotifyDataSetChanged();
}
};
*1 ですが、Randomで参照するので作成した画像データを元に int[] に Resource.Drawable.ramen1 などを入れておいてます。
ListView もそんなに怖くないですね。
ちょっとビビっていましたが、Android の ListView は大丈夫そうです。次は CardView か RecyclerView とかにチャレンジしたいですね。
Xamarin 気になった方は
是非 ダウンロード して触ってみてください。Visual Studio 2015 をご利用の方は Update 3 にアップデートする際にカスタムインストールで Xamarin を追加しましょう。
学習用リソース や JXUG リンクページ に参考資料を纏めてますので併せてどうぞ。
Xamarin の導入支援サービスを始めました。ベースは基本的なアプリを一緒に作ることで Xamarin を使えるようになって頂く内容ですが、ご要望に応じて講習内容のカスタマイズも可能です。詳しくは田淵までお問い合わせください(^^)
ytabuchi.hatenablog.com
Xamarin の情報が欲しい方はこのブログも購読いただいたり、私のTwitterアカウントをフォローいただいたりすると嬉しいです。
私が所属している エクセルソフト の宣伝を少しさせてください。弊社は開発者向けの様々なソフトウェアを扱っています。おなじみの ReSharper (JetBrains)、 や Atlassian の JIRA, Confluence、Office/PDF ファイルを .NET/Java で操作するライブラリ Aspose(アスポーズ)、Windows アプリ、Web ページ、iOS/Android アプリの UI テストができる TestComplete などお勧めです(^^) また、Visual Studio Professional/Enterprise with MSDN も販売してますし、日本で売っていない海外のソフトウェア、開発ツールなどを弊社経由で日本円で購入頂くことも可能です。ご興味あれば 弊社ページ を覗いてみてください。
以上です。