Xamarin.forms: [Enhancement] CollectionView item spacing

Created on 8 Dec 2018  Â·  16Comments  Â·  Source: xamarin/Xamarin.Forms

Summary

The current CollectionView spec (#3172) lacks the ability to specify the amount of space between items inside of it. There are, of course, cases where a user might wish for specific spacing, and could be especially useful with the Grid layout type that CollectionView provides.

API Changes

ListItemsLayout:

  • public double ItemSpacing { get; set; }

GridItemsLayout:

  • public double VerticalItemSpacing { get; set; }
  • public double HorizontalItemSpacing { get; set; }

Intended Use Case

Provide adequate space between items inside of a CollectionView.

On iOS, these will map to GetMinimumLineSpacingForSection and GetMinimumInteritemSpacingForSection. On Android, these will add a subclass of RecyclerView.ItemDecoration which will provide the spacing between items.

collectionview enhancement âž•

Most helpful comment

What's the status of this, still needs specification?

From a DX standpoint, I first tried to add a Margin to my Frame within the ItemTemplate, and it did nothing. I then went looking to any option to set Spacing on either the GridItemsLayout or CollectionView.

I then solved this by adding a ContentView and setting Padding to achieve the spacing. O @jassmith forgive me!

And finally I came here.

Screenshot 2019-03-30 12 56 56

All 16 comments

Where would the ItemSpacing be added? Currently I can not see a way of doing this?

Does this also affect the edge spacing? As i describe here https://github.com/xamarin/Xamarin.Forms/issues/3172#issuecomment-450669384 we need something in addition to the CollectionView margin to have the same spacing between the columns in a grid layout and the sides of the grid.

For example, having a thickness of 5 on all items would result in a spacing of 10 between the items and a spacing of 5 on the outside of the grid. In this case, something like an EdgeOffset of 5 would be required to keep the same spacing in- and outside of the grid.

@pauldipietro I've added ItemSpacing to the CollectionView spec.

@krdmllr My first instinct is to say "yes, this will also effect edge spacing"; i.e., it would work like your example above with a Thickness of 5 -> 5 around the edges, 10 in between items. But I'll need to dig into the actual implementation on each platform to be totally sure; if we can reasonably limit this to _inter-item_ spacing and leave the edges alone, then we might do that just so it's less mental effort for devs to figure out what effect margin/padding will have.

I suspect in either case we will need to address the issues you mentioned in your comment on #3172; I just don't know yet how we'd want to go about handling an EdgeOffset (or whatever we end up calling it).

So in #4996 I talked in adding also Padding so we can apply "insets" to the Viewport. Take note insets on CarouselView are also handle by the renderers so you can be able to select the 1st item if multiple items are on the screen and we need to push the 1st item to the center

@hartez In my opinion, ItemSpacing should be a separate property that translates directly to InterimSpacing/LineSpacing (vertical/horizontal) whereas section insets should map to Padding.

ItemSpacing should not do the job of Padding. If there is a calculation issue (e.g. 10 between items, 5 on the edges), then the dev should also set Padding to correct this.

OR make Margin work for items so that there is no need for ItemSpacing and as I argued before, let people use Padding on the CollectionView to even out the extra space.

What's the status of this, still needs specification?

From a DX standpoint, I first tried to add a Margin to my Frame within the ItemTemplate, and it did nothing. I then went looking to any option to set Spacing on either the GridItemsLayout or CollectionView.

I then solved this by adding a ContentView and setting Padding to achieve the spacing. O @jassmith forgive me!

And finally I came here.

Screenshot 2019-03-30 12 56 56

@davidortinau this still has the problem that the spacing between the items (10+10) is not the spacing the outer items have to the window (10). But i think your point is that your way the shadow of the frame still works?

edit: I would vote for an item spacing and padding property on the collection view since stack layout and grid both have a item spacing property aswell (RowSpacing/ColumnSpacing/Spacing)

Perhaps I'm overselling it by saying I "solved" anything other than getting space between my items. You're correct @krdmllr that this produces different spacing between than outside. Margin would have a similar outcome.

I whipped up a possible implementation of this, and I'm looking for feedback: https://github.com/xamarin/Xamarin.Forms/tree/cv-itemspacing

Rather than using Thickness, I've added bindable properties to the layout classes:

double ListItemsLayout.ItemSpacing
double GridItemsLayout.VerticalItemSpacing
double GridItemsLayout.HorizontalItemSpacing

On iOS, this maps to GetMinimumLineSpacingForSection and GetMinimumInteritemSpacingForSection. On Android, these add a subclass of RecyclerView.ItemDecoration called SpacingItemDecoration.

You can play around with them in the ControlGallery on that branch; just navigate to CollectionView Gallery -> ItemsSpacingGallery.

If folks don't immediately hate it or find glaring omissions, I'll update the spec and PR it.

closed by #6478

Is this available in a release yet? I was looking for the property on the CollectionView but was unable to find it? Perhaps it hasnt been rolled out yet?

Im using XF 4.1.0.496342-pre2 and it looked like this was in the 4.1.0 milestone.

It works in XF 4.2.0.618605-pre2.

<CollectionView.ItemsLayout>
    <ListItemsLayout Orientation="Vertical"
                     ItemSpacing="10" />
</CollectionView.ItemsLayout>

We have issue on HorizontalItemSpacing. Even when we set "0" some default spacing is there. No issue with VerticalItemSpacing though.
See the yellow lines between the columns of the Collection view:

Screen Shot 2019-08-20 at 5 34 46 PM

This is the code to reproduce:

<StackLayout Margin="10,50,10,5" Padding="0" Spacing="0" BackgroundColor="Yellow" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
        <CollectionView ItemsSource="{Binding GameCells}" Margin="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
            <CollectionView.ItemsLayout>
                <GridItemsLayout Orientation="Vertical" Span="9" HorizontalItemSpacing="0" VerticalItemSpacing="0"/>
            </CollectionView.ItemsLayout>
            <CollectionView.ItemTemplate>
                <DataTemplate>
                    <ContentView BackgroundColor="Green" Padding="1" Margin="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                        <ContentView BackgroundColor="White" Padding="10" Margin="0" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
                            <Label Text="{Binding DisplayText}" FontSize="Large" FontAttributes="Bold" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
                                   HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
                        </ContentView>
                    </ContentView>
                </DataTemplate>
            </CollectionView.ItemTemplate>    
        </CollectionView>
    </StackLayout>

We have issue on HorizontalItemSpacing. Even when we set "0" some default spacing is there. No issue with VerticalItemSpacing though.

@NirmalSubedi17 Please open a new issue at https://github.com/xamarin/Xamarin.Forms/issues/new/choose and we will take a look. Thanks!

Was this page helpful?
0 / 5 - 0 ratings