Create overlaying loader on a mobile app using xamarin forms - xaml

I am using Xamarin forms and am trying to create an overlaying loader for my screens. From my findings, I need to use an absolute layout, which I have done. I have accomplished for the loader to work on some screens however when the screen is a little more complex (using nested scrollviews, grids, etc.) it doesn't seem to work. Below is a sample of the code that DOES work:
<AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout Padding="10" Orientation="Vertical" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<StackLayout Padding="0,85,0,0">
<Image Source="myimage.png" HorizontalOptions="Center" VerticalOptions="Start" />
</StackLayout>
<StackLayout Orientation="Vertical" Padding="10, 5, 10, 5" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Label Text="This works perfect"></Label>
</StackLayout>
</StackLayout>
<!-- Loader -->
<ContentView BackgroundColor="#222222"
Opacity="0.3"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1"
IsVisible="{Binding IsIndicatorActive}">
<ActivityIndicator AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1"
VerticalOptions="{StaticResource LoaderPosition}"
HorizontalOptions="{StaticResource LoaderPosition}"
IsEnabled="{Binding IsIndicatorActive}"
IsRunning="{Binding IsIndicatorActive}"
IsVisible="{Binding IsIndicatorActive}" />
</ContentView>
</AbsoluteLayout>
The following code is what DOESN'T work:
<AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout Orientation="Vertical" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<ScrollView>
<StackLayout Padding="0,85,0,0">
<Image Source="myimage.png" HorizontalOptions="Center" VerticalOptions="Start" />
</StackLayout>
<StackLayout Orientation="Vertical" Padding="10, 5, 10, 5" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<Label Text="This doesn't work"></Label>
</StackLayout>
</ScrollView>
<Grid HorizontalOptions="FillAndExpand" VerticalOptions="EndAndExpand" ColumnSpacing="0" RowSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" HorizontalOptions="FillAndExpand" Text="Button1" Command="{Binding Button2Command}" />
<Button Grid.Row="0" Grid.Column="1" HorizontalOptions="FillAndExpand" Text="Button2" Command="{Binding Button2Command}" />
</Grid>
</StackLayout>
<!-- Loader -->
<ContentView BackgroundColor="#222222"
Opacity="0.3"
AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1"
IsVisible="{Binding IsIndicatorActive}">
<ActivityIndicator AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1"
VerticalOptions="{StaticResource LoaderPosition}"
HorizontalOptions="{StaticResource LoaderPosition}"
IsEnabled="{Binding IsIndicatorActive}"
IsRunning="{Binding IsIndicatorActive}"
IsVisible="{Binding IsIndicatorActive}" />
</ContentView>
</AbsoluteLayout>
From my understanding it has something to do with the fact that scrollviews and gridviews are Managed Layouts and absolute layouts are Unmanaged Layouts so I figured if i put a stacklayout occupying the full absolute layout and afterwards the scrollview and gridview instide the stacklayout it would be relative to its parent (the way html handles this). Clearly this isn't handled in such manner (instead i just get a blank screen), which is leaving me stumped as to how I would go about this issue.
Any ideas how I can get around this issue and have my loader display without affecting my screen display? Thanks!

Maybe this will be easier:
https://components.xamarin.com/view/andhud
https://components.xamarin.com/view/btprogresshud
To implement those you only need to use the Dependency Service:
iOS implementation:
http://pastie.org/10821570
Android Implementation:
http://pastie.org/10821571
Interface implementation:
using System;
namespace YourNameSpace
{
public interface IHudService
{
void ShowHud(string ProgressText = "Loading...");
void HideHud();
void SetText(string Text);
void SetProgress(double Progress, string ProgressText = "");
}
}
And to use it simply use:
DependencyService.Get<IHudService>().ShowHud();
//Your Task...
DependencyService.Get<IHudService>().HideHud();

Related

How can an image within a grid in xamarin.forms be centered

I'm developing a Xamarin. Form mobile apps and trying to center and image above 2 buttons, how can I center and image in a grid XAML tag, see XAML code below in which I'm using, and having difficulty place it in the center of the mobile app screen.
<?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="DemoApp.Views.MainPage"
NavigationPage.HasNavigationBar="False">
<ContentPage.Content>
<Grid HorizontalOptions="CenterAndExpand" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<StackLayout Padding="10" HorizontalOptions="Center" VerticalOptions="Center" >
<Image Grid.Row="0" Grid.Column="0" Source="RegisterUser" WidthRequest="100" HeightRequest="81" HorizontalOptions="Center" VerticalOptions="Center" />
</StackLayout>
<Button Text="Sign-In" VerticalOptions="CenterAndExpand" HorizontalOptions="Center" TextColor="White"
Grid.Row="2" Grid.Column="0"
BorderRadius="4" BorderWidth="1"
BackgroundColor="LightGray" />
<Button Text="Register" TextColor="White"
VerticalOptions="CenterAndExpand"
HorizontalOptions="Center"
Grid.Row="2" Grid.Column="1"
BorderRadius="4" BorderWidth="1"
BackgroundColor="LightGray" />
</Grid>
</ContentPage.Content>
</ContentPage>
your grid has 2 cols, so your StackLayout needs to span them in order to be centered across the entire grid
<StackLayout Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Padding="10" HorizontalOptions="Center" VerticalOptions="Center" >
<Image Source="RegisterUser" WidthRequest="100" HeightRequest="81" HorizontalOptions="Center" VerticalOptions="Center" />
</StackLayout>

Placing a stacklayout in the center of the screen

I tried to insert the horizontaloptions="CenterAndExpand" code into all of the stacklayout path but didn't work.
It's still in the upper-left corner :(
Somebody any idea? I actually don't use the grid, I just left it there.
My Code:
<ContentPage.Content>
<AbsoluteLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Image AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1" Source="BackgroundPicture.jpg" Aspect="AspectFill"/>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackLayout>
<StackLayout Orientation="Horizontal">
<local:RoundedEntry x:Name="RegFirstNameEntry" Placeholder="Firstname" WidthRequest="177"></local:RoundedEntry>
<local:RoundedEntry x:Name="RegLastNameEntry" Placeholder="Lastname" WidthRequest="177"></local:RoundedEntry>
</StackLayout>
<StackLayout Orientation="Horizontal">
<local:RoundedEntry x:Name="RegPhoneNumberEntry" Placeholder="Phone" WidthRequest="177" Keyboard="Telephone"></local:RoundedEntry>
<local:RoundedEntry x:Name="RegEmailEntry" Placeholder="Email" WidthRequest="177"></local:RoundedEntry>
</StackLayout>
<StackLayout Orientation="Vertical">
<local:RoundedEntry x:Name="RegPasswordEntry" Placeholder="Password" IsPassword="True" ></local:RoundedEntry>
<local:RoundedEntry x:Name="RegPasswordAgainEntry" Placeholder="Password" IsPassword="True"></local:RoundedEntry>
</StackLayout>
</StackLayout>
</Grid>
</AbsoluteLayout>
</ContentPage.Content>
</ContentPage>
It's because your StackLayout defaults are FillAndExpand.
To center it inside Grid set StackLayout's HorizontalOptions="Center" VerticalOptions="Center".

Overlay label, list and a button on top of an image on Xamarin.Forms

I want to make a page where there is a picture and basically the everything else on the page on top of the image.
Something similar to this
XAML Code like :
<?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="Project.Page">
<ScrollView>
<AbsoluteLayout>
<Image Source="{Binding ContentImage}}" Aspect="AspectFill" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1"/>
<Label Text="{Binding label}" FontSize="15" AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0,1,-1,-1" />
</AbsoluteLayout>
</ScrollView>
I have this so far. But this only has the label way at the bottom right, and I can't seem to get the list or buttons to work properly. I was thinking maybe just have the image be the background, but the image is supposed to change by the push of a button or something and I am not entirely sure if you can do that with a background image.
Is something like this possible with Xamarin.Forms?
Sorry if my English is poor! It's my second language!
Thanks in advance!
EDIT: I was able to use the image as background and change by a button click. Now I just need to find out how to actually position a ListView.
I moved some items around from a demo, this is just one way to handle it using an AbsoluteLayout and Grid
<AbsoluteLayout x:Name="ViewLayout">
<Image Source="coffee.png" Aspect="AspectFill" AbsoluteLayout.LayoutBounds="1,1,1,1" AbsoluteLayout.LayoutFlags="All" />
<AbsoluteLayout x:Name="ViewControls" AbsoluteLayout.LayoutBounds="1,1,1,.50" AbsoluteLayout.LayoutFlags="All" BackgroundColor="#66000000" Margin="10,10,10,10">
<StackLayout Orientation="Vertical" Margin="20,20,20,20" BackgroundColor="Transparent" AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="1,1,1,1">
<Grid Margin="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Text="Salted Caramel Mocha Frappuccino" TextColor="White" HorizontalOptions="CenterAndExpand" VerticalTextAlignment="Center" Grid.Column="0" Grid.ColumnSpan="3" Grid.RowSpan="2" />
<Button Text="Extra Shot" BackgroundColor="#77000000" BorderRadius="4" BorderColor="White" BorderWidth="2" TextColor="White" Grid.Row="0" Grid.Column="3" />
<Button Text="Whipped Cream" BackgroundColor="#77000000" BorderRadius="4" BorderColor="White" BorderWidth="2" TextColor="White" Grid.Row="1" Grid.Column="3" />
</Grid>
<Grid Margin="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Button Text="Tall (12oz)" BackgroundColor="#77000000" BorderRadius="4" BorderColor="White" BorderWidth="2" TextColor="White" HorizontalOptions="FillAndExpand" Grid.Column="0" />
<Button Text="Grande (16oz)" BackgroundColor="#77000000" BorderRadius="4" BorderColor="White" BorderWidth="2" TextColor="White" HorizontalOptions="FillAndExpand" Grid.Column="1" />
<Button Text="Venti (20oz)" BackgroundColor="#77000000" BorderRadius="4" BorderColor="White" BorderWidth="2" TextColor="White" HorizontalOptions="FillAndExpand" Grid.Column="2" />
</Grid>
</StackLayout>
</AbsoluteLayout>
</AbsoluteLayout>

keyboard popup its hide last row of grid

I have using AppCompact Themes in xamarin forms android when keyboard popup its hide last row of grid
Before Keyboard Popup see Image
Below is my code. I've created the grid having title, description. I want to show the camera icon and its bar above the keyboard when it comes and go back to the bottom of the screen when the keyboard hides.
<Grid RowSpacing="0" VerticalOptions="FillAndExpand">
<Grid.RowDefinitions>
<RowDefinition Height="80" />
<RowDefinition Height="*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<StackLayout
Grid.Row="0"
Padding="10,8"
BackgroundColor="White"
HorizontalOptions="FillAndExpand"
Orientation="Horizontal">
<Entry
x:Name="GeneralPostTitle"
Margin="10,10,10,0"
FontSize="20"
HorizontalOptions="FillAndExpand"
Placeholder="Title"
PlaceholderColor="Gray"
TextColor="Black"
VerticalOptions="End" />
</StackLayout>
<StackLayout
Grid.Row="1"
Padding="10,0"
BackgroundColor="White"
HorizontalOptions="FillAndExpand"
Spacing="0"
VerticalOptions="FillAndExpand">
<StackLayout Padding="0" VerticalOptions="Fill">
<customRenderer:PlaceholderEditor
x:Name="EditorDescription"
Margin="10,10,10,0"
FontSize="22"
HeightRequest="130"
HorizontalOptions="Fill"
Placeholder="Add Description"
PlaceholderTextColor="Gray"
TextColor="Gray" />
</StackLayout>
<ScrollView Padding="10" Orientation="Horizontal">
<StackLayout
x:Name="Images"
HorizontalOptions="FillAndExpand"
Orientation="Horizontal"
Spacing="5" />
</ScrollView>
</StackLayout>
<StackLayout
Grid.Row="2"
Padding="20,0"
BackgroundColor="#FAFAFA">
<Image
Aspect="AspectFit"
HeightRequest="40"
HorizontalOptions="StartAndExpand"
WidthRequest="30">
<Image.Source>
<OnPlatform
x:TypeArguments="ImageSource"
Android="camera"
WinPhone="Icons/camera.png"
iOS="Icons/camera.png" />
</Image.Source>
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="ImagePost_OnTapped" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
</Grid>
After Keyboard Popup see Image
You need to set SoftInput to AdjustResize in order for Android to resize the views so they stay visible. In Forms, you can do this with the platform specifics feature in Forms 2.3.3.
Check out this Gist on how to do this in OnCreate(). Note the workaround that's needed to remove an underlay added to the status bar in API 21+.

Xamarin - slide element within Frame outside of view

Not really sure how to properly describe my problem using correct wording as I'm new to Xamarin and Xaml.
I have a Frame with several StackLayouts within and I want to slide a specific StackLayout outside the Frame without showing it outside the Frame.
I can currently do this with:
XAML:
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:controls="clr-namespace:XLabs.Forms.Controls;assembly=XLabs.Forms"
xmlns:mr="clr-namespace:MR.Gestures;assembly=MR.Gestures"
x:Class="iRemote.UI.Maps.LocationFinderMap"
xmlns:map="clr-namespace:iRemote.Location"
Title="Location Finder">
<Frame HasShadow="true" OutlineColor="Color.Black" WidthRequest="700" HeightRequest="300" Padding="3"
BackgroundColor="White">
<mr:StackLayout x:Name="sl_main" Padding="2" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand"
Orientation="Horizontal" WidthRequest="200">
<StackLayout HorizontalOptions="Start" Orientation="Vertical">
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Label Text="Parcel #" />
<Entry x:Name="txtParcel" WidthRequest="100" />
<Label HorizontalOptions="FillAndExpand" />
<Button x:Name="btnClose" BackgroundColor="#0786a3" BorderRadius="30" TextColor="White"
Text="Close" HorizontalOptions="End" />
</StackLayout>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<Label Text="Meter #" />
<Entry x:Name="txtMeter" WidthRequest="100" />
</StackLayout>
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
<SearchBar x:Name="search" Placeholder="Search" />
</StackLayout>
<StackLayout Padding="2" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<StackLayout HorizontalOptions="FillAndExpand">
<mr:Image x:Name="img_map" Source="down" HeightRequest="19" WidthRequest="32" />
</StackLayout>
</StackLayout>
</StackLayout>
<StackLayout x:Name="sl_map" Padding="2" HorizontalOptions="FillAndExpand" HeightRequest="5"
VerticalOptions="FillAndExpand" IsVisible="true" WidthRequest="300">
<map:ExtendedMap
BackgroundColor="Blue"
x:Name="MP"
IsShowingUser="true"
MapType="Street" />
</StackLayout>
</mr:StackLayout>
</Frame>
</ContentPage>
Code-Behind:
if (panelShowing)
{
var rect = new Rectangle(this.Width - sl_map.Width, sl_map.Y, sl_map.Width, sl_map.Height);
sl_map.LayoutTo(rect, 250, Easing.CubicIn);
}
else
{
var rect = new Rectangle(this.Width + sl_map.Width - 40, sl_map.Y, sl_map.Width, sl_map.Height);
sl_map.LayoutTo(rect, 200, Easing.CubicOut);
}
However, sl_map simply just shows outside the frame. I want it to not be visible as it crosses the border of the frame. I hope that's clear enough. Again, sorry if I'm not using the correct terminology. I'm a WinForms guy.