I'm wondering how we can achieve in Xamarin Forms a title transition in nav bar when user scrolling. For example, the Message app on iOS :
When user scroll :
Title "Messages" transition from page content to navigation bar. Is there a way to accomplish this in the same way on Android and iOS with Xamarin Forms ?
We could define a custom TitleView and set the TextColor of title when scrolling the page .
in Xaml
<NavigationPage.TitleView>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.2*" />
<ColumnDefinition Width="0.6*" />
<ColumnDefinition Width="0.2*" />
</Grid.ColumnDefinitions>
<Label x:Name="TitleLabel" Text="Message" FontSize="22" TextColor="Transparent" Grid.Column="1" HorizontalTextAlignment="Center" VerticalTextAlignment="Center" />
//... you can put any other elements on other two Columns like button and image icon
</Grid>
</NavigationPage.TitleView>
For content I defined a simple ScrollView for show the effect
<ScrollView Scrolled="ScrollView_Scrolled" Orientation="Vertical">
<StackLayout>
<Label Text="Message" FontSize="35" HorizontalTextAlignment="Start" HeightRequest="60" />
<BoxView BackgroundColor="LightBlue" HeightRequest="300" />
<BoxView BackgroundColor="LightGreen" HeightRequest="300" />
<BoxView BackgroundColor="LightPink" HeightRequest="300" />
</StackLayout>
</ScrollView>
In code behind
Note :
60 here is the height of label in content Page . The alpha of title Label will set to 1 when the message label scrolls out of the screen. I didn't used data binding just for demo . Of course you could binding the TextColor to ViewModel .
private void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
{
var scrollView = sender as ScrollView;
var TransY = e.ScrollY;
if(TransY>0)
{
double alpha = TransY / 60;
TitleLabel.TextColor = Color.FromRgba(0.0,0.0,0.0,alpha);
}
}
Related
I am using Rg.Plugins.Popup plugin in my xamarin forms app. It is a nice plugin for modal dialogs. However, I am looking to dismiss the dialog when user scrolls down. (Most dialogs in iOS has this behavior of closing with scrolling down).
XAML inside Popup page.
Option 1
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
HasSystemPadding="True"
CloseWhenBackgroundIsClicked="False"
x:Name="MyPage"
x:Class="wQuran.Views.Today.PrayerTimesSettingsPopupPage">
<Frame Style="{DynamicResource PopupFrame}" VerticalOptions="FillAndExpand" IsClippedToBounds="True">
<Grid RowDefinitions="Auto,*" Style="{DynamicResource BaseGrid}">
<BoxView Grid.Row="0" Style="{DynamicResource PopupTitleBoxView}"/>
<Grid Grid.Row="0" ColumnDefinitions="*,30" HeightRequest="40" Padding="10">
<Label Grid.Column="0" Text="{Binding Title}" Style="{DynamicResource PopupTitleLabel}"/>
<ImageButton Grid.Column="1" Style="{DynamicResource DialogCloseImageButton}" Command="{Binding CloseDialogCommand}"/>
</Grid>
</Grid>
</Frame>
</pages:PopupPage>
Option 2.
Updated XAML and added the Frame inside ScrollView
<ScrollView Scrolled="ScrollView_Scrolled">
....
</ScrollView>
private void ScrollView_Scrolled(object sender, Xamarin.Forms.ScrolledEventArgs e)
{
if (e.ScrollY > 100)
{
itemViewModel.CloseDialogCommand.Execute(null);
}
}
In option 1 I don't have the scroll, so the plug in works with default behavior, but I have no way to close the dialog in scroll.
In option 2, I added the frame inside the scrollview to check for Y scroll and dismiss the dialog. The Scrolled event never fires. Additionally, I cannot close the dialog when clicking outside the modal.
After all, my question is how to dismiss the dialog while scrolling down?
After all, my question is how to dismiss the dialog while scrolling down?
I guess that you want to close PopupPage when ScrollView scroll ending. If yes, please take a look the following code:
<pages:PopupPage
x:Class="FormsSample.simplecontrol.Page16"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup">
<StackLayout
Padding="20,0"
HorizontalOptions="FillAndExpand"
VerticalOptions="Center">
<Frame
Padding="0"
BackgroundColor="CadetBlue"
CornerRadius="10"
HeightRequest="100">
<ScrollView Scrolled="ScrollView_Scrolled">
<StackLayout Padding="10">
<Label
FontSize="20"
HorizontalOptions="Center"
Text="First Popup Page"
TextColor="Black" />
<Label Text="Hello Xamarin Guys" TextColor="Red" />
<Label Text="This is Very Awesome Popup Plugins For Xamarin forms" TextColor="LightBlue" />
<Button Text="Close" TextColor="Black" />
<Image Source="a11.jpg" />
</StackLayout>
</ScrollView>
</Frame>
</StackLayout></pages:PopupPage>
private async void ScrollView_Scrolled(object sender, ScrolledEventArgs e)
{
ScrollView scrollView = sender as ScrollView;
double scrollingSpace = scrollView.ContentSize.Height - scrollView.Height;
if (scrollingSpace <= e.ScrollY) // Touched bottom
// Do the things you want to do
await PopupNavigation.Instance.PopAsync();
}
I am trying to achieve the effect, cross-platform(ios, android and uwp), as shown in the image below:
Clicking "More" normally would open a page, as normal behaviour for a tab bar item. Not sure how to override that behaviour and reveal the sliding master page instead. To the left of the "More" tab bar item, theres another tab bar item, when clicked it refreshes the data on (or reloads) the MainPage.
SettingsPage.xaml (master page, the sliding settings page)
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyProject.Classes"
xmlns:views="clr-namespace:MyProject.Views"
x:Class="MyProject.Views.SettingsMasterPage"
IconImageSource="menu.png"
Padding="0,40,0,0"
Title="Menu">
<StackLayout>
<ListView x:Name="listView" x:FieldModifier="public">
<ListView.ItemsSource>
<x:Array Type="{x:Type local:MasterPageItem}">
<local:MasterPageItem Title="Settings Link 1" />
<local:MasterPageItem Title="Settings Link 2" />
<local:MasterPageItem Title="Settings Link 3" />
</x:Array>
</ListView.ItemsSource>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding IconSource}" />
<Label Grid.Column="1" Text="{Binding Title}" />
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
MyTabbedPage.xaml
<TabbedPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific;assembly=Xamarin.Forms.Core"
xmlns:views="clr-namespace:MyProject.Views;assembly=MyProject"
x:Class="Xamarin.Sigma01.Views.LoggerDetectionTabbedPage"
android:TabbedPage.ToolbarPlacement="Bottom"
BarBackgroundColor="White"
SelectedTabColor="Black"
BarTextColor="Black">
<TabbedPage.Children>
<views:MainPage IconImageSource="tab_icon_mainpage.png" />
<!-- second link should be the sandwhich button that brings up the settings page -->
</TabbedPage.Children>
</TabbedPage>
MainPage.xaml (the main page, navigated to by the left TabBar link icon, to the left of the sandwhich icon with title "More")
<ContentPage.Content>
<StackLayout>
<Label Text="Welcome to the Main page!"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ContentPage.Content>
An easy way I can achieve the effect is to use Shell. It's released for months and just check your VS version for the correct template.
Create a new Xamarin.Forms project using VS2019.
You can use Shell out of the box if you can see the following screen.
Find "ItemsPage.xaml" in the Views folder.
Add one line in the ContentPage at the top
<ContentPage
...
Shell.TabBarIsVisible="False">
Add a StackLayout to contain the existing CollectionView and add your bottom buttons.
<RefreshView ...>
<!-- new StackLayout -->
<StackLayout>
<CollectionView ..... />
<!-- new Buttons -->
<StackLayout
HeightRequest="52"
Orientation="Horizontal"
BackgroundColor="#2196F3"
Visual="Material">
<Button
WidthRequest="200"
BackgroundColor="Transparent"
Text="Refresh"
Command="{Binding LoadItemsCommand}" />
<Button
BackgroundColor="Transparent"
Text="More"
Clicked="Button_Clicked" />
</StackLayout>
</StackLayout>
Go to "ItemsPage.xaml.cs" to complete the button event, add a method:
private void Button_Clicked(object sender, EventArgs e)
{
Shell.Current.FlyoutIsPresented = true;
}
Set startup project and deploy, check the effect and play around.
Additionally, in the latest Xamarin.Forms, UWP Shell is an experimental feature, and so does in XF 5.0. But the flyout things will probably work fine (not too sure about this).
An alternative, following the idea from #Shaw, but without Shell is to use the good old MasterDetail Page (which supports UWP) and add two buttons at the bottom to provide the "More" and "Refresh" functionality.
If this sounds like a good option for you, keep reading:
Add a Master-Detail Page to your Solution
On Visual Studio 2019 adding a Master-Detail to your solution is pretty straight forward. You only need to right click the Xamarin.Forms Project in the Solution Explorer and go to Add -> New Item (or simply use the shortcut Ctrl+Shift+A):
in the window that appears, select Master-Detail Page, give it a cool name (MasterDetailPage1 in this example!) and click Add:
By doing this you successfully have added a Master Detail to your solution. Now just go to App and set MainPage to it as follows:
MainPage = new MasterDetailPage1();
Add the bottom buttons
Now we want two buttons at the bottom of our Detail page. This is simply done by adding a stack of two buttons that locate at the end. Our newly added MasterDetailPage1Detail.xaml will then look 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="MasterTabRefresh.MasterDetailPage1Detail"
Title="Detail">
<StackLayout>
<Label Text="This is a detail page. To get the 'triple' line icon on each platform add a icon to each platform and update the 'Master' page with an Icon that references it."
Padding="10"/>
<StackLayout Orientation="Horizontal"
VerticalOptions="EndAndExpand"
Spacing="0">
<Button BackgroundColor="CornflowerBlue"
Text="Refresh"
TextColor="White"
CornerRadius="0"
HorizontalOptions="FillAndExpand"/>
<Button BackgroundColor="CornflowerBlue"
Text="More"
TextColor="White"
CornerRadius="0"
HorizontalOptions="FillAndExpand"
Clicked="MoreClicked"/>
</StackLayout>
</StackLayout>
</ContentPage>
which should look like:
And in the code behind (MasterDetailPage1Detail.xaml.cs ) we add the "More" functionality:
private void MoreClicked(object sender, EventArgs e)
{
((MasterDetailPage)Application.Current.MainPage).IsPresented = !((MasterDetailPage)Application.Current.MainPage).IsPresented;
}
Add a nice X (close) button to your menu/master
This could be achieved by adding a label with an "X" at the top right of the menu.
Simply modify your MasterDetailPage1Master.xaml to look like (note Label at Column 2 Row 0!)
<?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="MasterTabRefresh.MasterDetailPage1Master"
Title="Master">
<StackLayout>
<ListView x:Name="MenuItemsListView"
SeparatorVisibility="None"
HasUnevenRows="true"
ItemsSource="{Binding MenuItems}">
<ListView.Header>
<Grid BackgroundColor="#03A9F4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="80"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Label Grid.Column="2"
Grid.Row="0"
Text="X"
FontAttributes="Bold"
HorizontalTextAlignment="Center"
VerticalTextAlignment="Center">
<Label.GestureRecognizers>
<TapGestureRecognizer Tapped="X_Tapped"/>
</Label.GestureRecognizers>
</Label>
<Label
Grid.Column="1"
Grid.Row="2"
Text="My wonderful App"
Style="{DynamicResource SubtitleStyle}"/>
</Grid>
</ListView.Header>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="15,10" HorizontalOptions="FillAndExpand">
<Label VerticalOptions="FillAndExpand"
VerticalTextAlignment="Center"
Text="{Binding Title}"
FontSize="24"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>
Which should look like this:
And then add the "Close" functionality to that "X" Label in the code behind (MasterDetailPage1Master.xaml):
private void X_Tapped(object sender, EventArgs e)
{
((MasterDetailPage)Application.Current.MainPage).IsPresented = false;
}
And that is it! This should get you going. Happy coding!
I'm study Xamarin, I have Xamarin Forms using Collection View. I want to create master menu on home page in android. I can't auto change show view item in Collection View.
enter image description here
Bind the ItemTemplate to a DynamicResource and change the Resource on a button click or where you want the change to happen.
Define the templates in resource of the page.
<ContentPage.Resources>
<DataTemplate x:Key="menuTemplate1">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*" />
<ColumnDefinition Width="0.7*" />
</Grid.ColumnDefinitions>
<Image Source="https://i.stack.imgur.com/di65V.jpg?s=328&g=1" />
<StackLayout Grid.Column="2">
<Label Text="Hi there" />
<Label Text="Hi there" />
</StackLayout>
</Grid>
</DataTemplate>
<DataTemplate x:Key="menuTemplate2">
<Image Source="https://i.stack.imgur.com/di65V.jpg?s=328&g=1" />
</DataTemplate>
</ContentPage.Resources>
Initialize DynamicResource in Page.Xaml.cs
public MainPage()
{
InitializeComponent();
Resources["menuTemplate"] = Resources["menuTemplate1"];
}
Bind the DynamicResource toItemTemplate`
<CollectionView ItemTemplate="{DynamicResource menuTemplate}" ItemsSource="{Binding ItemCollection}" />
Change the DynamicResource on button click or where you want.
void Button_Clicked(System.Object sender, System.EventArgs e)
{
if(Resources["menuTemplate"] == Resources["menuTemplate1"])
{
Resources["menuTemplate"] = Resources["menuTemplate2"];
}
else
{
Resources["menuTemplate"] = Resources["menuTemplate1"];
}
}
Please do check and comment for any query.
I need to integrate the Dynamic horizontal listview in my project. I found this concept below blog on the website. But I confused this code to integrate into my project. Kindly suggest me an idea to anyone. I need this image type grid or horizontal listview( https://i.stack.imgur.com/OvJZE.png).
Mainpage.xaml.cs
public void SetupUserStack()
{
---------- issue in _itemSelectCommand in my code
cButtonList.Add(new CircleButton(_itemSelectCommand)
{ CircleSize = otherCircleSize, CircleFontSize = 35, Text = initials, BackgroundColor = Color.White, TextColor = ourBlue, BorderColor = ourBlue, BorderWidth = 1.5 });
var b2 = new Button() { Text = lname, TextColor = ourBlue };
//otherGrid.Children.Add(LargeCB, 0, 0);
otherGrid.Children.Add(cButtonList[i], 0, 0);
otherGrid.Children.Add(b2, 0, 1);
UserStack.Children.Add(otherGrid);
}
Blog I refer: horizontal-list-view-with-circular-button-styling-in-xamarin-forms
This is the another way to achieve the same thing. Xamarin forms now support the Bindable Layouts
XAML Code:
<ScrollView
Orientation="Horizontal"
HorizontalScrollBarVisibility="Default">
<StackLayout Margin="20,0,20,0"
Orientation="Horizontal"
BindableLayout.ItemsSource="{Binding LogoImages}">
<BindableLayout.ItemTemplate>
<DataTemplate>
<Image
HeightRequest="25"
Margin="0,0,5,0"
Source="{Binding logoImage}">
</Image>
</DataTemplate>
</BindableLayout.ItemTemplate>
</StackLayout>
</ScrollView>
Here is more information with the example :
Bindable Layouts
Use a collectionView to create a horizontal-list would be easier and faster, for example:
<CollectionView ItemsSource="{Binding Monkeys}"
ItemsLayout="HorizontalList">
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="10">
<Grid.RowDefinitions>
<RowDefinition Height="35" />
<RowDefinition Height="35" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70" />
<ColumnDefinition Width="140" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2"
Source="{Binding ImageUrl}"
Aspect="AspectFill"
HeightRequest="60"
WidthRequest="60" />
<Label Grid.Column="1"
Text="{Binding Name}"
FontAttributes="Bold"
LineBreakMode="TailTruncation" />
//...your layout
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
The Monkeys should be a list that in your ViewModel.
You can check the sample with MVVM structure here:collectionviewdemos
In your linking blog, he creates the grid dynamically with the users.Count and I think it hard to integrate his code to MVVM structure.
newbie here. I remember in Win10, there is a PopUp UI which can contains many controls like Dropdown box, DatePciker and others. This PopUp can be constructed in Xaml.
I am developing an app for Tablet.
It is possible to use such PopUp in Xamarin forms which contains Dropdown List, DatePicker, Time Picker? It is advisable to do such complex UI ? will it cause problem in Android and iOS?
Problem : How to create PopUp in Xaml
so ,I can use a button to open or close it.
var button = new Button {Text = "Show Popup"};
button.Clicked += (s, e) => popup.Show();
Update
<?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="MyApp.View.PopUpDemo"
Title="PopUp Demo"
Icon="itemIcon3">
<Grid>
<Grid>
<!--Your Page xaml-->
<Button x:Name="btnPopUp" Click="ShowPopUp"/>
</Grid>
<Grid HorizontalOptions="Fill" BackgroundColor="##60000000" IsVisible="{Binding GridVisibility}">
<Grid VerticalOptions="CenterAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width="9*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<Frame Grid.Column="1" Padding="0" HasShadow="True" OutlineColor="#e6e6e6">
<Grid BackgroundColor="White" RowSpacing="0" ColumnSpacing="0">
<!--content for popup-->
</Grid>
</Frame>
</Grid>
</Grid>
</Grid>
</ContentPage>
I would like to know :
I am using a normal ContentPage.
1) In it, i place your MarkUp <Grid> ,I remove <ContentPage.Content>. Is this correct?
2) Is Frame will be the PopUp ?
3) what code to use in btnPopUp to show the PopUp?
Thanks
Yes you can achieve it without any performance issue. Either you can use an overlay to show pop up as shown below
<Grid>
<Grid>
<!--Your Page xaml-->
</Grid>
<Grid HorizontalOptions="Fill" BackgroundColor="##60000000" IsVisible="{Binding GridVisibility}">
<Grid VerticalOptions="CenterAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width="9*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<Frame Grid.Column="1" Padding="0" HasShadow="True" OutlineColor="#e6e6e6">
<Grid BackgroundColor="White" RowSpacing="0" ColumnSpacing="0">
<!--content for popup-->
</Grid>
</Frame>
</Grid>
</Grid>
</Grid>
This one is quite simple. Here i have added grid to achieve this. You can also use other layouts. But for performance grid is better as per xamarin team.
For the second grid i have added Visibility property so that you can wire up with any event.
Here i have added backgroundcolor for popup ##60000000 so that when popup appears background will be transparent with light black color effect.
If you need to have same pop up in multiple screens you can use 3rd party plugin https://github.com/rotorgames/Rg.Plugins.Popup which will make you work easier. For this you have to make a new contentpage, replace the contentpage with
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
x:Class=""
BackgroundColor="##60000000"
InputTransparent="True"
HasSystemPadding="True"
CloseWhenBackgroundIsClicked="False">
<pages:PopupPage.Animation>
<animations:MoveAnimation
PositionIn="Bottom"
PositionOut="Bottom"/>
</pages:PopupPage.Animation>
<Grid>
<!--your xaml code-->
</Grid>
Note:Replace contentPage with PopupPage in youpage.xaml.cs. To get popup effect your layout should be like 1st example i shown. Here you can also get nice animation effects. More details you can see in their site.
Now you can call the pop up by calling:navigation.PushPopupAsync(new YourContentPage());
And remove the popup by calling await PopupNavigation.RemovePageAsync(this);
Hope this will be useful for you