Best way to handle screen rotation in CollectionView

I currently have this issue in my CollectionView.

I have a grouped list displayed in my app, when the screen rotates the items that are not visible are changed to the right width but not the ones visible. What could be the best approach to fix this without the need of refreshing the whole page?

Code:

<RelativeLayout BackgroundColor="Transparent">
                <Label
                    Margin="{StaticResource HeaderLabelMargin}"
                    FontFamily="{DynamicResource MontserratBold}"
                    FontSize="Medium"
                    HorizontalTextAlignment="Center"
                    IsVisible="{Binding IsListEmpty}"
                    RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                           Property=Height,
                                                                           Factor=1}"
                    RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                          Property=Width,
                                                                          Factor=1}"
                    Text="{xt:Translate no_combos}"
                    VerticalTextAlignment="Center" />
                <CollectionView
                    IsGrouped="True"
                    IsVisible="{Binding IsListEmpty, Converter={xt:ValueBoolInverseConverter}}"
                    ItemsSource="{Binding ComboList}"
                    RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                           Property=Height,
                                                                           Factor=1}"
                    RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                          Property=Width,
                                                                          Factor=1}"
                    SelectionMode="None">
                    <CollectionView.Header>
                        <StackLayout>
                            <Label
                                Margin="{StaticResource HeaderLabelMargin}"
                                FontFamily="{DynamicResource MontserratBold}"
                                FontSize="Medium"
                                HorizontalOptions="Center"
                                Text="{xt:Translate character_facing_right}" />
                            <Picker />
                        </StackLayout>
                    </CollectionView.Header>
                    <CollectionView.GroupHeaderTemplate>
                        <DataTemplate x:DataType="models:ComboCategoryView">
                            <StackLayout>
                                <sfBorder:SfBorder
                                    Margin="{StaticResource HeaderBorderMargin}"
                                    BackgroundColor="{StaticResource AccentColor}"
                                    BorderColor="{StaticResource ButtonBorderColor}"
                                    BorderWidth="{StaticResource HeaderBorderWidth}"
                                    CornerRadius="{StaticResource HeaderBorderCornerRadius}">
                                    <Label
                                        Margin="{StaticResource StandardSpacing}"
                                        FontFamily="{DynamicResource MontserratBoldItalic}"
                                        FontSize="Medium"
                                        Text="{Binding Category}" />
                                </sfBorder:SfBorder>
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.GroupHeaderTemplate>
                    <CollectionView.ItemTemplate>
                        <DataTemplate x:DataType="models:ComboView">
                            <controls:ComboItem
                                Title="{Binding Title}"
                                Combo="{Binding Combo}"
                                Comment="{Binding Comment}"
                                IsStock="{Binding IsStock}"
                                Type="{Binding Type}"
                                UniqueId="{Binding UniqueId}" />
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                    <CollectionView.Footer>
                        <ContentView Margin="{StaticResource FooterSpacing}" />
                    </CollectionView.Footer>
                    <CollectionView.EmptyView>
                        <StackLayout>
                            <Label
                                Margin="{StaticResource HeaderLabelMargin}"
                                FontSize="Medium"
                                HorizontalOptions="Center"
                                Text="{xt:Translate no_combos}" />
                        </StackLayout>
                    </CollectionView.EmptyView>
                </CollectionView>
                <sfBorder:SfBorder
                    Margin="{StaticResource StandardSpacing}"
                    BackgroundColor="{StaticResource PrimaryColor}"
                    BorderColor="{StaticResource ButtonBorderColor}"
                    BorderWidth="{StaticResource ButtonBorderWidth}"
                    CornerRadius="{StaticResource ButtonBorderRadius}"
                    RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                      Property=Width,
                                                                      Factor=1,
                                                                      Constant={StaticResource ButtonRelativeConstant}}"
                    RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                      Property=Height,
                                                                      Factor=1,
                                                                      Constant={StaticResource ButtonRelativeConstant}}">
                    <Button
                        BackgroundColor="Transparent"
                        Clicked="Handle_AddCombo_Clicked"
                        FontSize="Large"
                        HeightRequest="{StaticResource ButtonSize}"
                        Text="+"
                        TextColor="{StaticResource MainTextColor}"
                        WidthRequest="{StaticResource ButtonSize}" />
                </sfBorder:SfBorder>
                <sfBusyInd:SfBusyIndicator
                    AnimationType="Box"
                    IsVisible="{Binding IsBusy}"
                    RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                           Property=Height,
                                                                           Factor=1}"
                    RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                          Property=Width,
                                                                          Factor=1}"
                    ViewBoxHeight="{StaticResource IndicatorSize}"
                    ViewBoxWidth="{StaticResource IndicatorSize}" />
            </RelativeLayout>

Answers

  • JoeMankeJoeManke USMember ✭✭✭✭✭

    I don't know if this is an accurate assessment at all, but my first instinct is that your problem is the RelativeLayout, specifically that the constraints are not being updated when the parent Height/Width properties change.

  • JarvanJarvan Member, Xamarin Team Xamurai

    Try to detect CollectionView's SizeChanged event and call Layout.ForceLayout method in it.

    <RelativeLayout x:Name="relativeLayout">
        ...
        <CollectionView x:Name="collectionView" SizeChanged="collectionview_SizeChanged">
            ...
        </CollectionView>
    </RelativeLayout>
    
    private void collectionview_SizeChanged(object sender, EventArgs e)
    {
        relativeLayout.ForceLayout();
    }
    

    Refer to: https://forums.xamarin.com/discussion/50487/relativelayout-constraint-doesnt-work-without-rotation-first

  • albertoha94albertoha94 Member ✭✭

    Hello @JoeManke
    I tried with a different layout (´StackLayout´) to see if that was the case and no, I still had the rows issue.

    Hello @Jarvan
    Unfortunately, this didn't solve the issue. I tried changing the color of the ´CollectionView´ to green to see if it was expanding correctly and it was. So the issue are the rows inside, those are the ones that are not notified, not the ones visible at least.

  • JarvanJarvan Member, Xamarin Team Xamurai
    edited December 4

    A workaround is to set the scroll an item at an index into view after refreshing the whole page. Detect the Scrolled event to get the scroll item's index and use ScrollTo emthod to set the scroll item. Tutorial.

    int index;
    
    private void CollectionView_Scrolled(object sender, ItemsViewScrolledEventArgs e)
    {
        index = e.CenterItemIndex;
    }
    ...
    collecionView.ScrollTo(index);
    
  • albertoha94albertoha94 Member ✭✭

    @Jarvan
    Hello again, I tried your solution but I'm uncertain how to use it.
    I tried to add it like this:

    Page:

    public void Handle_CollectionView_SizeChanged(object sender, EventArgs e)
            {
                collectionViewMain.ScrollTo(viewModel.Index);
            }
    
            public void Handle_CollectionView_Scrolled(object sender, ItemsViewScrolledEventArgs e)
            {
                viewModel.Index = e.CenterItemIndex;
            }
    

    XAML:

    <CollectionView
                        x:Name="collectionViewMain"
                        IsGrouped="True"
                        Scrolled="Handle_CollectionView_Scrolled"
                        SizeChanged="Handle_CollectionView_SizeChanged"
    

    But nothing seems to change.
    Thx.

Sign In or Register to comment.