Xamarin.Android
RecyclerView
Zoeken…
RecyclerView Basics
Dit is een voorbeeld van het gebruik van Android Support Library V7 RecyclerView
. Ondersteuningsbibliotheken worden over het algemeen aanbevolen omdat ze achterwaarts compatibele versies van nieuwe functies bieden, nuttige UI-elementen bieden die niet in het framework zijn opgenomen en een reeks hulpprogramma's bieden waar apps gebruik van kunnen maken.
Om de RecyclerView
te krijgen, zullen we de nodige Nuget-pakketten installeren. Eerst zullen we zoeken naar v7 recyclerview
. Scroll naar beneden totdat we Xamarin Android Support Library - v7 RecyclerView
. Selecteer het en klik op Pakket toevoegen .
Als alternatief is Android Support Library V7 RecyclerView
beschikbaar als een Xamarin-component. Om het component toe te voegen, klikt u met de rechtermuisknop op Components
in het Android-project in Solution Explorer en klikt u op Get More Components
.
Zoek in het venster Component Store naar RecyclerView. Selecteer Android Support Library V7 RecyclerView
in de zoeklijst. Klik vervolgens op Add to App
. De component wordt toegevoegd aan het project.
De volgende stap is het toevoegen van de RecyclerView aan een pagina. Binnen het axml
bestand (layout) kunnen we RecyclerView
toevoegen zoals hieronder.
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:scrollbars="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" />
RecyclerView vereist dat ten minste twee hulpklassen worden ingesteld voor de standaard standaardimplementatie, namelijk: Adapter
en ViewHolder
. Adapter
blaast itemlay-outs op en koppelt gegevens aan weergaven die worden weergegeven in een RecyclerView. ViewHolder kijkt omhoog en slaat viewreferenties op. De weergavehouder helpt ook bij het detecteren van klikken op itemweergave.
Hier is een eenvoudig voorbeeld van adapterklasse
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;
}
}
}
In de OnCreateViewHolder
methode blazen we eerst een View op en maken we een instantie van de ViewHolder-klasse. Dit exemplaar moet worden geretourneerd. Deze methode wordt door de adapter aangeroepen wanneer deze een nieuw exemplaar van ViewHolder vereist. Deze methode wordt niet voor elke cel aangeroepen. Nadat RecyclerView voldoende cellen heeft om de weergave te vullen, worden de oude cellen die uit de weergave worden geschoven opnieuw gebruikt voor verdere cellen.
De OnBindViewHolder
callback wordt door Adapter aangeroepen om de gegevens op de opgegeven positie weer te geven. Deze methode moet de inhoud van het itemView bijwerken om het item op de gegeven positie weer te geven.
Omdat de cel bevat slechts een enkele TextView
, kunnen we een eenvoudige ViewHolder zoals hieronder hebben.
public class MyViewHolder : RecyclerView.ViewHolder
{
public TextView TextView { get; set; }
public MyViewHolder (TextView v) : base (v)
{
TextView = v;
}
}
De volgende stap is om dingen te bedraden in 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;
}
De klasse LayoutManager is verantwoordelijk voor het meten en positioneren van artikelweergaven in een RecyclerView en bepaalt het beleid voor het recyclen van artikelweergaven die niet langer zichtbaar zijn voor de gebruiker. Vóór de RecyclerView
moesten we ListView
gebruiken om cellen in te rangschikken zoals in een verticaal scrollende lijst en GridView
om items in een tweedimensionaal, schuifbaar raster weer te geven. Maar nu kunnen we beide bereiken met RecyclerView door een andere LayoutManger in te stellen. LinearLayoutManager
rangschikt cellen zoals in een ListView en GridLayoutManager
rangschikt cellen Grid mode.
RecyclerView met Click-evenementen
Dit voorbeeld laat zien hoe u Click EventHandlers in een Xamarin.Android RecyclerView kunt instellen.
In Android Java is de manier om een luisteraar voor een klik in te stellen een onClickListener voor de weergave waarop wordt geklikt, zoals deze:
ImageView picture = findViewById(R.id.item_picture);
picture.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// do stuff
}
});
In Xamarin.Android is de manier om een luisteraar voor een Click-evenement in te stellen door een EventHandler toe te voegen , op de volgende manieren:
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
}
Merk op dat de EventHandler is toegevoegd, niet ingesteld. Als de Click EventHandler wordt toegevoegd in een GetView-methode van een GridView / ListView-adapter of een OnBindViewHolder-methode van een RecyclerView.Adapter, wordt elke keer dat de itemweergave wordt gemaakt, een nieuwe EventHandler toegevoegd. Na verschillende keren scrollen worden meerdere EventHandlers toegevoegd en wanneer op de weergave wordt geklikt, worden ze allemaal geactiveerd.
Om dit probleem te voorkomen, moeten de EventHandlers worden afgemeld en vervolgens worden geabonneerd in de GetView- of OnBindViewHolder-methoden. Ze moeten ook de nummer 3.- manier gebruiken om de EventHandler in te stellen, anders is het niet mogelijk om de EventHandlers uit te schrijven.
Een voorbeeld van een RecyclerView.Adapter met Click-evenementen wordt hieronder weergegeven:
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);
}
}