Abstraktes Header-Bild in den Farben von tsjdev apps

Blogbeitrag

Xamarin.Forms Controls: RepeaterView mit alternativen Zeilenfarbe

Ich habe bereits gezeigt, wie man sich ganz einfach eine RepeaterView erstellen kann. Nun möchte ich die bestehende Implementierung so erweitern, dass jede zweite Zeile eine andere Hintergrundfarbe hat. Dies hat den großen Vorteil, dass sich die Lesbarkeit der Daten deutlich erhöht und man einen größeren Kontrast zwischen den einzelnen Einträgen herstellen.

Wir öffnen unsere Klasse RepeaterView.cs und fügen zwei neue BindableProperties hinzu. Zum einen wollen wir die alternative Zeilenfarbe ein- bzw. ausschalten und zum anderen wollen wir die Hintergrundfarbe individuell einstellen. Daher erhalten wir die beiden folgenden Einträge:

public static readonly BindableProperty IsAlternateRowColorEnabledProperty =
    BindableProperty.Create(nameof(IsAlternateRowColorEnabled), typeof(bool), typeof(RepeaterView), false);

public bool IsAlternateRowColorEnabled
{
    get => (bool)GetValue(IsAlternateRowColorEnabledProperty);
    set => SetValue(IsAlternateRowColorEnabledProperty, value);
}

public static readonly BindableProperty AlternateRowColorProperty =
    BindableProperty.Create(nameof(AlternateRowColor), typeof(Color), typeof(RepeaterView), Color.Black);

public Color AlternateRowColor
{
    get => (Color)GetValue(AlternateRowColorProperty);
    set => SetValue(AlternateRowColorProperty, value);
}

Nun passen wir die Methode ViewFor an. Dafür ergänzen wir den optionalen Parameter isEvenRow vom Typ bool, welcher später angibt, ob es sich um eine gerade Zeile handelt. Ebenso fügen wir die Logik hinzu, dass validiert wird, ob die alternative Zeilenfarbe aktiviert ist und sollte isEvenRow auf true stehen, so wird die Hintergrundfarbe entsprechend angepasst. Somit erhalten wir die folgende Methode:

protected virtual View ViewFor(object item, bool isEvenRow = false)
{
    if (ItemTemplate == null)
        return null;

    var content = ItemTemplate.CreateContent();

    var view = content is ViewCell viewCell ? viewCell.View : content as View;

    view.BindingContext = item;

    if (ItemTappedCommand != null)
        AddTapGestureToChildView(view);

    if (IsAlternateRowColorEnabled)
    {
        if (isEvenRow)
            view.BackgroundColor = AlternateRowColor;
    }

    return view;
}

Im nächsten Schritt passen wir die Methode ItemsSourcePropertyOnChanged an, denn innerhalb dieser Methode können wir ermitteln, ob es sich um eine gerade Zeile und diese Information entsprechend an die ViewFor-Methode übergeben. Wir erhalten dann die folgende Methode:

private static void ItemsSourcePropertyOnChanged(BindableObject bindable, 
    object oldValue, object newValue)
{
    if (!(bindable is RepeaterView control))
        return;

    control.Children.Clear();

    var collection = (ICollection)newValue;
    if (collection == null)
        return;

    if (collection is INotifyCollectionChanged observableCollection)
        control.AddCollectionNotificationsListener(observableCollection);

    var isEvenRow = false;
    foreach (var item in collection)
    {
        control.Children.Add(control.ViewFor(item, isEvenRow));
        isEvenRow = !isEvenRow;
    }
}

Nun müssen wir abschließend noch die Methode ObsersavableCollectionOnCollectionChanged anpassen. Hier fügen wir am Anfang ein If-Statement hinzu, denn sollte die alternative Zeilenfarbe aktiviert sein, so müssen wir bei einer Veränderung der ItemsSource die vollständige Liste neu berechnen. Die bestehende Logik wandert dann in den Else-Zweig. Hier der Code-Ausschnitt, welcher eingefügt werden muss:

if (IsAlternateRowColorEnabled)
{
    Children.Clear();

    var isEvenRow = false;
    foreach (var item in (ICollection)s)
    {
        Children.Add(ViewFor(item, isEvenRow));
        isEvenRow = !isEvenRow;
    }
}

Damit können wir die neue Funktionalität bereits verwenden und der folgende Screenshot zeigt das Ergebnis:

Der gesamte Code befindet sich natürlich auch wieder auf GitHub und ich bin jetzt schon gespannt, wie wir die RepeaterView noch weiter verbessern können.

Weiterempfehlen

Diesen Beitrag teilen

Wenn dir der Beitrag gefallen hat: gern weiterreichen. Gute Links dürfen sich ruhig schnell verbreiten.

Vorheriger/Nächster Beitrag

Windows 10 IoT Core auf einem Raspberry Pi Vorheriger Beitrag Windows 10 IoT Core auf einem Raspberry Pi Mail vom AWS IoT Button senden in C# Nächster Beitrag Mail vom AWS IoT Button senden in C#
Android Archive Erstellung schlägt fehl Android Archive Erstellung schlägt fehl Xamarin.iOS App mit Azure DevOps bauen Xamarin.iOS App mit Azure DevOps bauen Buch-Tipp: Cross-Plattform-Apps mit Xamarin.Forms entwickeln von André Krämer Buch-Tipp: Cross-Plattform-Apps mit Xamarin.Forms entwickeln von André Krämer Xamarin.Android App mit Azure DevOps bauen Xamarin.Android App mit Azure DevOps bauen
Lust auf ein kurzes digitales Hallo? Wenn du eine Idee teilen, eine Frage loswerden oder ein Projekt anschieben willst: mein Posteingang ist deutlich zuverlässiger als Brieftauben. apps@tsjdev-apps.de Mail schicken