I'm making an app with Xamarin Form that should work both on iOS and Android, I have a carousel view with an image inside, so I have tried making a carousel with a cell using this nugget: URL
while working fine on iOS on android the cell keeps crashing so I've changed with a cell containing only one image with a binding on the URL
now everything working but the are sono images sporadically missing inside the carousel.
Am I missing something? is there a nugget package for xamarin form for caching displaying correctly all the images?
thanks
making FFImage.Loading working on Android with no success
android cell
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ffimage="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:local="clr-namespace:CTSApp.Utility"
x:Class="CTSApp.Celle.cella_volantino_android">
<ContentView.Content>
<ScrollView>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
<local:PinchToZoomContainer>
<local:PinchToZoomContainer.Content>
<Image Source="{Binding url}" HorizontalOptions = "FillAndExpand"
VerticalOptions = "FillAndExpand" />
</local:PinchToZoomContainer.Content>
</local:PinchToZoomContainer>
</StackLayout>
</ScrollView>
</ContentView.Content>
</ContentView>
iOS cell
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ffimage="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:fftransf="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
xmlns:local="clr-namespace:CTSApp.Utility" x:Class="CTSApp.Celle.cella_volantino">
<ContentView.Content>
<ScrollView>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
<local:PinchToZoomContainer>
<local:PinchToZoomContainer.Content>
<ffimage:CachedImage Grid.RowSpan="2" Aspect="AspectFill"
Source="{Binding url}"
DownsampleToViewSize="false"
LoadingPlaceholder="placeholder.png"
ErrorPlaceholder="placeholder.png"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<ffimage:CachedImage.CacheDuration>
<x:TimeSpan>0,0,15,0</x:TimeSpan>
</ffimage:CachedImage.CacheDuration>
</ffimage:CachedImage>
</local:PinchToZoomContainer.Content>
</local:PinchToZoomContainer>
</StackLayout>
</ScrollView>
</ContentView.Content>
</ContentView>
thanks for help.
EDIT
Here is my main activity:
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Plugin.FirebasePushNotification;
using Firebase;
using Plugin.CurrentActivity;
using Plugin.Permissions;
using Xamarin;
using Xamarin.Forms;
using Android.Content.Res;
using SegmentedControl.FormsPlugin.Android;
using ZXing.Mobile;
namespace CTSApp.Droid
{
[Activity(Label = "CTSApp", Icon = "#drawable/ic_launcher", Theme = "#style/MyTheme.Splash", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(bundle);
global::Xamarin.Forms.Forms.Init(this, bundle);
MobileBarcodeScanner.Initialize(Application);
Rg.Plugins.Popup.Popup.Init(this, bundle);
ZXing.Net.Mobile.Forms.Android.Platform.Init();
FFImageLoading.Forms.Droid.CachedImageRenderer.Init(enableFastRenderer: true);
Plugin.CurrentActivity.CrossCurrentActivity.Current.Activity = this;
CrossCurrentActivity.Current.Init(this, bundle);
SegmentedControlRenderer.Init();
FirebasePushNotificationManager.ProcessIntent(Intent);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
Plugin.Permissions.PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
global::ZXing.Net.Mobile.Forms.Android.PermissionsHandler.OnRequestPermissionsResult (requestCode, permissions, grantResults);
}
}
}
FFImageLoader version 2.4.3.840
Xamarin form version 2.50
EDIT 2
Maybe I've found the problem, here is the new definitive cell I'm using
<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:ffimage="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:local="clr-namespace:CTSApp.Utility"
x:Class="CTSApp.Celle.cella_volantino_android">
<ContentView.Content>
<ScrollView>
<StackLayout HorizontalOptions="FillAndExpand" VerticalOptions="CenterAndExpand">
<local:PinchToZoomContainer>
<local:PinchToZoomContainer.Content>
<Image Source="{Binding url}" HorizontalOptions = "FillAndExpand"
VerticalOptions = "FillAndExpand" >
<Image.Source>
<UriImageSource Uri="{Binding url}"
CacheValidity="14"
CachingEnabled="true"/>
</Image.Source>
</Image>
</local:PinchToZoomContainer.Content>
</local:PinchToZoomContainer>
</StackLayout>
</ScrollView>
</ContentView.Content>
</ContentView>
Now I'm using the standard image with caching , now on iOS everything works fine , on android I'm getting error from some pages
ImageLoaderSourceHandler: Could not retrieve image or image data was invalid: Uri:
that obviously does not load, I've followed the tutorial here
https://doumer.me/resolve-image-loading-error-in-xamarin-forms/
Still no luck, but if I turn the phone horizontally the image load correctly, I really have no clue
video here:
https://streamable.com/rk1rv
Here is a sample with CarouselView to show image.All can work in IOS and Android.If want to use ffimage:CachedImage ,replacing Image with it.
Here is Xaml code:
<StackLayout>
<CarouselView x:Name="carousel" ItemsSource="{Binding uris}">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image
x:Name="PlantPicture"
Source="{Binding uri}"
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="150"
HeightRequest="150">
</Image>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
</StackLayout>
Model code :
public class FloraData
{
public class StringData
{
public string uri { get; set; }
}
public List<StringData> uris { get; set; }
public FloraData()
{
uris = new List<StringData>() { new StringData() { uri = "https://static.inaturalist.org/photos/504134/medium.jpg?1379628103" },
new StringData() { uri = "https://static.inaturalist.org/photos/8784478/small.jpg?1499006293" },
new StringData() { uri = "https://api.idigbio.org/v2/media/23cbb9eb2750e80848ac95b5d2919323?size=thumbnail" },
new StringData() { uri = "https://api.idigbio.org/v2/media/c085496285be91ace0768eb517cc704b?size=thumbnail" },
new StringData() { uri = "http://swbiodiversity.org/imglib/arizona/IND/IND-0049/IND-0049216_1491615930_tn.jpg" }};
}
}
Finally , ContentPage.cs BindingContext :
FloraData floraData = new FloraData();
carousel.BindingContext = floraData;
Related
I'm working on a Xamarin.Form App (Android and iOs) which need to get AAID and IDFA.
I started with Android part, I implemented AdvertisingIdClient.GetAdvertisingIdInfo but this function return Timeout error (about after 10s)
I use DependencyService from Form to get AAID from Android project and I compile with Android 11.0
I followed internet examples to achieve it but I'm quite sure I missed something or did something wrong, but what?
What I did :
Added nuget Xamarin.GooglePlayServices.Ads (120.3.0.3) and Xamarin.GooglePlayServices.Basement (117.6.0.4), should be latest compliant with Android 11
Created Interface for dependency service and Created cs in Android project
In Form I call my Dependencyservice function using Task.Run to run i in background (not sure it's the rigth way, but function run, otherwise function raise an error)
IDeviceAdIdentifier service = DependencyService.Get<IDeviceAdIdentifier>();
var tadid = Task.Run(() =>
{
var t = service.GetAdvertisingIdentifier();
t.Wait();
return t.Result;
});
tadid.Wait();
Idfa = tadid.Result;
In Android I save Context from MainActivity
In Android Service I have :
[assembly: Dependency(typeof(TestAdId.Droid.Services.DeviceAdIdentifier))]
namespace TestAdId.Droid.Services
{
public class DeviceAdIdentifier : TestAdId.Services.IDeviceAdIdentifier
{
public async Task<string> GetAdvertisingIdentifier()
{
if (MainActivity.Context == null) return "";
string id = "";
try
{
AdvertisingIdClient.SetShouldSkipGmsCoreVersionCheck(true);
var adinfo = AdvertisingIdClient.GetAdvertisingIdInfo(MainActivity.Instance); // Also tested with MainActivity.Context which is Application context saved during init
if (adinfo != null)
return adinfo.Id;
}
catch (IOException ioerr)
{
return ioerr.Message;
}
catch (Exception err)
{
return err.Message;
}
return "";
}
}
}
In my manifest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.testadid" android:installLocation="auto">
<uses-sdk android:minSdkVersion="25" android:targetSdkVersion="30" />
<application android:label="TestAdId.Android" android:theme="#style/MainTheme" android:icon="#drawable/xamarin_logo">
<meta-data android:name="com.google.android.gms.ads.AD_MANAGER_APP" android:value="true" />
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
The error raised on my Samsung Galaxy A71 is :
Message : java.util.concurrent.TimeoutException: Timed out waiting for the service connection
StackTrace :
at Java.Interop.JniPeerMembers+JniStaticMethods.InvokeObjectMethod (System.String encodedMember, Java.Interop.JniArgumentValue* parameters) [0x00018] in <1921523bc22e407fa9a0855bdae29335>:0
at Google.Ads.Identifier.AdvertisingIdClient.GetAdvertisingIdInfo (Android.Content.Context context) [0x00027] in /Users/runner/work/1/s/generated/com.google.android.gms.play-services-ads-identifier/obj/Release/monoandroid90/generated/src/Google.Ads.Identifier.AdvertisingIdClient.cs:171
at TestAdId.Droid.Services.DeviceAdIdentifier.GetAdvertisingIdentifier () [0x00032] in C:\Working\Digital\Sources\TestAdId\TestAdId\TestAdId.Android\Services\DeviceAdIdentifier.cs:30
--- End of managed Java.IO.IOException stack trace ---
java.io.IOException: java.util.concurrent.TimeoutException: Timed out waiting for the service connection
at com.google.android.gms.ads.identifier.AdvertisingIdClient.zzb(com.google.android.gms:play-services-ads-identifier##17.0.1:16)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.getAdvertisingIdInfo(com.google.android.gms:play-services-ads-identifier##17.0.1:3)
Caused by: java.util.concurrent.TimeoutException: Timed out waiting for the service connection
at com.google.android.gms.common.BlockingServiceConnection.getServiceWithTimeout(com.google.android.gms:play-services-basement##17.6.0:4)
at com.google.android.gms.ads.identifier.AdvertisingIdClient.zzb(com.google.android.gms:play-services-ads-identifier##17.0.1:14)
... 1 more
I tested an application to retrieve AAID and it works on my phone.
So if someone can help me it will be great. Tell me if you need more information/code
Thanks
Hervé
It's just a POC so nothing really special in MainActivity. I created a standard xamarin.Forms project and put my code in about page in a button
Android MainActivity.cs
using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.OS;
using Android.Content;
namespace TestAdId.Droid
{
[Activity(Label = "TestAdId", Icon = "#mipmap/icon", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation | ConfigChanges.UiMode | ConfigChanges.ScreenLayout | ConfigChanges.SmallestScreenSize )]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
public static Context Context =null;
public static MainActivity Instance = null;
protected override void OnCreate(Bundle savedInstanceState)
{
Instance = this;
base.OnCreate(savedInstanceState);
Context = Android.App.Application.Context;
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
The About Screen 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="TestAdId.Views.AboutPage"
xmlns:vm="clr-namespace:TestAdId.ViewModels"
Title="{Binding Title}">
<ContentPage.BindingContext>
<vm:AboutViewModel />
</ContentPage.BindingContext>
<ContentPage.Resources>
<ResourceDictionary>
<Color x:Key="Accent">#96d1ff</Color>
</ResourceDictionary>
</ContentPage.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackLayout BackgroundColor="{StaticResource Accent}" VerticalOptions="FillAndExpand" HorizontalOptions="Fill">
<StackLayout Orientation="Horizontal" HorizontalOptions="Center" VerticalOptions="Center">
<ContentView Padding="0,40,0,40" VerticalOptions="FillAndExpand">
<Image Source="xamarin_logo.png" VerticalOptions="Center" HeightRequest="64" />
</ContentView>
</StackLayout>
</StackLayout>
<ScrollView Grid.Row="1">
<StackLayout Orientation="Vertical" Padding="30,24,30,24" Spacing="10">
<Label Text="Start developing now" FontSize="Title"/>
<Label Text="Make changes to your XAML file and save to see your UI update in the running app with XAML Hot Reload. Give it a try!" FontSize="16" Padding="0,0,0,0"/>
<Label FontSize="16" Padding="0,24,0,0">
<Label.FormattedText>
<FormattedString>
<FormattedString.Spans>
<Span Text="Learn more at "/>
<Span Text="https://aka.ms/xamarin-quickstart" FontAttributes="Bold"/>
</FormattedString.Spans>
</FormattedString>
</Label.FormattedText>
</Label>
<Label x:Name="IdfaLabel" Text="Unknown" TextColor="Black" FontSize="16" ></Label>
<Button Margin="0,10,0,0" Text="Get IDFA"
Clicked="Button_Clicked"
BackgroundColor="{StaticResource Primary}"
TextColor="White" />
</StackLayout>
</ScrollView>
</Grid>
</ContentPage>
The About Form Code
using System;
using System.ComponentModel;
using System.Threading.Tasks;
using TestAdId.Services;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using System.Net;
namespace TestAdId.Views
{
public partial class AboutPage : ContentPage
{
public string Idfa = "";
public AboutPage()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
IdfaLabel.Text = "Getting IDFA...";
IDeviceAdIdentifier service = DependencyService.Get<IDeviceAdIdentifier>();
var tadid = Task.Run(() =>
{
var t = service.GetAdvertisingIdentifier();
t.Wait();
return t.Result;
});
tadid.Wait();
Idfa = tadid.Result;
IdfaLabel.Text = Idfa;
}
}
}```
Tell me if you need another thing. This is a really simple sample just to try to making AAID working
Thanks
Regards
Hervé
I've been trying to record a video from Xamarin CommunityToolkit.
When the app it's in portraid mode video it's saved like it's in landscape mode and it's rotated at 90.
I have seen that many people using images can rotate them 90 degrees by controlling the orientation of the phone. But how can I do this with videos?
This is Camera 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="MYAPP.Views.CameraPage"
xmlns:vm="clr-MYAPP.ViewModels"
xmlns:xct="http://xamarin.com/schemas/2020/toolkit"
xmlns:local="clr-namespace:MYAPP.Views;assembly=CustomView"
Title="{Binding Title}">
<AbsoluteLayout>
<StackLayout Orientation="Vertical" Spacing="0" AbsoluteLayout.LayoutFlags="All"
AbsoluteLayout.LayoutBounds="0,0,1,1">
<local:CameraPreview Camera="Rear"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
<xct:CameraView
Grid.Column="0"
x:Name="cameraView"
CaptureMode="Photo"
FlashMode="Off"
MediaCaptured="CameraView_MediaCaptured"
OnAvailable="CameraView_OnAvailable"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand" />
</StackLayout>
<Button
HorizontalOptions="CenterAndExpand"
VerticalOptions="End"
WidthRequest="500"
HeightRequest="70"
CornerRadius="15"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.5,1,AutoSize,AutoSize"
Margin="0, 0, 0, 30"
x:Name="doCameraThings"
Clicked="DoCameraThings_Clicked"
IsEnabled="False"
Text="Registra" />
</AbsoluteLayout>
</ContentPage>
This is CameraContentPage:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Xamarin.Essentials;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Xamarin.Forms.PlatformConfiguration;
using MYAPP.Services;
using Xamarin.CommunityToolkit.UI.Views;
using Xamarin.CommunityToolkit.Core;
namespace MYAPP.Views
{
public partial class CameraPage : ContentPage
{
public CameraPage()
{
InitializeComponent();
Title = "Camera";
cameraView.CaptureMode = CameraCaptureMode.Video;
cameraView.VideoStabilization = true;
}
void DoCameraThings_Clicked(object sender, EventArgs e)
{
cameraView.Shutter();
doCameraThings.Text = cameraView.CaptureMode == CameraCaptureMode.Video
? "Stop Recording"
: "Snap Picture";
}
void CameraView_OnAvailable(object sender, bool e)
{
doCameraThings.IsEnabled = e;
}
void CameraView_MediaCaptured(object sender, MediaCapturedEventArgs e)
{
switch (cameraView.CaptureMode)
{
default:
case CameraCaptureMode.Default:
case CameraCaptureMode.Photo:
break;
case CameraCaptureMode.Video:
FileMediaSource file = e.Video.File;
DependencyService.Get<IStorage>().exportFileMediaSource(file, "asd.mp4");
doCameraThings.Text = "Registra";
DependencyService.Get<IToast>().ShortAlert("Video salvato");
break;
}
}
}
}
I'm using Xamarin.CommunityToolkit ver 1.2.0. How can rotate video when saved ?
MediaCapturedEventArgs Rotarion property it's readonly and return 0.
API Level 29
I have a webview in one of my page and I want to add a stacklayout from the top then the webview. But Webview take whole screen and the stacklayout never get shown. I want to hide default navigation bar and create my own one. I still couldn't test for the apple side
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns:other="clr-namespace:CustApp.CusApp.Dushan.Other"
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"
EnableBackButtonOverride="True"
x:Class="CustApp.Views.GeneralPayments.MotorPayments.hnb.HNBmotorPayment">
<ContentPage.Content>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackLayout Grid.Row="0" VerticalOptions="Start" HorizontalOptions="FillAndExpand" Orientation="Horizontal" Padding="10,5,10,5">
<Image HorizontalOptions="StartAndExpand" Source="pdfDown.png"/>
<Label HorizontalOptions="CenterAndExpand" Text="ALL"/>
<Image HorizontalOptions="EndAndExpand" Source="pdfDown.png"/>
</StackLayout>
<WebView Grid.Row="1" x:Name="webView"
HorizontalOptions="CenterAndExpand"
Navigating="webView_Navigating"
Navigated="MywebView_Navigated"/>
</Grid>
</ContentPage.Content>
</ContentPage>
Code behind
protected override void OnAppearing()
{
base.OnAppearing();
NavigationPage.SetHasNavigationBar(this, false);
if (isFirstRun)
{
jsonOutput = JsonConvert.SerializeObject(payData);
//var htmlSource = new HtmlWebViewSource();
var urlSource = new UrlWebViewSource();
string url = DependencyService.Get<IBaseUrl>().Get();
TempUrl = Path.Combine(url, "xamarinhtmlmotor.html");
urlSource.Url = TempUrl;
webView.Source = urlSource;
isFirstRun = false;
Content = webView;
}
}
The cause is you set the Content = webView in code behind which means the the whole content is webview and those code in the Xaml will be overwritten.
Solution:
Remove Content = webView; and try again.
I am working on a Xamarin.Forms (Portable) using Visual Studio 2015.
The application allows me to retrieve information from a Database and display it.
I am able to display all the created records in a ListView on UWP. However, on Android they are not all showing up.
From my Menu Page, you can clearly see the big difference in terms of UI size. I am curious to know why this is happening on the Android platform.
Below are some of the relevant code. If you need to see more, please let me know.
MenuPage.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="XamarinFormsDemo.Views.MenuPage"
BackgroundImage="bg3.jpg">
<StackLayout>
<StackLayout Orientation="Vertical"
Padding="30"
HeightRequest="30"
BackgroundColor="#24e97d">
<Image Source="ebmspersonnellogo1.png"
HeightRequest="40"/>
</StackLayout>
<StackLayout Orientation="Vertical"
VerticalOptions="Center"
Padding="45,60,45,60">
<Image x:Name="sales"
Source="salesicon.png">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="SalesTapGestureRecognizer_OnTapped"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<Image x:Name="personnel"
Source="personnelicon.png">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="PersonnelTapGestureRecognizer_OnTapped"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<Image x:Name="crm"
Source="crmicon.png">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="CRMTapGestureRecognizer_OnTapped"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<Image x:Name="asset"
Source="asseticon.png">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="AssetTapGestureRecognizer_OnTapped"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<Image x:Name="receivables"
Source="receivables.png">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="ReceivablesTapGestureRecognizer_OnTapped"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<Image x:Name="prapprovals"
Source="prapprovals.png">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="ApprovalsTapGestureRecognizer_OnTapped"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
<StackLayout Orientation="Vertical"
Padding="30,10,30,10"
HeightRequest="20"
BackgroundColor="#24e97d"
VerticalOptions="Center"
Opacity="0.5">
<Label Text="© Copyright 2015 smesoft.com.ph All Rights Reserved "
HorizontalTextAlignment="Center"
VerticalOptions="Center"
HorizontalOptions="Center" />
</StackLayout>
</StackLayout>
</ContentPage>
MenuPage.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
namespace XamarinFormsDemo.Views
{
public partial class MenuPage : ContentPage
{
public MenuPage()
{
InitializeComponent();
NavigationPage.SetHasNavigationBar(this, false);
}
private async void NavigateButton_OnClicked(object sender, EventArgs e)
{
await Navigation.PushAsync(new EmployeeRecordsPage());
}
private async void SalesTapGestureRecognizer_OnTapped(Object sender, EventArgs e)
{
await sales.ScaleTo(0.95, 80, Easing.CubicOut);
await sales.ScaleTo(1, 80, Easing.CubicIn);
await Navigation.PushModalAsync(new SalesAndExpensePage());
}
private async void PersonnelTapGestureRecognizer_OnTapped(Object sender, EventArgs e)
{
await personnel.ScaleTo(0.90, 75, Easing.CubicOut);
await personnel.ScaleTo(1, 75, Easing.CubicIn);
await Navigation.PushModalAsync(new PersonnelPage());
}
private async void CRMTapGestureRecognizer_OnTapped(Object sender, EventArgs e)
{
await crm.ScaleTo(0.90, 75, Easing.CubicOut);
await crm.ScaleTo(1, 75, Easing.CubicIn);
await Navigation.PushModalAsync(new CRMPage());
}
private async void AssetTapGestureRecognizer_OnTapped(Object sender, EventArgs e)
{
await asset.ScaleTo(0.90, 75, Easing.CubicOut);
await asset.ScaleTo(1, 75, Easing.CubicIn);
await Navigation.PushModalAsync(new AssetManagementPage());
}
private async void ReceivablesTapGestureRecognizer_OnTapped(Object sender, EventArgs e)
{
await receivables.ScaleTo(0.90, 75, Easing.CubicOut);
await receivables.ScaleTo(1, 75, Easing.CubicIn);
await Navigation.PushModalAsync(new ReceivablesAndPayablesPage());
}
private async void ApprovalsTapGestureRecognizer_OnTapped(Object sender, EventArgs e)
{
await prapprovals.ScaleTo(0.90, 75, Easing.CubicOut);
await prapprovals.ScaleTo(1, 75, Easing.CubicIn);
await Navigation.PushModalAsync(new ApprovalsPage());
}
}
}
Here's a screen shot of UWP and Android. First image is UWP, second image is Android.
First of all. Your view is awfully nested, which can lead to performance problems.
Second of all. You are saying you are using a ListView. However, I don't see it anywhere in your XAML. There you are just using a StackLayout and stacking views below each other.
This means that any item that cannot fit within the screen will not be displayed at all. Consider rewriting your UI and use a ListView instead. Your items are very similar to each other and only title, image and click handler differ from each other. Using a ListView could also eliminate repeating yourself as you do currently with all those tap handlers, and you could limit yourself to only have one.
You could have something like this:
public class MenuItemViewModel
{
public string Name { get; set; }
public string ImageUrl { get; set; }
}
Then in your ViewModel for the page:
public List<MenuItemViewModel> MenuItems { get; } = new List<MenuItemViewModel>();
MenuItems.Add(new MenuItemViewModel {
Name = "Sales and Expense",
ImageUrl = "salesicon.png"
});
MenuItems.Add(new MenuItemViewModel {
Name = "Personnel",
ImageUrl = "personnelicon.png"
});
...
Then in your XAML something like this:
<ListView x:Name="MenuList">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Padding="15,0">
<Label Text="{Binding Name}" />
<Image Source="{Binding ImageUrl}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Then set ItemsSource of the ListView to your MenuItems from your ViewModel.
You can get the selected item by subscribing to ItemSelected on the ListView:
MenuList.ItemSelected += ItemSelected;
private async void ItemSelected(object sender, ItemTappedEventArgs e)
{
var menuItem = e.Item as MenuItemViewModel;
if (menuItem == null) return;
Page nextPage = null;
switch(menuItem.Name)
{
case "Sales and Expense":
nextPage = new SalesAndExpensePage();
break;
case "Personnel":
nextPage = new PersonnelPage();
break;
}
await Navigation.PushModalAsync(nextPage);
}
why isn't the WebView showing ? I have tried FillAndExpand and CenterAndExpand , but it still not working!
<?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:views="clr-namespace:MyApp.Views;assembly=MyApp"
x:Class="MyApp.Pages.Main">
<StackLayout>
<StackLayout Orientation="Horizontal" VerticalOptions="Start">
<!-- top controls -->
</StackLayout>
<StackLayout x:Name="WebViewLayout" VerticalOptions="CenterAndExpand">
<WebView Source="https://www.google.com/" VerticalOptions="CenterAndExpand" HorizontalOptions="FillAndExpand"/>
</StackLayout>
<StackLayout Orientation="Horizontal" VerticalOptions="End">
<views:AdMobView WidthRequest="400" HeightRequest="50" />
</StackLayout>
</StackLayout>
</ContentPage>
Change the Vertical Options of the StackLayout (which holds the WebView) from CenterAndExpand to FillAndExpand and the WebView itself.
I hope this helps. :)
<StackLayout x:Name="WebViewLayout" VerticalOptions="FillAndExpand">
<WebView Source="https://www.google.com/" VerticalOptions = "FillAndExpand"/>
</StackLayout>
I would suggest taking the WebView out of the parent StackLayout and the change the outer most StackLayout to a Grid.
That being said, I think that might help solve the issue without doing that:
public override void OnAppearing() {
SizeChanged += (sender, e) => {
WebViewItem.WidthRequest = Width;
WebViewItem.HeightRequest = 200; //Or what ever
}
OnSizeChanged(null, null); //Make it run at least once
}
I can't say exactly why but setting the VerticalOptions on the stack layout seemed to solve it for me. The following results in the web view being drawn:
var webView = new WebView();
webView.Source = "https://www.xamarin.com";
webView.MinimumWidthRequest = 200;
webView.MinimumHeightRequest = 200;
webView.HorizontalOptions = LayoutOptions.FillAndExpand;
webView.VerticalOptions = LayoutOptions.FillAndExpand;
var stackLayout = new StackLayout;
this.Content = stackLayout;
stackLayout.Children.Add(webView);
stackLayout.HorizontalOptions = LayoutOptions.FillAndExpand;
stackLayout.VerticalOptions = LayoutOptions.FillAndExpand;
I admit the layout behavior for StackLayout is pretty confusing.