DisplayActionsSheet with Rg.Plugin.Popup Xamarin

Animated and beautiful ๐Ÿ˜ custom Display Action sheet

ยท

3 min read

DisplayActionsSheet with Rg.Plugin.Popup Xamarin

Design and UX experience are important when we build an application. It's very important to have a consistent design across all our components. When we use a cross-platform technology like Xamarin Forms, the current technology provides us with a native view that usually doesn't respect our design guidelines. In this post, we will show how we can make a custom DisplayAlert.

Prerequist

  • Rg.Plugin.Popup Nuget
  • Xamarin forms 5
  • (Optional) Xamarin.CommunityToolkit Nuget

Note : Check there for Configuration of Rg.Plugin.Popup

Implementation

Preparation of callback

First steps we must create a callback Task for our Popup for data return

 public class CallbackPopup : PopupPage 
    {
        private TaskCompletionSource<object> _taskCompletionSource;

        public Task<object> PagePopupTask
        {
            get => _taskCompletionSource.Task;
        }

        public CallbackPopup()
        {
            _taskCompletionSource = new TaskCompletionSource<object>();
        }

        public void SetPopupResult(object result) =>
            _taskCompletionSource.SetResult(result);
    }

Settings up your view and event

Next step is just create your Popup's UI ๐Ÿ˜

Note : Let your creativity speak at this level for your XAML

<?xml version="1.0" encoding="UTF-8" ?>
<customDisplay:CallbackPopup
    x:Class="YourApp.BaseDialog"
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
    xmlns:customDisplay="clr-namespace:YourApp.CustomDisplayMessage"
    xmlns:tk="http://xamarin.com/schemas/2020/toolkit">
    <customDisplay:CallbackPopup.Animation>
        <animations:MoveAnimation
            DurationIn="200"
            DurationOut="300"
            EasingIn="SinOut"
            EasingOut="SinIn"
            HasBackgroundAnimation="True"
            PositionIn="Bottom"
            PositionOut="Bottom" />
    </customDisplay:CallbackPopup.Animation>
    <Frame
        Margin="10,0"
        Padding="10"
        BackgroundColor="{AppThemeBinding Light=#FFF,
                                          Dark=#000,
                                          Default=#FFF}"
        CornerRadius="10"
        HorizontalOptions="Fill"
        VerticalOptions="Center">
        <Grid RowDefinitions="auto,auto,*">
            <Label
                x:Name="TitleLabel"
                TextColor="{AppThemeBinding Dark=#FFF,
                                            Light=#000,
                                            Default=#000}"
                VerticalOptions="Center" />
            <Label
                x:Name="DescriptionLabel"
                Grid.Row="1"
                FontSize="Body"
                Opacity = "0.6"
                TextColor="{AppThemeBinding Dark=#FFF,
                                            Light=#000,
                                            Default=#000}"
                VerticalOptions="Center" />
            <ScrollView Grid.Row="2">
                <CollectionView
                    x:Name="list"
                    ChildAdded="list_ChildAdded"
                    HeightRequest="1"
                    SelectionChanged="list_SelectionChanged"
                    SelectionMode="Single">
                    <CollectionView.ItemTemplate>
                        <DataTemplate>
                            <Grid>
                                <Frame
                                    tk:TouchEffect.AnimationDuration="200"
                                    tk:TouchEffect.NativeAnimation="True"
                                    tk:TouchEffect.NativeAnimationColor="#CCD0DC"
                                    tk:TouchEffect.PressedScale="0.85"

                                    CornerRadius="10"
                                    HasShadow="False">
                                    <Label  FontSize="Body"
                                                  Opacity = "0.6"
                                           TextColor="{AppThemeBinding Dark=#FFF,
                                            Light=#000,
                                            Default=#000}"  Text="{Binding .}" />
                                </Frame>
                                 <!--  Remove selectable style of xamarin  -->
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup Name="CommonStates">
                                        <VisualState Name="Selected">
                                            <VisualState.Setters>
                                                <Setter Property="BackgroundColor" Value="{AppThemeBinding Dark=#000, Light=#FFF, Default=#FFF}" />
                                            </VisualState.Setters>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                            </Grid>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </ScrollView>

        </Grid>
    </Frame>
</customDisplay:CallbackPopup>

C# functionnality

[XamlCompilation(XamlCompilationOptions.Compile)]
    public partial class BaseDialog : CallbackPopup
    {
        public BaseDialog(string title, string description, string[] options)
        {
            InitializeComponent();

            TitleLabel.Text = title;
            DescriptionLabel.Text = description;
            list.ItemsSource = options;
        }

        protected override void OnDisappearingAnimationEnd()
        {
            base.OnDisappearingAnimationEnd();
            SetPopupResult(list.SelectedItem);
        }
        // Control of size of component
        private void list_ChildAdded(object sender, ElementEventArgs e)
        {
            var cell = (e.Element as View);
            cell.SizeChanged += Cell_SizeChanged;
        }

        //  Control heigh of you compoment
        private void Cell_SizeChanged(object sender, EventArgs e)
        {
            if (list.HeightRequest < 300)
            {
                var cell = (sender as View);
                list.HeightRequest += cell.Height;
            }
        }

        private async void list_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            await Rg.Plugins.Popup.Services.PopupNavigation.Instance.PopAsync();
        }
}

Setting up for calling

Final step is just for Calling (static)

public class CustomDisplayAlert
    {
        public static async Task<object> ShowDialogAsync(string title, string description = "", params string[] options)
        {
            var popup = new BaseDialog(title,description,options);
            await Rg.Plugins.Popup.Services.PopupNavigation.Instance.PushAsync(popup);

            return await popup.PagePopupTask;
        }
}

Usage

// ...

            var result = await CustomDisplayAlert.ShowDialogAsync("Options", "Choose one option", "Delete", "Update"); 
//....

Test

ezgif-4-9a03507603.gif

Happy coding ๐Ÿ‘Œ

Ressources

Sample

https://github.com/keevBush/SampleDisplayActionSheet

ย