Xamarin.Android
RecyclerView
サーチ…
RecyclerViewの基本
これは、 Android Support Library V7 RecyclerView
使用例です。サポートライブラリは、新しい機能の下位互換性のあるバージョンを提供し、フレームワークに含まれていない有用なUI要素を提供し、アプリケーションが引き出すことができるさまざまなユーティリティを提供するため、一般に推奨されます。
RecyclerView
を入手するには、必要なNugetパッケージをインストールします。まず、 v7 recyclerview
を検索します。 Xamarin Android Support Library - v7 RecyclerView
表示されるまでスクロールダウンします。それを選択し、[ パッケージの追加 ] をクリックします。
また、 Android Support Library V7 RecyclerView
は、Xamarinコンポーネントとして利用できます。コンポーネントを追加するには、ソリューションエクスプローラでAndroidプロジェクト内のComponents
右クリックし、[ Get More Components
をGet More Components
]をクリックしGet More Components
。
表示されるComponent Storeウィンドウで、RecyclerViewを検索します。検索リストで、 Android Support Library V7 RecyclerView
選択します。次に、[ Add to App
にAdd to App
]をクリックします。コンポーネントがプロジェクトに追加されます。
次のステップはRecyclerViewをページに追加することです。 axml
(レイアウト)ファイル内で、 RecyclerView
を以下のように追加することができます。
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
RecyclerViewには、 Adapter
とViewHolder
基本的な標準実装のために、少なくとも2つのヘルパークラスが設定されている必要がありViewHolder
。 Adapter
アイテムレイアウトを膨張させ、RecyclerView内に表示されるビューにデータをバインドします。 ViewHolderはビュー参照を検索して保存します。ビューホルダーは、アイテムビューのクリックを検出するのにも役立ちます。
次に、アダプタクラスの基本的な例を示します
public class MyAdapter : RecyclerView.Adapter
{
string [] items;
public MyAdapter (string [] data)
{
items = data;
}
// Create new views (invoked by the layout manager)
public override RecyclerView.ViewHolder OnCreateViewHolder (ViewGroup parent, int viewType)
{
// set the view's size, margins, paddings and layout parameters
var tv = new TextView (parent.Context);
tv.SetWidth (200);
tv.Text = "";
var vh = new MyViewHolder (tv);
return vh;
}
// Replace the contents of a view (invoked by the layout manager)
public override void OnBindViewHolder (RecyclerView.ViewHolder viewHolder, int position)
{
var item = items [position];
// Replace the contents of the view with that element
var holder = viewHolder as MyViewHolder;
holder.TextView.Text = items[position];
}
public override int ItemCount {
get {
return items.Length;
}
}
}
OnCreateViewHolder
メソッドでは、最初にViewを展開し、ViewHolderクラスのインスタンスを作成します。このインスタンスを返す必要があります。このメソッドは、ViewHolderの新しいインスタンスが必要なときにアダプタによって呼び出されます。このメソッドは、単一のセルごとに呼び出されることはありません。 RecyclerViewにビューを満たすのに十分なセルがあれば、Viewからスクロールされている古いセルを再利用して、それ以降のセルを再利用します。
OnBindViewHolder
コールバックは、指定された位置にデータを表示するために、Adapterによって呼び出されます。このメソッドは、itemViewの内容を更新して、指定された位置の項目を反映する必要があります。
セルにはTextView
が1つしか含まれていないため、以下のように単純なViewHolderを持つことができます。
public class MyViewHolder : RecyclerView.ViewHolder
{
public TextView TextView { get; set; }
public MyViewHolder (TextView v) : base (v)
{
TextView = v;
}
}
次のステップは、 Activity
内のものを配線することです。
RecyclerView mRecyclerView;
MyAdapter mAdapter;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
SetContentView (Resource.Layout.Main);
mRecyclerView = FindViewById<RecyclerView> (Resource.Id.recyclerView);
// Plug in the linear layout manager:
var layoutManager = new LinearLayoutManager (this) { Orientation = LinearLayoutManager.Vertical };
mRecyclerView.SetLayoutManager (layoutManager);
mRecyclerView.HasFixedSize = true;
var recyclerViewData = GetData();
// Plug in my adapter:
mAdapter = new MyAdapter (recyclerViewData);
mRecyclerView.SetAdapter (mAdapter);
}
string[] GetData()
{
string[] data;
.
.
.
return data;
}
LayoutManagerクラスは、RecyclerView内のアイテムビューの測定と位置付け、およびユーザーが見えなくなったアイテムビューのリサイクル時期に関するポリシーの決定を担当します。 RecyclerView
前に、 ListView
を使用して垂直方向にスクロールするリストのようにセルを配置し、 GridView
を使用してアイテムを2次元のスクロール可能なグリッドに表示する必要がありました。しかし、今度は、別のLayoutMangerを設定することで、RecyclerViewで両方を達成することができます。 LinearLayoutManager
はListViewのようにセルを配置し、 GridLayoutManager
はセルのグリッドを整列します。
RecyclerView with Clickイベント
この例は、Xamarin.Android RecyclerViewでClick EventHandlerを設定する方法を示しています。
Android Javaでは、Clickのリスナーを設定する方法は、クリックされるビューに対してonClickListenerを使用しています。
ImageView picture = findViewById(R.id.item_picture);
picture.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// do stuff
}
});
ただし、Xamarin.Androidでは 、Clickイベントのリスナーを設定する方法は、次の方法でEventHandlerを追加することです。
1。
ImageView picture = FindViewById<ImageView>(Resource.Id.item_picture);
picture.Click += delegate {
// do stuff
};
2。
ImageView picture = FindViewById<ImageView>(Resource.Id.item_picture);
picture.Click += async delegate {
// await DoAsyncMethod();
// do async stuff
};
3。
ImageView picture = FindViewById<ImageView>(Resource.Id.item_picture);
picture.Click += Picture_Click;
... // rest of your method
private void Picture_Click(object sender, EventArgs e)
{
// do stuff
}
EventHandlerは追加されており、設定されていないことに注意してください。 Click EventHandlerがGridView / ListViewアダプタのGetViewメソッド、またはRecyclerView.AdapterのOnBindViewHolderメソッドに追加された場合、アイテムビューが作成されるたびに新しいEventHandlerが追加されます。複数回スクロールすると、複数のEventHandlerが追加され、ビューがクリックされるとすべてのイベントが発生します。
この問題を回避するには、EventHandlerの登録を解除し、GetViewまたはOnBindViewHolderメソッドで引き続きサブスクライブする必要があります。また、EventHandlerを設定するには3番の方法を使用する必要があります。そうしないと、EventHandlerの登録を解除できません。
Clickイベントを含むRecyclerView.Adapterの例を以下に示します。
public class ViewHolderPerson : Android.Support.V7.Widget.RecyclerView.ViewHolder
{
public View Item { get; private set; }
public ImageView Picture { get; private set; }
public TextView Name { get; private set; }
public ViewHolderPerson(View itemView) : base(itemView)
{
this.Item = itemView;
this.Picture = itemView.FindViewById<ImageView>(Resource.Id.Item_Person_Picture);
this.Name = itemView.FindViewById<TextView>(Resource.Id.Item_Person_Name);
}
}
public class AdapterPersons : Android.Support.V7.Widget.RecyclerView.Adapter
{
private Context context;
private Android.Support.V7.Widget.RecyclerView recyclerView;
private List<Person> persons;
public AdapterPersons(Context context, Android.Support.V7.Widget.RecyclerView recyclerView, List<Person> persons)
{
this.context = context;
this.recyclerView = recyclerView;
this.persons = persons;
}
public override int ItemCount => persons.Count;
public override void OnBindViewHolder(RecyclerView.ViewHolder holder, int position)
{
Person person = this.persons[position];
((ViewHolderPerson)holder).Name.Text = person.Name;
((ViewHolderPerson)holder).Picture.SetImageBitmap(person.Picture);
// Unsubscribe and subscribe the method, to avoid setting multiple times.
((ViewHolderPerson)holder).Item.Click -= Person_Click;
((ViewHolderPerson)holder).Item.Click += Person_Click;
}
private void Person_Click(object sender, EventArgs e)
{
int position = this.recyclerView.GetChildAdapterPosition((View)sender);
Person personClicked = this.persons[position];
if(personClicked.Gender == Gender.Female)
{
Toast.MakeText(this.context, "The person clicked is a female!", ToastLength.Long).Show();
}
else if(personClicked.Gender == Gender.Male)
{
Toast.MakeText(this.context, "The person clicked is a male!", ToastLength.Long).Show();
}
}
public override RecyclerView.ViewHolder OnCreateViewHolder(ViewGroup parent, int viewType)
{
View itemView = LayoutInflater.From(parent.Context).Inflate(Resource.Layout.item_person, parent, false);
return new ViewHolderPerson(itemView);
}
}