I have Xamarin Forms application. I need to put image as json in project.
Here is XAML:
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:forms="clr-namespace:Lottie.Forms;assembly=Lottie.Forms"
x:Class="xxx.Views.ScanReadyPage">
<StackLayout>
<forms:AnimationView
x:Name="lottie"
Animation="12240-cash-car.json"
Loop="False"
AutoPlay="True"
WidthRequest="200"
HeightRequest="200"
Margin="10,0,10,0"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand" />
</StackLayout>
</ContentPage.Content>
</ContentPage>
I have installed Com.Airbnb.Xamarin.Forms.Lottie version 3.0.3 and Xamarin.Forms version 4.3.0.991221
I have added downloaded file from lottiefiles.com: 12240-cash-car.json to Assets folder in XamarinForms.Android project and set build action to Android Asset.
Nothing is displayed on Android. No informations at output, no error occured. I have changed Xamarin Forms to 3.6.0 - no changes. I have installed all versions of Lottie: from 2.6.3 to 3.0.3. - no image is being displayed. (Version 2.6.3. and earlier have error about missing keystore).
I have checked code behind version but it is also not working:
public MainPage()
{
element = new AnimationView()
{
Loop = true,
AutoPlay = true,
Animation = "12230-bounce-down-steps.json",
WidthRequest = 400,
HeightRequest = 400,
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
IsVisible = true,
Speed = 1
};
}
AnimationView element = new AnimationView();
protected override void OnAppearing()
{
element.Animation = "12230-bounce-down-steps.json";
element.Play();
}
How to make it works?
I have found solution here: https://iinteractive.com/notebook/2017/05/31/lottie-xamarin.html . At start install "Com.Airbnb.Xamarin.Forms.Lottie" in all 3 projects. Then install another library: "Com.Airbnb.Android.Lottie" separately in Android project. Now you can go to MainActivity.cs, enter "using Lottie.Forms.Droid" and "AnimationViewRenderer.Init(); and json images are displaying correctly. Thanks Guilherme Nimer for good tip.
did u init the AnimationViewRenderer from MainActivity?
MainActivity.cs
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
PullToRefreshLayoutRenderer.Init();
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
AnimationViewRenderer.Init();
LoadApplication(new App());
}
on AppDelegate.cs
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init();
LoadApplication(new App());
AnimationViewRenderer.Init();
return base.FinishedLaunching(app, options);
}
Working animation that i use in my proj
<?xml version="1.0" encoding="utf-8" ?>
<pages:PopupPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:pages="clr-namespace:Rg.Plugins.Popup.Pages;assembly=Rg.Plugins.Popup"
xmlns:lottie="clr-namespace:Lottie.Forms;assembly=Lottie.Forms"
xmlns:animations="clr-namespace:Rg.Plugins.Popup.Animations;assembly=Rg.Plugins.Popup"
x:Class="SincorSPM.ErrorPopup.PopupError">
<pages:PopupPage.Animation>
<animations:ScaleAnimation
PositionIn="Bottom"
PositionOut="Center"
ScaleIn="1"
ScaleOut="0.7"
DurationIn="700"
EasingIn="BounceOut"/>
</pages:PopupPage.Animation>
<Frame IsClippedToBounds="True" CornerRadius="15" Margin="15,15">
<StackLayout BackgroundColor="White" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" Margin="15,15">
<Label Text="Ocorreu um erro!" TextColor="Orange" FontSize="Title" Margin="10,10,10,3" HorizontalOptions="CenterAndExpand"/>
<Label Text="Verifique sua conexão e tente novamente" TextColor="Black" FontSize="Medium" Margin="10,0,10,0" HorizontalOptions="CenterAndExpand"/>
<Label x:Name="txCode" IsVisible="False" TextColor="Black" FontSize="Medium" Margin="10,0,10,0" HorizontalOptions="CenterAndExpand"/>
<lottie:AnimationView
Animation="dc.json"
AutoPlay="True" Loop="true"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand" />
<Button Margin="10,10" HorizontalOptions="FillAndExpand" Text="Fechar" BackgroundColor="#032e5c" CornerRadius="15" TextColor="White" Clicked="Fechar"/>
</StackLayout>
</Frame>
</pages:PopupPage>
my lottie is 3.0.3
I solved the issue by updating my xamarin.forms to the latest and changing Target Android Version to 10.0
Related
Description
Xamarin application opens different Page upon NavigationPage.Pushaync().
NavigationPage.Asyncpush() is called within a ButtonClicked Method.
That different page used to be the one being pushed but it no longer is.
ViewModel.cs
private async void OnAboutUsClicked()
{
var modifiedContactUs = new ModifiedContactUs() { BackgroundColor = ResourceColourModel.BackgroundColor };
await Application.Current.MainPage.Navigation.PushAsync(modifiedContactUs);
}
ModifiedContactUs.xaml
<?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.Views.Pages.ModifiedContact"
xmlns:mapObject="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps">
<ContentPage.Content>
<StackLayout>
<Grid BackgroundColor="white">
<mapObject:Map x:Name="mapId" HasZoomEnabled="True" MapType="Street">
</mapObject:Map>
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
ModifiedContactUs.xaml.cs
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace Project.Views.Pages
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ModifiedContactUs : ContentPage
{
public ModifiedContactUs()
{
InitializeComponent();
}
}
ContactUs.xaml(The different Page)
<?xml version="1.0" encoding="utf-8" ?>
<customControl:CustomContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:map ="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
xmlns:ffimageloading="clr-namespace:FFImageLoading.Svg.Forms;assembly=FFImageLoading.Svg.Forms"
xmlns:customControl="clr-namespace:Project.CustomControls.Renderers"
xmlns:templates_navbar="clr-namespace:Project.Views.Templates.Menus"
xmlns:fontAwesome="clr-namespace:Project._Utilities"
mc:Ignorable="d"
x:Class="Project.Views.Pages.ContactUs"
>
<ContentPage.Content>
<StackLayout BackgroundColor="Transparent" Spacing="0">
<templates_navbar:NavBar DotMenu_IsVisible="False" BackButton_IsVisible="True"/>
<Grid BackgroundColor="white">
<Grid.RowDefinitions>
<RowDefinition Height=".33*"/>
<RowDefinition Height=".07*"/>
<RowDefinition Height=".6*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".7*"/>
<ColumnDefinition Width=".3*"/>
</Grid.ColumnDefinitions>
<StackLayout Grid.Column="0" Padding="10">
<StackLayout>
<Label
Text="Company Name"
FontAttributes="Bold"
FontSize="Medium"
FontFamily="Lato-Bold"
VerticalOptions="CenterAndExpand"
HorizontalOptions="StartAndExpand"
/>
<Label
Text="{Binding Address}"
FontFamily="Lato-Bold"
VerticalOptions="CenterAndExpand"
HorizontalOptions="StartAndExpand"
/>
</StackLayout>
<StackLayout>
<Label
Text="Opening Times"
FontAttributes="Bold"
FontSize="Medium"
FontFamily="Lato-Bold"
VerticalOptions="CenterAndExpand"
HorizontalOptions="StartAndExpand"
/>
<Label
x:Name="weekdays_lbl"
Text="{Binding Weekday}"
FontFamily="Lato-Bold"
VerticalOptions="CenterAndExpand"
HorizontalOptions="StartAndExpand"
/>
<Label
x:Name="weekend_lbl"
Text="{Binding Weekend}"
FontFamily="Lato-Bold"
VerticalOptions="CenterAndExpand"
HorizontalOptions="StartAndExpand"
/>
</StackLayout>
</StackLayout>
<StackLayout Grid.Column="1">
<StackLayout VerticalOptions="CenterAndExpand">
<Button
x:Name="CallUsBtn"
Text="Call Us"
TextColor="White"
BackgroundColor="{StaticResource PrimaryColour}"
FontFamily="Lato-Bold"
FontSize="12"
BorderWidth="2"
BorderColor="White"
Margin="1"
CornerRadius="22"
Command="{Binding PhoneCommand}"
/>
<Button
x:Name="MessageUsBtn"
Text="Message"
TextColor="White"
BackgroundColor="{StaticResource PrimaryColour}"
FontFamily="Lato-Bold"
FontSize="12"
BorderWidth="2"
BorderColor="White"
Margin="1"
CornerRadius="22"
Command="{Binding EmailCommand}"
/>
<Button
x:Name="RequestCallBack"
Text="Request CallBack"
TextColor="White"
BackgroundColor="{StaticResource AccentColour}"
FontFamily="Lato-Bold"
FontSize="11"
BorderWidth="2"
BorderColor="White"
Margin="1"
CornerRadius="22"
Command="{Binding CallbackCommand}"
/>
</StackLayout>
</StackLayout>
</Grid>
<Grid Grid.Row="1" Padding="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".25*"/>
<ColumnDefinition Width=".25*"/>
<ColumnDefinition Width=".25*"/>
<ColumnDefinition Width=".25*"/>
</Grid.ColumnDefinitions>
<StackLayout Grid.Column="0">
<Grid VerticalOptions="CenterAndExpand">
<Image
Source="{FontImage FontFamily={StaticResource MaterialFontFamily},
Glyph={x:Static fontAwesome:IconFonts.Facebook}, Color=#1877F2,Size=60}"
HeightRequest="80"
/>
<Button Clicked="SocialMediaBtnHandler" BackgroundColor="Transparent" Margin="5, 0" CommandParameter="facebook"/>
</Grid>
</StackLayout>
<StackLayout Grid.Column="1">
<Grid VerticalOptions="CenterAndExpand">
<Image
Source="{FontImage FontFamily={StaticResource MaterialFontFamily},
Glyph={x:Static fontAwesome:IconFonts.Twitter}, Color=#00ACED, Size=60}"/>
<Button Clicked="SocialMediaBtnHandler" BackgroundColor="Transparent" Margin="5, 0" CommandParameter="twitter"/>
</Grid>
</StackLayout>
<StackLayout Grid.Column="2">
<Grid VerticalOptions="CenterAndExpand">
<Image
Source="{FontImage FontFamily={StaticResource MaterialFontFamily},
Glyph={x:Static fontAwesome:IconFonts.Linkedin}, Color=#0E76A8, Size=60}"/>
<Button Clicked="SocialMediaBtnHandler" BackgroundColor="Transparent" Margin="5, 0" CommandParameter="linkedIn"/>
</Grid>
</StackLayout>
<StackLayout Grid.Column="3">
<Grid VerticalOptions="CenterAndExpand" Padding="2">
<ffimageloading:SvgCachedImage
Source="social_logo_instagram.png"
HeightRequest="40"/>
<Button Clicked="SocialMediaBtnHandler" BackgroundColor="Transparent" Margin="5, 0" CommandParameter="instagram"/>
</Grid>
</StackLayout>
</Grid>
<Grid Grid.Row="2">
<Grid>
<StackLayout Grid.Row="0" Padding="5">
<map:Map x:Name="mapObject" HasZoomEnabled="True" MapType="Street">
<map:Map.ItemTemplate>
<DataTemplate>
<map:Pin
Position="{Binding Position}"
Address="{Binding Address}"
Label="{Binding PlaceName}"
/>
</DataTemplate>
</map:Map.ItemTemplate>
</map:Map>
</StackLayout>
</Grid>
</Grid>
</Grid>
<AbsoluteLayout BackgroundColor="Red" HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand" AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="SizeProportional">
</AbsoluteLayout>
</StackLayout>
</ContentPage.Content>
</customControl:CustomContentPage>
ContactUs.xaml.cs (The different page)
using Project._SharedData;
using Project.CustomControls.Renderers;
using Project.Models;
using Project.ViewModels;
using Rg.Plugins.Popup.Services;
using System;
using Xamarin.Essentials;
using Xamarin.Forms;
using Xamarin.Forms.Maps;
using Xamarin.Forms.Xaml;
namespace Project.Views.Pages
{
[XamlCompilation(XamlCompilationOptions.Compile)]
[System.ComponentModel.DesignTimeVisible(false)]
public partial class ContactUsPage : CustomContentPage
{
ContactUsVM _ContactUsVM;
public ContactUsPage()
{
InitializeComponent();
BindingContext = _ContactUsVM = new ContactUsVM();
initMap();
configureDisplay();
setFontOpeningTime();
}
protected override void OnAppearing()
{
base.OnAppearing();
_ContactUsVM.OnAppearing();
configureDisplay();
}
protected override void OnDisappearing()
{
base.OnDisappearing();
_ContactUsVM.OnDisappearing();
try
{
if (PopupNavigation.Instance != null)
PopupNavigation.Instance.PopAsync(true);
}
catch (Exception) { }
}
private void setFontOpeningTime()
{
DayOfWeek day = DateTime.Now.DayOfWeek;
// Set the font based on whether current day is weekday or weekend
if ((day == DayOfWeek.Saturday) || (day == DayOfWeek.Sunday))
{
weekend_lbl.FontAttributes = FontAttributes.Bold;
}
else
{
weekdays_lbl.FontAttributes = FontAttributes.Bold;
}
}
private void configureDisplay()
{
if (!string.IsNullOrEmpty(SharedPrefs.UserSessionEmail))
{
RequestCallBack.IsVisible = true;
MessageUsBtn.Text = "Email";
}
else
{
RequestCallBack.IsVisible = false;
MessageUsBtn.Text = "Message";
}
}
private async void SocialMediaBtnHandler(object sender, EventArgs e)
{
string socialMediaName = (sender as Button).CommandParameter.ToString().ToLower();
await Launcher.OpenAsync(SocialMediaModel.WebLink(socialMediaName));
}
private void initMap()
{
try
{
double latitude = Convert.ToDouble(SharedData.CompanyDetailsList[0].Latitude);
double longitude = Convert.ToDouble(SharedData.CompanyDetailsList[0].Longitude);
mapObject.MoveToRegion(MapSpan.FromCenterAndRadius(new Position(latitude, longitude), Distance.FromMeters(100)));
mapObject.ItemsSource = SharedData.CompanyDetailsList;
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
}
}
Expected behavior
To navigate to a new Page named ModifiedContactUs
Actual behavior:
Navigates to page called named ContactUs
Basic Information:
Android Build:
-minimum level 21
-Target level 30
Devices:
-Huawei Y6 2019
-API level 29
-Pixel 5
-API level 30
Notes
This question is different to from the first question I asked recently (Where the device crashes). This is behavior happens on all devices I test on except the one from that first question
Expected behavior
To navigate to a new Page named ModifiedContactPage
Actual behavior:
Navigates to page called named ContactUsPage
From your code I saw you just push to ModifiedContactUs not ModifiedContactPage .
var modifiedContactUs = new ModifiedContactUs() { BackgroundColor = ResourceColourModel.BackgroundColor };
await Application.Current.MainPage.Navigation.PushAsync(modifiedContactUs);
Suggestion
Try to add breakpoint to see if it triggers button click event es expected .
Delete the old class and try again .
Delete the app from the device and try again .
This worked: Clone the repo into a new folder as a new project and copy the files and changes to this new repo.
Attempted configuration solutions that did not work: Restarting visual studio. Untick and Tick Debug Mode. Untick and tick Deploy in Configuration Manager under Build. In Android Properties> android Options making sure debugging is checked and debugger is Xamarin.
Im trying to click Image,box or label object which in Carousel views content page. Android works fine but IOS not, why? Can you help or explain?
Here is simple demo:
<CarouselPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CarouselPageNavigation.MainPage">
<ContentPage>
<ContentPage.Padding>
<OnPlatform x:TypeArguments="Thickness">
<On Platform="iOS, Android" Value="0,40,0,0" />
</OnPlatform>
</ContentPage.Padding>
<StackLayout>
<Label Text="Green" FontSize="Medium" HorizontalOptions="Center" />
<BoxView Color="Green" WidthRequest="200" HeightRequest="200" HorizontalOptions="Center" VerticalOptions="CenterAndExpand">
<BoxView.GestureRecognizers>
<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
</BoxView.GestureRecognizers>
</BoxView>
</StackLayout>
</ContentPage>
Here is .cs
private void TapGestureRecognizer_Tapped(object sender, System.EventArgs e)
{
DisplayAlert("sdada", "sdada", "sdadada");
}
I solved it update to beta IOS SDK update on mac side before xamarin.forms 4.5.0.617.
Now this issue has been fixed , you can update Xamrin Forms to the latest version 4.5.0.617 , then it will work in iOS 13.4 .
Thanks Junior Jiang
I am trying to programmatically add an ActivityIndicator to my Xamarin ContentPages that do data access. I have all of the code working great below on my Android device (a Samsung Galaxy Tab A). When I went to test it on my iOS (iPhone 7), it does not render any of the pages that are wrapped in the AbsoluteLayout. I simplified the repo down to this project that demonstrates the issue.
The full project is here: https://github.com/wadebaird/absoluteLayoutIssue
Here are the basics, I have the ContentPage below, of which I programmatically add buttons to the "MainPageStackLayout" during OnAppearing.
<?xml version="1.0" encoding="utf-8" ?>
<absolutelayoutissue:CommonContentPage
xmlns:absolutelayoutissue="clr-namespace:AbsoluteLayoutIssue"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AbsoluteLayoutIssue.AbsoluteLayoutProgrammatic">
<absolutelayoutissue:CommonContentPage.Content>
<ScrollView>
<StackLayout x:Name="MainPageStackLayout" VerticalOptions="Start" Margin="20, 20" Spacing="25">
<Label FontSize="Large" FontAttributes="Bold" Margin="20" TextColor="Red" HorizontalTextAlignment="Center"
Text="No network connection detected, please enable a connection to use this application."
IsVisible="False" />
</StackLayout>
</ScrollView>
</absolutelayoutissue:CommonContentPage.Content>
</absolutelayoutissue:CommonContentPage>
During the constructor I call this method to programmatically add an AbsoluteLayout that wraps the ActivityIndicator and a Label:
public void AddActivityIndicator()
{
var content = this.Content;
var overlay = new AbsoluteLayout
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
};
var activityIndicator = new ActivityIndicator
{
IsEnabled = true,
HorizontalOptions = LayoutOptions.FillAndExpand,
//Use the same color as the school text color as it should contrast the background the same.
Color = Color.Black,
};
var activityMessage = new Label
{
IsEnabled = true,
HorizontalOptions = LayoutOptions.FillAndExpand,
TextColor = Color.Black,
Text = "Loading...",
};
var stackLayout = new StackLayout();
stackLayout.Children.Add(activityIndicator);
stackLayout.Children.Add(activityMessage);
activityIndicator.SetBinding(ActivityIndicator.IsVisibleProperty, nameof(ViewModel.IsBusy));
activityIndicator.SetBinding(ActivityIndicator.IsRunningProperty, nameof(ViewModel.IsBusy));
activityMessage.SetBinding(Label.IsVisibleProperty, nameof(ViewModel.IsBusy));
AbsoluteLayout.SetLayoutFlags(content, AbsoluteLayoutFlags.All);
AbsoluteLayout.SetLayoutBounds(content, new Rectangle(0f, 0f, 1, 1));
AbsoluteLayout.SetLayoutFlags(stackLayout, AbsoluteLayoutFlags.PositionProportional);
AbsoluteLayout.SetLayoutBounds(stackLayout, new Rectangle(0.5, 0.5, AbsoluteLayout.AutoSize, AbsoluteLayout.AutoSize));
overlay.Children.Add(content);
overlay.Children.Add(stackLayout);
this.Content = overlay;
}
When this is done the page loads as completely blank. When I model the page vs programmatically adding the AbsoluteLayout, it all works perfect:
<?xml version="1.0" encoding="utf-8" ?>
<absolutelayoutissue:CommonContentPage
xmlns:absolutelayoutissue="clr-namespace:AbsoluteLayoutIssue"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="AbsoluteLayoutIssue.AbsoluteLayoutModeled">
<absolutelayoutissue:CommonContentPage.Content>
<AbsoluteLayout HorizontalOptions="FillAndExpand" VerticalOptions="FillAndExpand">
<ScrollView AbsoluteLayout.LayoutFlags="All" AbsoluteLayout.LayoutBounds="0,0,1,1">
<StackLayout x:Name="MainPageStackLayout" VerticalOptions="Start" Margin="20, 20" Spacing="25">
<Label FontSize="Large" FontAttributes="Bold" Margin="20" TextColor="Red" HorizontalTextAlignment="Center"
Text="No network connection detected, please enable a connection to use this application."
IsVisible="False" />
</StackLayout>
</ScrollView>
<StackLayout AbsoluteLayout.LayoutFlags="PositionProportional" AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1">
<ActivityIndicator IsEnabled="True" HorizontalOptions="FillAndExpand" Color="Black" IsVisible="{Binding IsBusy}" IsRunning="{Binding IsBusy}" />
<Label IsEnabled="True" HorizontalOptions="FillAndExpand" TextColor="Black" Text="Loading..." IsVisible="{Binding IsBusy}"/>
</StackLayout>
</AbsoluteLayout>
</absolutelayoutissue:CommonContentPage.Content>
</absolutelayoutissue:CommonContentPage>
However I don't want to model it as I want to be able to add this code to the fly on any page in my app.
So the question is can anyone see the difference between my modeled page and my programmatically built one? If not, has anyone seen this issue before? I can't seem to find any settings on the AbsoluteLayout to get around it.
Thank you in advance.
After a day of continuing to try and figure this out I discovered that switching around the order of setting the AbsoluteLayout on the Page.Content and then adding it's children fixed the rendering / layout issue:
overlay.Children.Add(content);
overlay.Children.Add(stackLayout);
this.Content = overlay;
needs to be like this:
this.Content = overlay;
overlay.Children.Add(content);
overlay.Children.Add(stackLayout);
I m using Vs for mac: 7.5.1(Build 22). I try to build a Master Detail page with ListView binding to a simple class.
Problem encountered: Specified cast is not valid.
In the code behind: I have red underline for InitializeComponent as well as for the ListView. Why?
In the SideMenu.xaml: Do I need to add this?
xmlns:local="clr-namespace:MyNavigationSideMenu"
Here the code:
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MyNavigationSideMenu;assembly=MyNavigationSideMenu"
x:Class="MyNavigationSideMenu.MySideMenu">
<MasterDetailPage.Master>
<ContentPage Title="Menu">
<Grid BackgroundColor ="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height ="200"/>
<RowDefinition Height ="*"/>
</Grid.RowDefinitions>
<Grid>
<Image Source="bg.png" Aspect="AspectFill" />
<StackLayout Padding="0,20,0,0" HorizontalOptions="CenterAndExpand" VerticalOptions="CenterAndExpand">
<Image Source="home.png" Aspect="AspectFit" WidthRequest="60" HeightRequest="60" />
<Label Text="Xamarin Buddy" TextColor="White" FontSize="Large" />
</StackLayout>
</Grid>
<StackLayout Grid.Row="1" Spacing="15">
<ListView x:Name ="navigationLV"
RowHeight ="60"
SeparatorVisibility ="None"
BackgroundColor ="#e8e8e8"
ItemSelected="OnMenuItemSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout>
<StackLayout VerticalOptions="FillAndExpand"
Orientation="Horizontal"
Spacing="20">
<Image Source="{Binding Icon}"
WidthRequest="30"
HeightRequest="30"
VerticalOptions="Center"/>
<Label Text="{Binding Title}"
FontSize="Medium"
VerticalOptions="Center"
TextColor="Black"/>
</StackLayout>
<BoxView
HeightRequest="1"
BackgroundColor="Gray"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</Grid>
</ContentPage>
</MasterDetailPage.Master>
<MasterDetailPage.Detail>
<NavigationPage>
</NavigationPage>
</MasterDetailPage.Detail>
here the code behind of SideMenu:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using MyNavigationSideMenu.MenuItems;
namespace MyNavigationSideMenu
{
public partial class MySideMenu : MasterDetailPage
{
public List<MasterPageItem> menuList { get; set; }
public MySideMenu()
{
InitializeComponent();
menuList = new List<MasterPageItem>();
// Adding menu items to menuList and you can define title ,page and icon
menuList.Add(new MasterPageItem() { Title = "Home", Icon = "home.png", TargetType = typeof(HomePage) } );
navigationLV.ItemsSource = menuList;
// Initial navigation, this can be used for our home page
Detail = new NavigationPage((Page)Activator.CreateInstance(typeof(HomePage)));
}
private void OnMenuItemSelected(object sender, SelectedItemChangedEventArgs e)
{
var item = (MasterPageItem)e.SelectedItem;
Type page = item.TargetType;
Detail = new NavigationPage((Page)Activator.CreateInstance(page));
IsPresented = false;
}
}
}
You need to check all these 3 steps:
1.Save the MySideMenu.xaml file & check red underline has gone.
2.Right click on MySideMenu.xaml & click on Properties & check Build Action should be set to "Embedded resource".
3.Add Try Catch for Initialize component in MySideMenu.xaml file & check which line the error is getting displayed.
I want to display a ListView and other controls inside a ScrollView. All is bound to a ViewModel. My attempts failed because it's not recommend to put a ListView inside a ScrollView. As I use a complex ViewCell DataTemplate, I did not consider to add my items in the code behind file as Buttons instead of a ListView.
Hope someone can show me a Xaml or CS pattern to achieve my goal.
Please only suggest a solution which works on iOS and Android!
Thanks
Eric
This is XAML code
<ScrollView Padding="2">
<StackLayout HorizontalOptions="FillAndExpand">
<Grid HorizontalOptions="FillAndExpand">
<StackLayout>
<ScrollView Orientation="Horizontal">
<ListView BackgroundColor="Transparent" ItemsSource="{Binding UsersList}" SeparatorVisibility="None" x:Name="YourListView" RowHeight="50">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout BackgroundColor="Transparent" Padding="5">
<Button Text="{Binding UserName}" WidthRequest="115" HorizontalOptions="FillAndExpand" TextColor="White" BackgroundColor="#4b76c4" FontAttributes="Bold" FontSize="20" FontFamily="Avenir Book"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollView>
</StackLayout>
</Grid>
</StackLayout>
</ScrollView>
and .cs file you need set BindingContext
BindingContext = new YourViewModel();
Solution:
As Rodrigo E suggested I download the latest Xamarin Evolve App 2016. After digging through the code I adjusted/simplified the FeedPage.xaml in the solution to that:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:XamarinEvolve.Clients.UI;assembly=XamarinEvolve.Clients.UI"
xmlns:pull="clr-namespace:Refractored.XamForms.PullToRefresh;assembly=Refractored.XamForms.PullToRefresh"
x:Class="XamarinEvolve.Clients.UI.FeedPage"
x:Name="FeedPage"
Title="Evolve Feed"
Icon="tab_feed.png"
BackgroundColor="{DynamicResource WindowBackgroundTable}">
<pull:PullToRefreshLayout
IsPullToRefreshEnabled="True"
RefreshCommand="{Binding RefreshCommand}"
IsRefreshing="{Binding IsBusy}">
<local:AlwaysScrollView
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand">
<StackLayout>
<StackLayout Spacing="0">
<local:NonScrollableListView
x:Name="ListViewSessions"
ItemsSource="{Binding Sessions}">
<local:NonScrollableListView.RowHeight>
<OnPlatform x:TypeArguments="x:Int32" Android="50" iOS="50" WinPhone="50"/>
</local:NonScrollableListView.RowHeight>
<local:NonScrollableListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Button Text="{Binding Title}" BackgroundColor="Black" TextColor="Green" />
</ViewCell>
</DataTemplate>
</local:NonScrollableListView.ItemTemplate>
</local:NonScrollableListView>
</StackLayout>
<StackLayout Padding="0" Spacing="0" BackgroundColor="Green">
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
<Button Text="OTHER" BackgroundColor="Blue" TextColor="White" />
</StackLayout>
</StackLayout>
</local:AlwaysScrollView>
</pull:PullToRefreshLayout>
There are a few things to do:
In the FeedViewModel.cs I added that code for a quick test:
async Task ExecuteLoadSessionsCommandAsync()
{
if (LoadingSessions)
return;
LoadingSessions = true;
try
{
NoSessions = false;
Sessions.Clear();
OnPropertyChanged("Sessions");
#if DEBUG
await Task.Delay(1000);
#endif
var sessions = await StoreManager.SessionStore.GetNextSessions();
var testSessions = new List<Session>();
testSessions.Add(new Session
{
Title = "TEST"
});
testSessions.Add(new Session
{
Title = "TEST"
});
testSessions.Add(new Session
{
Title = "TEST"
});
sessions = testSessions;
if(sessions != null)
Sessions.AddRange(sessions);
NoSessions = Sessions.Count == 0;
}
catch(Exception ex)
{
ex.Data["method"] = "ExecuteLoadSessionsCommandAsync";
Logger.Report(ex);
NoSessions = true;
}
finally
{
LoadingSessions = false;
}
}
You have to reference the package Refractored.XamForms.PullToRefresh to get the Pull-to-Refresh behavor.
This is in that namespace referenced: xmlns:pull="clr-namespace:Refractored.XamForms.PullToRefresh;assembly=Refractored.XamForms.PullToRefresh"
You have to Copy the AlwaysScrollView , NonScrollableListView to your PCL library.
refercene it with: xmlns:local="clr-namespace:"
In your iOS Project add that custom ListView Renderer:
public class NonScrollableListViewRenderer : ListViewRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (Control != null)
Control.ScrollEnabled = false;
}
}
public class AlwaysScrollViewRenderer : ScrollViewRenderer
{
public static void Initialize()
{
var test = DateTime.UtcNow;
}
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
this.AlwaysBounceVertical = true;
}
}
See file: Renderer
Put that CollectionChanged Handler in your Code-behind file:
ViewModel.Sessions.CollectionChanged += (sender, e) =>
{
var adjust = Device.OS != TargetPlatform.Android ? 1 : -ViewModel.Sessions.Count + 1;
ListViewSessions.HeightRequest = (ViewModel.Sessions.Count * ListViewSessions.RowHeight) - adjust;
};
See File FeedPage.cs.xaml: FeedPage.cs.xaml