Xam.Plugin.SimpleBottomDrawer icon indicating copy to clipboard operation
Xam.Plugin.SimpleBottomDrawer copied to clipboard

Grid use

Open jjgarrett0 opened this issue 3 years ago • 5 comments

Can this be used in a grid or does it only work in a RelativeLayout?

jjgarrett0 avatar Aug 09 '21 14:08 jjgarrett0

@jjgarrett0 as long as BottomDrawer inherits Frame it should be possible to use it within a Grid. So far I have an issue of "showing the drawer on top instead of bottom". Still, I guess, a right combination of VerticalOptions="End" should do the job.

P.S. @jjgarrett0 so have you managed to make BottomDrawer work with the Grid? Or did you end up going with RelativeLayout? What has blocked the grid-based approach for you?

P.P.S. I have no relations to the team or author of BottomDrawer. Just another user with a similar issue.

alexd-zyngr avatar Feb 23 '22 12:02 alexd-zyngr

@jjgarrett0 experimenting with LockStates order might also help achieving correct looks. Since BottomDrawer.Open() and BottomDrawer.Close() use LockStates.Last() and LockStates.First() respectively.

https://github.com/galadril/Xam.Plugin.SimpleBottomDrawer/blob/81eef2e1d0c5f3709f1f964f7cb58f0b785a9f39/Xam.Plugin.SimpleBottomDrawer/BottomDrawer.cs#L293

P.S. Not sure whether the control can handle non-monotonic (unsorted) array of such states properly.

[UPD] did not quite work with the Grid for me. The drawer is still shown on top of the screen but slides down to bottom.

alexd-zyngr avatar Feb 23 '22 12:02 alexd-zyngr

My xaml just in case:

<ContentPage.Content>
        <Grid BackgroundColor="Gray"
              HorizontalOptions="Fill"
              VerticalOptions="Fill"
              RowSpacing="0"
              ColumnSpacing="0"
              Padding="0"
              Margin="0">

            <Grid.RowDefinitions>
                <RowDefinition Height="48" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>

<!-- 
      primary contents of the screen 
      to be here
-->


<slidingdrawer:BottomDrawer Grid.Row="0" Grid.RowSpan="2"
                x:Name="BottomDrawerView"
                LockStates="{
                    Binding   Path=LockStatesForSlidingBottomDrawer 
                            , Source={x:Reference MapTabRootViewPage}
                }"
                IsExpanded="{
                    Binding IsStationInfoPopoverVisible
                            , Mode=TwoWay
                }"
                IsVisible="{
                    Binding IsStationInfoPopoverVisible
                            , Mode=OneWay
                }"
                ExpandedPercentage="{
                    Binding ExpandedPercentage
                          , Mode=TwoWay
                }"
                HorizontalOptions="Fill"
                VerticalOptions="End"
                CornerRadius="16"
                Padding="0"
                Margin="0" >

                <StackLayout Orientation="Vertical"
                    x:Name="BottomDrawerStack"
                    Spacing="0"
                    Padding="0"
                    Margin="0">


                    <!-- Slider top indicator for dragging -->
                    <BoxView BackgroundColor="#C7C7CC"
                             WidthRequest="32"
                             HeightRequest="3"
                             HorizontalOptions="Center"
                             Margin="15,22" />


                    <station:StationInfoBriefFragment 
                        BindingContext="{Binding StationBriefPopoverContext}"
                        HorizontalOptions="Fill"
                        Margin="0"/>
                </StackLayout>
            </slidingdrawer:BottomDrawer>
</Grid>
</ContentPage.Content>

alexd-zyngr avatar Feb 23 '22 14:02 alexd-zyngr

@jjgarrett0 so I've figured out that proper bottom positioning is achieved by that magical -65 constraint

https://github.com/galadril/Xam.Plugin.SimpleBottomDrawer/blob/81eef2e1d0c5f3709f1f964f7cb58f0b785a9f39/Samples/Xam.Plugin.SimpleBottomDrawer.Samples/Xam.Plugin.SimpleBottomDrawer.Samples/MainPage.xaml#L64

 RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent,
                                                                  Property=Height,
                                                                  Factor=1,
                                                                  Constant=-65}">

Which means DrawerView.Margin.Top == ContainerView.Height - 65


The same positioning can be achieved within a Grid by applying a large top margin.

<slidingdrawer:BottomDrawer Grid.Row="0" Grid.RowSpan="2"
            x:Name="BottomDrawerView"
            LockStates="{
                Binding   Path=LockStatesForSlidingBottomDrawer 
                        , Source={x:Reference MapTabRootViewPage}
            }"
            IsExpanded="{
                Binding IsStationInfoPopoverVisible
                        , Mode=TwoWay
            }"
            IsVisible="true"
            ExpandedPercentage="{
                Binding ExpandedPercentage
                        , Mode=TwoWay
            }"
            CornerRadius="16"
            
            HorizontalOptions="Fill"
>>>          VerticalOptions="Start"
            Padding="0"
>>>            Margin="{
                Binding Path=BottomDrawerVerticalOffset
                      , Source={x:Reference MapTabRootViewPage}
            }">

Still, that "large offset" has to be calculated manually (or I just don't know how to do it properly for the Grid)

public Thickness BottomDrawerVerticalOffset
        {
            get
            {

                double screenHeightPx = DeviceDisplay.MainDisplayInfo.Height;
                double screenHeightPt = screenHeightPx / DeviceDisplay.MainDisplayInfo.Density;

                double offsetFromSample = 65;
                double heightOfBottomBar = 50;
                double result =
                      screenHeightPt
                    - heightOfBottomBar
                    - offsetFromSample;

                var wrappedResult = new Thickness(
                      left  : 0
                    , top   : result
                    , right : 0
                    , bottom: 0
                );

                return wrappedResult;
            }
        }

So RelativeLayout and Constraint based approach seems easier and more reliable in my opinion.

alexd-zyngr avatar Feb 23 '22 16:02 alexd-zyngr

[UPD] seems like BottomDrawer.TranslateTo() does not work nicely with "large .Margin" approach. The drawer is rendered in the bottom but is not updated by drag gesture (despite all position calculations are done properly)

alexd-zyngr avatar Feb 23 '22 17:02 alexd-zyngr