You can create a custom popup to accomplish this in Xamarin.Forms
Here is the custom ContentView that I created. It uses BoxView to create a background fade effect and uses Frame to add shadow to the popup.
I also use animations to make a custom popup as if it were bouncing off the screen!
Application example
The code for this sample application is available on Github:
https://github.com/brminnick/InvestmentDataSampleApp

Code snippet
public class WelcomeView : ContentView { readonly BoxView _backgroundOverlayBoxView; readonly Frame _overlayFrame; readonly StackLayout _textAndButtonStack; readonly RelativeLayout _relativeLayout; public WelcomeView() { const string titleText = "Welcome"; const string bodyText = "Enjoy InvestmentDataSampleApp"; const string okButtonText = "Ok, thanks!"; var whiteWith75Opacity = new Color(255, 255, 255, 0.75); _backgroundOverlayBoxView = new BoxView { BackgroundColor = whiteWith75Opacity }; _backgroundOverlayBoxView.Opacity = 0; _overlayFrame = new Frame { HasShadow = true, BackgroundColor = Color.White }; _overlayFrame.Scale = 0; var titleLabel = new Label { FontAttributes = FontAttributes.Bold, Text = titleText, HorizontalTextAlignment = TextAlignment.Center }; var bodyLabel = new Label { Text = bodyText, HorizontalTextAlignment = TextAlignment.Center }; var blackWith75PercentOpacity = new Color(0, 0, 0, 0.75); var okButton = new Button { BackgroundColor = blackWith75PercentOpacity, TextColor = Color.White, BorderWidth = 1, BorderColor = blackWith75PercentOpacity, FontAttributes = FontAttributes.Bold, Margin = new Thickness(5), Text = okButtonText }; okButton.Clicked += (sender, e) => { Device.BeginInvokeOnMainThread(async () => { await this.FadeTo(0); this.IsVisible = false; this.InputTransparent = true; }); } _textAndButtonStack = new StackLayout { HorizontalOptions = LayoutOptions.CenterAndExpand, Spacing = 20, Children = { titleLabel, bodyLabel, okButton } }; _textAndButtonStack.Scale = 0; _relativeLayout = new RelativeLayout(); Func<RelativeLayout, double> gettextAndButtonStackHeight = (p) => _textAndButtonStack.Measure(_relativeLayout.Width, _relativeLayout.Height).Request.Height; Func<RelativeLayout, double> gettextAndButtonStackWidth = (p) => _textAndButtonStack.Measure(_relativeLayout.Width, _relativeLayout.Height).Request.Width; _relativeLayout.Children.Add(_backgroundOverlayBoxView, Constraint.Constant(-10), Constraint.Constant(0), Constraint.RelativeToParent(parent => parent.Width + 20), Constraint.RelativeToParent(parent => parent.Height) ); _relativeLayout.Children.Add(_overlayFrame, Constraint.RelativeToParent(parent => parent.Width / 2 - gettextAndButtonStackWidth(parent) / 2 - 20), Constraint.RelativeToParent(parent => parent.Height / 2 - gettextAndButtonStackHeight(parent) / 2 - 10), Constraint.RelativeToParent(parent => gettextAndButtonStackWidth(parent) + 30), Constraint.RelativeToParent(parent => gettextAndButtonStackHeight(parent) + 30) ); _relativeLayout.Children.Add(_textAndButtonStack, Constraint.RelativeToView(_overlayFrame, (parent, view) => view.X + 15), Constraint.RelativeToView(_overlayFrame, (parent, view) => view.Y + 15) ); if (Device.OS == TargetPlatform.Android) { _overlayFrame.IsVisible = false; _textAndButtonStack.BackgroundColor = whiteWith90Opacity; } Content = _relativeLayout; } public void DisplayView() { Device.BeginInvokeOnMainThread(async () => { var animationList = new List<Task> { _backgroundOverlayBoxView.FadeTo(1,AnimationConstants.WelcomeViewAnimationTime), _textAndButtonStack.ScaleTo(AnimationConstants.WelcomeViewMaxSize, AnimationConstants.WelcomeViewAnimationTime), _overlayFrame.ScaleTo(AnimationConstants.WelcomeViewMaxSize,AnimationConstants.WelcomeViewAnimationTime) }; await Task.WhenAll(animationList); animationList = new List<Task> { _textAndButtonStack.ScaleTo(AnimationConstants.WelcomeViewNormalSize, AnimationConstants.WelcomeViewAnimationTime), _overlayFrame.ScaleTo(AnimationConstants.WelcomeViewNormalSize, AnimationConstants.WelcomeViewAnimationTime) }; await Task.WhenAll(animationList); }); } }