xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

[Enhancement] CollectionView item spacing #4681

Closed pauldipietro closed 5 years ago

pauldipietro commented 5 years ago

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:

GridItemsLayout:

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.

rasmuschristensen commented 5 years ago

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

krdmllr commented 5 years ago

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.

hartez commented 5 years ago

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

hartez commented 5 years ago

@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).

rmarinho commented 5 years ago

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

adrianknight89 commented 5 years ago

@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.

davidortinau commented 5 years ago

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
krdmllr commented 5 years ago

@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)

davidortinau commented 5 years ago

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.

hartez commented 5 years ago

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.

hartez commented 5 years ago

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

samhouts commented 5 years ago

closed by #6478

LeoJHarris commented 5 years ago

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.

kramer-e commented 5 years ago

It works in XF 4.2.0.618605-pre2.

<CollectionView.ItemsLayout>
    <ListItemsLayout Orientation="Vertical"
                     ItemSpacing="10" />
</CollectionView.ItemsLayout>
NirmalSubedi17 commented 5 years ago

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>
hartez commented 5 years ago

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!