Let's create a class in Forms project.
using System.Threading.Tasks;
using Xamarin.Forms;
namespace MyProject
{
public class PopupLayout : RelativeLayout
{
private View _content;
private View _popup;
private RelativeLayout _backdrop;
protected override void OnChildAdded(Element child)
{
base.OnChildAdded(child);
}
public View Content
{
get { return _content; }
set {
if (_content != null)
Children.Remove(_content);
_content = value;
Children.Add(_content, () => Bounds);
}
}
public bool IsPopupActive
{
get { return _popup != null; }
}
public async Task<bool> ShowPopup(View popupView, string title = null)
{
await DismissPopup();
_popup = popupView;
_popup.VerticalOptions = LayoutOptions.CenterAndExpand;
if (_content != null)
_content.InputTransparent = true;
var backdrop = new RelativeLayout
{
BackgroundColor = Color.FromRgba(0, 0, 0, 0.4),
Opacity = 0,
GestureRecognizers = { new TapGestureRecognizer() },
Padding = new Thickness(20),
VerticalOptions = LayoutOptions.CenterAndExpand
};
var clickArea = new RelativeLayout
{
BackgroundColor = Color.Transparent,
Opacity = 0
};
var tap = new TapGestureRecognizer();
tap.Tapped += Tap_Tapped;
clickArea.GestureRecognizers.Add(tap);
var w = Constraint.RelativeToParent(p => p.Width - 40);
var h = Constraint.RelativeToParent(p => p.Height - 40);
var zero = Constraint.Constant(20);
var sl = new StackLayout
{
Orientation = StackOrientation.Vertical,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand,
Spacing = 0
};
var csl =new StackLayout
{
Orientation = StackOrientation.Vertical,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand,
Spacing = 0
};
if (!string.IsNullOrEmpty(title))
{
//This is a FontAwesome Label. We made it. You can use anything you want instead of this.
var closeLabel = new FALabel
{
Text = FAIcon.Times, //this it fontawesome icon Unicode
HorizontalOptions = LayoutOptions.EndAndExpand,
VerticalOptions = LayoutOptions.StartAndExpand,
TextColor = Color.White,
VerticalTextAlignment = TextAlignment.Center,
FontSize = 22
};
closeLabel.GestureRecognizers.Add(tap);
var slTitle = new StackLayout
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.Center,
Orientation = StackOrientation.Horizontal,
Children =
{
new Label
{
HorizontalOptions = LayoutOptions.StartAndExpand,
VerticalOptions = LayoutOptions.Center,
Text = title,
TextColor = Color.White
},
closeLabel
},
Padding = new Thickness(8, 5, 8, 5),
BackgroundColor = Color.FromHex("#D10000")
};
csl.Children.Add(slTitle);
}
csl.Children.Add(_popup);
sl.Children.Add (csl);
backdrop.Children.Add(clickArea, Constraint.Constant(0), Constraint.Constant(0), Constraint.RelativeToParent(p => p.Width),
Constraint.RelativeToParent(p => p.Height));
backdrop.Children.Add(sl,
zero,
zero,
w,
h);
_backdrop = backdrop;
Children.Add(backdrop,
Constraint.Constant(0),
Constraint.Constant(0),
Constraint.RelativeToParent(p => p.Width),
Constraint.RelativeToParent(p => p.Height)
);
UpdateChildrenLayout(); return await _backdrop.FadeTo(1); } private async void Tap_Tapped(object sender, System.EventArgs e) { await DismissPopup(); } public async Task DismissPopup() { if (_popup != null) { await Task.WhenAll(_popup.FadeTo(0), _backdrop.FadeTo(0)); _backdrop.Children.Remove(_popup); Children.Remove(_backdrop); _popup = null; } if (_content != null) { _content.InputTransparent = false; } } } }
How to use it in xaml page;
<?xml version="1.0" encoding="UTF-8"?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MyProject.SamplePopup" xmlns:l="clr-namespace:MyProject;assembly=MyProject"> <ContentPage.Content> <l:PopupLayout x:Name="plDefault" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"> <StackLayout x:Name="slMain" Orientation="Vertical" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand"> . . . . </StackLayout> </l:PopupLayout> </ContentPage.Content> </ContentPage>
You should set your PopupLayout from .cs too;
Appearing class;
plDefault.Children.Remove(slMain);
plDefault.Children.Add(slMain, Constraint.Constant(0), Constraint.Constant(0), Constraint.RelativeToParent(p => p.Width), Constraint.RelativeToParent(p => p.Height));
override OnSizeAllocated class for issues;
protected override void OnSizeAllocated(double width, double height) { base.OnSizeAllocated(width, height); //must be called slMain.WidthRequest = width; slMain.HeightRequest = height; }
How to open/close it;
var popupMainStack = new StackLayout
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Color.White
};
//You can add anything you want to main stack as children.
await Popup.ShowPopup(popupMainStack,"Popup Title");
await Popup.DismissPopup(); //Close popup
Simple ;)
(Burada bir karikatür vardı ama telif yerim diye kaldırdım. Herkese dava açıyorlarmış karikatür paylaşılıyor diye. Karikatürün doğasına hiç uymuyor bence bu tavır :-/ Çakallar çok yanlış tanıtılıyor.)