サーチ…


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 ComponentsGet More Components ]をクリックしGet More Components

ここに画像の説明を入力

表示されるComponent Storeウィンドウで、RecyclerViewを検索します。検索リストで、 Android Support Library V7 RecyclerView選択します。次に、[ Add to AppAdd 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には、 AdapterViewHolder基本的な標準実装のために、少なくとも2つのヘルパークラスが設定されている必要がありViewHolderAdapterアイテムレイアウトを膨張させ、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);
    }

}


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow