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
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'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;
I've created a rendered picker's to center center in the middle of the control but at the moment of entering the page, it shows the following error: System.ArgumentException.
I attach the code to see if you can help me.
In project new class...
using Xamarin.Forms;
namespace MaterialFUR
{
public class PickerCentrat : Picker
{
}
}
In Android ...
using MaterialFUR;
using MaterialFUR.Droid;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(PickerCentrat), typeof(RendererPicker))]
namespace MaterialFUR.Droid
{
public class RendererPicker : EntryRenderer
{
public RendererPicker(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Gravity = GravityFlags.CenterHorizontal;
}
}
}
}
In XAML page...
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MaterialFUR.AgafarMaterialPage"
xmlns:local="clr-namespace:MaterialFUR"
Title="Agafar Material">
<ContentPage.Content>
<StackLayout HorizontalOptions="Center" VerticalOptions="Center" Spacing="25">
<Button x:Name="btnScan" Clicked="btnScan_Clicked" BackgroundColor="Gray" TextColor="White" Text="Llegir codi de barres" FontSize="30" FontAttributes="Bold" BorderRadius="30"/>
<Entry x:Name="entCodi" TextColor="Black" FontSize="30" FontAttributes="Bold" Keyboard="Default" Placeholder="Codi" HorizontalTextAlignment="Center"/>
<Entry x:Name="entQtat" TextColor="Black" FontSize="30" FontAttributes="Bold" Keyboard="Numeric" Placeholder="Quantitat" HorizontalTextAlignment="Center"/>
<local:PickerCentrat x:Name="pckUbicacio" Title="Ubicació" TextColor="Black" FontSize="30" FontAttributes="Bold">
<Picker.Items>
<x:String>SATMOBIL-1</x:String>
<x:String>SATMOBIL-2</x:String>
<x:String>SATMOBIL-3</x:String>
<x:String>SATMOBIL-4</x:String>
<x:String>SATMOBIL-5</x:String>
<x:String>SATMOBIL-6</x:String>
<x:String>SATMOBIL-7</x:String>
<x:String>SATMOBIL-8</x:String>
<x:String>SATMOBIL-9</x:String>
<x:String>TALLER</x:String>
</Picker.Items>
</local:PickerCentrat>
<StackLayout Orientation="Horizontal" Margin="0,100">
<Button x:Name="btnConfirmar" Clicked="BtnConfirmar_Clicked" BackgroundColor="SteelBlue" TextColor="White" Text="Confirmar" FontSize="30" FontAttributes="Bold" BorderRadius="30"/>
<Button x:Name="btnCancelar" Clicked="BtnCancelar_Clicked" BackgroundColor="Gray" TextColor="White" Text="Cancelar" FontSize="30" FontAttributes="Bold" BorderRadius="30"/>
</StackLayout>
</StackLayout>
</ContentPage.Content>
Error displayed.
I appreciate your help, thanks!
Your class needs to Inherit from PickerRenderer
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
[assembly: ExportRenderer(typeof(PickerCentrat), typeof(RendererPicker))]
namespace MaterialFUR.Droid
{
public class RendererPicker : PickerRenderer
{
public RendererPicker(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Picker> e)
{
base.OnElementChanged(e);
if (Control != null)
{
Control.Gravity = GravityFlags.CenterHorizontal;
}
}
}
}
When in doubt about which class you need to Inherit from for your CustomRenderer, you can always check on the Xamarin.Forms source code here (for Android).
Hope this helps.
First time with cross-platform apps with xamarin, i'm working with xamarin forms in visual studio 2017 community.
I have a button with an image and text but the text needs to be below the image. currently the text is displaying to the left of the image, how can i do this?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
namespace AppUnap
{
public class PPrincipal : ContentPage
{
public PPrincipal()
{
Button btn1= new Button();
btn1.Image = "notas.png";
btn1.Text = "Calificaciones";
btn1.HorizontalOptions = LayoutOptions.CenterAndExpand;
Button btn2 = new Button();
btn2.Image = "notas.png";
btn2.Text = "Aula Virtual";
btn2.HorizontalOptions = LayoutOptions.CenterAndExpand;
Content = new StackLayout
{
Spacing = 0,
VerticalOptions = LayoutOptions.CenterAndExpand,
Children =
{
new StackLayout
{
Spacing = 0,
Orientation = StackOrientation.Horizontal,
Children =
{
btn1,
btn2,
}
}
}
};
}
}
}
You need to use ContentLayout on your button.
Here is the code I use in XAML:
<Button Command="{Binding MyCommand}" ContentLayout="Top,0" Text="mytext" Image="myimage.png" />
Top = Position of the Image
0 = spacing between image & text
You should find easily how to use the ContentLayout in C#
To get the above result I used a ImageButtom, because is possible adjust the image size. I made like this:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Label
Text="{Binding CountryId}"
TextColor="{DynamicResource PrimaryDarkColor}"
FontFamily="MontSerratBold"
Margin="0, 0, 0, 10"
VerticalOptions="End"
HorizontalTextAlignment="Center"
VerticalTextAlignment="End"/>
<ImageButton
Source="{Binding CountryUrl}"
HorizontalOptions="Center"
VerticalOptions="Start"
BackgroundColor="Transparent"
Padding="0, 10, 0, 30"
HeightRequest="90"
Command="{Binding OpenPickerPopUp}"/>
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);
}