Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Android] Update the adapter used by RecyclerViewScrollListener #6601

Merged
merged 1 commit into from
May 5, 2022

Conversation

rmarinho
Copy link
Member

@rmarinho rmarinho commented Apr 28, 2022

Description of Change

When the ItemsSource/Adapter was changing we weren't updating the reference on the scrollviewer so we could't get the right position.

Did some other cleanup

Issues Fixed

Fixes #6328
Fixes #6457

Use the following page to test - Make sure position changes on load, then change categor on top, position should reset to 0, and swipe again to see if position updates properly.

	public partial class CarouselDemo : ContentPage
	{
		Color GetColor(int page) => page switch
		{
			0 => Colors.DarkRed,
			1 => Colors.DarkGreen,
			2 => Colors.DarkBlue,
			3 => Colors.DarkOrange,
			4 => Colors.DarkOliveGreen,
			_ => null
		};

		public CarouselDemo()
		{
			List<Category> categories = new List<Category>();

			for (int cat = 0; cat < 4; cat++)
			{
				var category = new Category()
				{
					Col = cat,
					Name = $"Category {cat}"
				};

				for (int page = 0; page < 5; page++)
				{
					var items = new List<Item>();

					for (int col = 0; col < 5; col++)
					{
						for (int row = 0; row < 6; row++)
						{
							items.Add(new Item()
							{
								Name = $"Categ {cat}, page {page}",
								Col = col,
								Row = row,
								Color = GetColor(page)
							});
						}
					}

					category.Items.Add(new Pager<Item>(page, items));
				}

				categories.Add(category);
			}

			Categories.Add(new Pager<Category>(0, categories));

			CurrentCategory = Categories[0][0];

			BindingContext = this;
			InitializeComponent();
		}

		public List<Pager<Category>> Categories { get; } = new List<Pager<Category>>();

		private Category currentCategory;
		public Category CurrentCategory
		{
			get => currentCategory;
			set
			{
				currentCategory = value;
				OnPropertyChanged();
			}
		}

		private void CategBtn_Clicked(object sender, EventArgs e)
		{
			if (sender is Button b && b.BindingContext is Category cat)
				CurrentCategory = cat;
		}
	}
	public abstract class BaseClass
	{
		public int Row { get; set; }
		public int Col { get; set; }

		public string Name { get; set; }
	}
	public class Category : BaseClass
	{
		public List<Pager<Item>> Items { get; } = new List<Pager<Item>>();
	}
	public class Item : BaseClass
	{
		public Color Color { get; set; }
	}
	public class Pager<T> : List<T>
	{
		public Pager(int page, IEnumerable<T> items) : base(items)
		{
			PageIndex = page;
		}

		public int PageIndex { get; }
	}

XAML

  <ContentPage.Resources>

        <DataTemplate x:Key="CategView">
            <Grid BindableLayout.ItemsSource="{Binding}" ColumnSpacing="5"
                  ColumnDefinitions="*,*,*,*">

                <BindableLayout.ItemTemplate>

                    <DataTemplate>

                        <Button x:Name="CategBtn"
                                Grid.Column="{Binding Col}"
                                Background="DarkRed"
                                Clicked="CategBtn_Clicked"
                                CornerRadius="0"
                                FontSize="16"
                                LineBreakMode="WordWrap"
                                Text="{Binding Name}" />

                    </DataTemplate>

                </BindableLayout.ItemTemplate>
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="ItemView">
            <Grid BindableLayout.ItemsSource="{Binding}"
                  ColumnDefinitions="*,*,*,*,*"
                  ColumnSpacing="5"
                  RowDefinitions="*,*,*,*,*,*"
                  RowSpacing="5">

                <BindableLayout.ItemTemplate>

                    <DataTemplate>

                        <Button Grid.Row="{Binding Row}"
                                Grid.Column="{Binding Col}"
                                Background="{Binding Color}"
                                CornerRadius="0"
                                FontSize="14"
                                LineBreakMode="WordWrap"
                                Text="{Binding Name}"
                                TextColor="White" />

                    </DataTemplate>

                </BindableLayout.ItemTemplate>

            </Grid>
        </DataTemplate>

    </ContentPage.Resources>

    <Grid RowDefinitions="Auto,0.25*,*" RowSpacing="5">

        <Label FontSize="24"
               HorizontalTextAlignment="Center"
               TextColor="Green"
               VerticalTextAlignment="Center">
            <Label.Text>
                <MultiBinding StringFormat="Position: {0}">
                    <Binding Path="Position"
                             Source="{x:Reference ItemSwiper}" />
                </MultiBinding>
            </Label.Text>
        </Label>

        <CarouselView Grid.Row="1"
                      ItemTemplate="{StaticResource CategView}"
                      ItemsSource="{Binding Categories}"
                      Loop="False">

            <CarouselView.ItemsLayout>
                <LinearItemsLayout Orientation="Horizontal"
                                   SnapPointsAlignment="Start"
                                   SnapPointsType="MandatorySingle" />
            </CarouselView.ItemsLayout>

        </CarouselView>

        <CarouselView x:Name="ItemSwiper"
                      Grid.Row="2"
                      Background="Yellow"
                      ItemTemplate="{StaticResource ItemView}"
                      ItemsSource="{Binding CurrentCategory.Items}"
                      Loop="False">

            <CarouselView.ItemsLayout>
                <LinearItemsLayout Orientation="Horizontal"
                                   SnapPointsAlignment="Start"
                                   SnapPointsType="MandatorySingle" />
            </CarouselView.ItemsLayout>

        </CarouselView>

    </Grid>
    ``` 

@rmarinho rmarinho added area-controls-collectionview CollectionView, CarouselView, IndicatorView partner/android Issues for the Android SDK labels Apr 28, 2022
@rmarinho rmarinho added this to the 6.0.300 milestone Apr 28, 2022
@rmarinho rmarinho requested a review from hartez April 28, 2022 19:11
@rmarinho rmarinho linked an issue May 2, 2022 that may be closed by this pull request
@@ -43,11 +43,7 @@ protected virtual TItemsViewSource CreateItemsSource()

protected virtual void ItemsViewPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs property)
{
if (property.Is(Microsoft.Maui.Controls.ItemsView.ItemsSourceProperty))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we no longer updating the ItemsSource when it changes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The mapper does this

@rmarinho rmarinho merged commit 834039c into main May 5, 2022
@rmarinho rmarinho deleted the fix-6328 branch May 5, 2022 21:36
@github-actions github-actions bot locked and limited conversation to collaborators Dec 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-controls-collectionview CollectionView, CarouselView, IndicatorView partner/android Issues for the Android SDK
Projects
None yet
2 participants