Xamarin Images sometimes not downloaded inside ListView - c#

I have a ListView with two columns, the leftmost of which contains an <Image> like this:
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*" />
<ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
</Grid.RowDefinitions>
<AbsoluteLayout Grid.Column="0" Grid.Row="0">
<Image
HeightRequest="130"
Aspect="AspectFill"
Source="{Binding DynamicOfferImage}"
local:ImageBinding.URL="{Binding DynamicOfferURL}"
AbsoluteLayout.LayoutBounds="1,1,1,1"
AbsoluteLayout.LayoutFlags="All">
<Image.Aspect>
<OnPlatform x:TypeArguments="Aspect">
<On Platform="iOS">AspectFit</On>
<On Platform="Android">AspectFit</On>
</OnPlatform>
</Image.Aspect>
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnImageTapGestureRecognized"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
<StackLayout IsVisible="{Binding IsRedeemed}" Margin="20" AbsoluteLayout.LayoutBounds="1,1,1,1" AbsoluteLayout.LayoutFlags="All">
<ContentView Padding="3" BackgroundColor="#d9534f">
<Label Text="{loc:_ S=LoginIsRedeemed}" FontSize="Medium" TextColor="#ffffff" HorizontalOptions="Center"></Label>
</ContentView>
</StackLayout>
</AbsoluteLayout>
<StackLayout Grid.Column="1" Grid.Row="0">
<!-- Text here, irrelevant to question -->
</StackLayout>
</Grid>
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
The <Image>'s Source property is bound to a URL of a JPEG image hosted on Amazon S3. The problem is most of the time these images are downloaded fine, however sometimes one image, or even all images, won't download (or won't display?)
This issue doesn't go away until the user re-installs the app. Even restarting the app doesn't count, it has to be an actual re-installation.
Below is a mockup of what this ends up looking like in some scenarios:
Any help much appreciated!
NOTE: This is not a duplicate of Xamarin Forms ListView Images Sometimes Displays, Sometimes Doesn't (UWP), as that scenario described is different.

I ended up taking G.hakim's advice and decided to employ FFImageLoading (via NuGet package) for the images. It was pretty simple although I had to use a slightly older version for Xamarin.Android. Some weird linker error occurs with the latest version (2.4.4.859) and had to go back to 2.4.1. Either way it works really well and even adds a little animation to the images on Xamarin.iOS.
Here was my code before:
<Image
HeightRequest="130"
Aspect="AspectFill"
Source="{Binding ImageURL}"
local:ImageBinding.URL="{Binding LinkURL}"
AbsoluteLayout.LayoutBounds="1,1,1,1"
AbsoluteLayout.LayoutFlags="All">
<Image.Aspect>
<OnPlatform x:TypeArguments="Aspect">
<On Platform="iOS">AspectFit</On>
<On Platform="Android">AspectFit</On>
</OnPlatform>
</Image.Aspect>
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnImageTapGestureRecognized"
NumberOfTapsRequired="1" />
</Image.GestureRecognizers>
</Image>
In order to get FFImageLoading to work you have to add this to the root <ContentPage> element:
xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"
xmlns:fftransformations="clr-namespace:FFImageLoading.Transformations;assembly=FFImageLoading.Transformations"
Then I was able to do this:
<ffimageloading:CachedImage
AbsoluteLayout.LayoutBounds="1,1,1,1"
AbsoluteLayout.LayoutFlags="All"
HeightRequest="130"
DownsampleToViewSize="true"
Source="{Binding ImageURL}"
local:ViewBinding.URL="{Binding LinkURL}">
<ffimageloading:CachedImage.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnViewTapGestureRecognized"
NumberOfTapsRequired="1" />
</ffimageloading:CachedImage.GestureRecognizers>
</ffimageloading:CachedImage>
In order for it to work with my TapGestureRecognizer I changed the ((Image)sender) cast in the method to a ((View)sender) cast because the CachedImage class in FFImageLoading doesn't actually inherit from Image, it inherits from View. Something to keep in mind if you have gestures or even custom bindings.
Aside from that it is very plug-and-play and I'm very happy with the outcome.

Related

Button not clickable due to overlapping view

This might be an easy solution but for some reason I couldn't find the solution online.
I have two views. One view is a grid and the other is a button. The Grid View is showing different views (boxview, label, etc..)
But underneath it is a button view. But this view is not included in the Grid View. I cannot put it inside the Grid View because of reasons. I just wanted to know if there's a possibility for it to be clickable without moving the views or even if there's a view on top of it?
Here's how it looks like:
<?xml version="1.0" encoding="UTF-8" ?>
<ContentView
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="PlayUIArea.NotificationConfirmView">
<ContentView.Content>
<Grid BackgroundColor="Blue">
<BoxView
WidthRequest="100"
VerticalOptions="Fill"
HorizontalOptions="Start"
BackgroundColor="Black" />
<Button Text="Confirm"
OnClick="Button_Click"
VerticalOptions="Start"
HorizontalOptions="Center" />
<Grid BackgroundColor="Red" Margin="100,0,0,0" Padding="-100,0,0,0">
<Label Text="Label Here"
HorizontalOptions="Center"
VerticalOptions="Center" />
</Grid>
</Grid>
</ContentView.Content>
</ContentView>
Is there anyway to make this clickable?
I am a bit late but I think I found a solution to this.
<Grid>
<WebView Grid.Row ="1" Source="[insert random embedded youtube source]"/>
<RelativeLayout Grid.Row ="1" InputTransparent="True" CascadeInputTransparent="False">
<Button CornerRadius="0" Command="{Binding GoToVideoFullscreen}"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.8}"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.9}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=Constant, Constant=17}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=Constant, Constant=17}"/>
</RelativeLayout>
</Grid>
I had a similar problem, where I wanted to overlap a WebView with a custom button. But my RelativeLayout, which I used to place the button was eating all the inputs and the WebView could not be used anymore.
So I added InputTransparent="True" and CascadeInputTransparent="False" to the RelativeLayout. The InputTransparent="True" makes it invisible to inputs, the CascadeInputTransparent="False" prevents the InputTransparent value from inheriting to the children (in this case my button).
Documentation:
https://learn.microsoft.com/de-de/dotnet/api/xamarin.forms.visualelement.inputtransparent?view=xamarin-forms
https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.layout.cascadeinputtransparent?view=xamarin-forms
Agree with #G.Mich , you should put all of elements in one layout . For example you can put them in a StackLayout
<ContentPage.Content>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<Button Onclick="Button_Clicked" /> <!-- This isn't clickable -->
<Grid>
your code here
</Grid>
</StackLayout>
</ContentPage.Content>
place the button on top of the Grid by placing it after the Grid in the XAML
<ContentPage.Content>
<Grid>
My code here
</Grid>
<Button Onclick="Button_Clicked" /> <!-- This isn't clickable -->
</ContentPage.Content>

remove extra space in xamarin forms layout

Hi i'm trying to place 2 image in xamarin forms using stackLayout.But it adds some space at the top of the form.I Used Blank Project.
my code is
<StackLayout>
<Image Source="review.jpg"
BackgroundColor="Transparent"
WidthRequest="300"
HeightRequest="100"
VerticalOptions="Start" HorizontalOptions="FillAndExpand"
FlexLayout.Grow="1">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Navigate_review"/>
</Image.GestureRecognizers>
</Image>
<Image Source="upload.jpg"
BackgroundColor="Transparent"
WidthRequest="320"
HeightRequest="100"
VerticalOptions="Start" HorizontalOptions="FillAndExpand"
FlexLayout.Grow="1">
<Image.GestureRecognizers>
<TapGestureRecognizer Tapped="Navigate_upload"/>
</Image.GestureRecognizers>
</Image>
</StackLayout>
i am getting this output:
Output Image 1
Output Image 2
It adds some extra space at the top of the page. how to set the layout to remove this space?
The code you post does not have any issue.
I reckon your app is created with Tabbed template. If that is the case, the empty space at the top is actually the tab. As shown in this image.
If you create a Blank project (not Tabbed nor MasterDetails), it will not have the empty spaces at the top. As shown in this image.
You can use the Margin attribute to remove the excess space on top, bottom, right or left. Let's assume, if we using a table view and it produces the 20 pixel excess space on top of the display. So we can reduce that excess space by using
<TableView Margin="0,-20,0,0" >
<TableVie/>
-20 using for reduce the excess 20pix😀
I think the problem is you are testing on emulators.Real devices will not show this issue I hope.
StackLayout and Grid have default spacing of 6. On StackLayout you can set Spacing. For more details, you can refer to this Document
Try this snippet:
<StackLayout
Spacing="0">
<Image
Source="hintsicon"
BackgroundColor="Transparent"
WidthRequest="300"
HeightRequest="100"
Aspect="Fill"
VerticalOptions="Start"
HorizontalOptions="FillAndExpand">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="Navigate_review" />
</Image.GestureRecognizers>
</Image>
<Image
Source="hintsicon"
BackgroundColor="Transparent"
WidthRequest="320"
HeightRequest="100"
Aspect="Fill"
VerticalOptions="Start"
HorizontalOptions="FillAndExpand">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="Navigate_upload" />
</Image.GestureRecognizers>
</Image>
</StackLayout>
I think you are using like below in your App.xaml.cs page:
MainPage = new NavigationPage(new MainPage());

Xamarin Editor not showing keyboard in ListView

I am totally new to xamarin,
Following is my code :
<ListView x:Name="boxActivitiesList" ItemTapped="boxActivitiesList_ItemTapped" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Vertical" Padding="25" VerticalOptions="Start" HorizontalOptions="Start">
<Label Text="{Binding Box}" TextColor="BlueViolet" FontSize="16" FontAttributes="Bold" LineBreakMode="TailTruncation" />
<TableView IsVisible="{Binding IsVisible}" Intent="Settings" HasUnevenRows="True" BackgroundColor="White">
<TableRoot>
<TableSection>
<ViewCell>
<StackLayout Orientation="Horizontal" Padding="15,0">
<Label HorizontalOptions="Fill" Text="Remarks" VerticalOptions="Center" TextColor="Black"></Label>
<Editor x:Name="txtRemarks" HorizontalOptions="FillAndExpand"></Editor>
</StackLayout>
</ViewCell>
</TableSection>
</TableRoot>
</TableView>
<Button x:Name="btnSave" Text="Save" Clicked="btnSave_Clicked" CommandParameter="{Binding BoxId}" IsVisible="{Binding IsVisible}"></Button>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
When I click on Editor, Keyboard does not show. Can you please tell me what I am doing wrong.
I'm not sure why the Editor is not working in the Table, however i would reconsider this design and just use a Grid to realize a more complex layout inside your parent ViewCell.
Although there should be nothing wrong with the way you have it, it does seem to be overly complicating things with more nested controls when its not really needed. Ergo, the nested table should really just be a layout like Grid or StackPanel
Lastly, Xamarin.Forms can be a little fickle at the best of times with the various devices it supports. so its best to keep things as simple as possible

Xamarin Forms IOS "Entry" is uneditable

I am using Xamarin.Forms to build my app. In the Login Page, I have the following layout
<ScrollView>
<Grid
RowSpacing="{StaticResource MediumSpacing}"
ColumnSpacing="{StaticResource MediumSpacing}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Two stackLayouts-->
<!--StackLayout 1-->
<StackLayout Spacing="0" Padding="0">
<!--Three stacklouts here-->
<!--First-->
<StackLayout>
<StackLayout.Spacing>
<OnPlatform x:TypeArguments="x:Double" Android="12" iOS="30" WinPhone="12"/>
</StackLayout.Spacing>
<StackLayout.Padding>
<OnPlatform x:TypeArguments="Thickness" Android="32,24,32,24" iOS="16,24,16,24" WinPhone="32,24"/>
</StackLayout.Padding>
<imagecircle:CircleImage
HorizontalOptions="Center"
VerticalOptions="Center"
WidthRequest="95" HeightRequest="95"
BorderColor="{StaticResource Primary}"
Aspect="AspectFill"
x:Name="CircleImageAvatar"/>
<Label HorizontalTextAlignment="Center"
HorizontalOptions="FillAndExpand"
StyleId="LoginPageIdentifier"
LineBreakMode="WordWrap"
FontSize="Large"
TextColor="{DynamicResource DetailTextColor}"
Text="Single Sign On">
<Label.FontSize>
<OnPlatform x:TypeArguments="x:Double" Android="15" iOS="15" WinPhone="15"/>
</Label.FontSize>
</Label>
</StackLayout>
<!--Second Stack Layout-->
<StackLayout>
<StackLayout.Padding>
<OnPlatform x:TypeArguments="Thickness" Android="32,0" iOS="32,0" WinPhone="32,0"/>
</StackLayout.Padding>
<StackLayout.Spacing>
<OnPlatform x:TypeArguments="x:Double" Android="0" iOS="15" WinPhone="10"/>
</StackLayout.Spacing>
<toolkit:EntryLine
Text="{Binding Email}"
Keyboard="Email"
HorizontalOptions="FillAndExpand"
Placeholder="Email Address"
x:Name="EntryEmail"
StyleId="EmailTextField"
BorderColor="#ECECEC">
<toolkit:EntryLine.HorizontalTextAlignment>
<OnPlatform x:TypeArguments="TextAlignment" iOS="Center"/>
</toolkit:EntryLine.HorizontalTextAlignment>
</toolkit:EntryLine>
<toolkit:EntryLine
Text="{Binding NamespaceUri}"
HorizontalOptions="FillAndExpand"
HorizontalTextAlignment="Center"
Placeholder="Namespace"
StyleId="EmailTextField"
Keyboard="Text"
BorderColor="#ECECEC">
<toolkit:EntryLine.HorizontalTextAlignment>
<OnPlatform x:TypeArguments="TextAlignment" iOS="Center"/>
</toolkit:EntryLine.HorizontalTextAlignment>
</toolkit:EntryLine>
</StackLayout>
<!--Third Stack Layout-->
<StackLayout>
<StackLayout.Padding>
<OnPlatform x:TypeArguments="Thickness" Android="32,16,32,0" iOS="32,25,32,0" WinPhone="32,16,32,0"/>
</StackLayout.Padding>
<StackLayout.Spacing>
<OnPlatform x:TypeArguments="x:Double" Android="0" iOS="16" WinPhone="10"/>
</StackLayout.Spacing>
<Button
Text="Sign In"
Command="{Binding LoginCommandSso}"
HorizontalOptions="FillAndExpand"
StyleId="SignInButton"
TextColor="White"
BackgroundColor="{StaticResource Primary}">
<Button.FontAttributes>
<OnPlatform x:TypeArguments="FontAttributes" iOS="Bold"/>
</Button.FontAttributes>
</Button>
</StackLayout>
</StackLayout>
<!--StackLayout 2-->
<!--Contains activity indicator and Corresponding label-->
<AbsoluteLayout>
<StackLayout
Grid.Row="1"
Padding="16,0"
VerticalOptions="Center"
Orientation="Horizontal"
HorizontalOptions="Center"
AbsoluteLayout.LayoutFlags="PositionProportional"
AbsoluteLayout.LayoutBounds="0.5,0.5,-1,-1"
IsVisible="{Binding IsBusy}">
<ActivityIndicator IsRunning="{Binding IsBusy}">
<ActivityIndicator.Color>
<OnPlatform x:TypeArguments="Color" Android="{StaticResource Primary}"/>
</ActivityIndicator.Color>
</ActivityIndicator>
<Label Text="{Binding Message}" VerticalOptions="Center" HorizontalOptions="Center" />
</StackLayout>
</AbsoluteLayout>
<!--Stack Layout 3-->
</Grid>
</ScrollView>
When run on Android Emulator I can input text in "EntryLine" and everything seems to work fine.
However, when I am trying to run it on IOS simulator, the text becomes ineditable i.e. readonly. Basically on IOS simulator everything inside StackLayout is becoming "ReadOnly"
I also tried using forms "Entry" instead of FormsToolKit.EntryLine, but no result.
I am facing an issue in above code itself, adding just a "Entry" in xaml and testing on IOS simulator works fine.
Have already asked the same question on Xamarin Forums, but haven't found any answer.
EDIT 1 - Added the complete stack layout.
Using -
Visual Studio 2017, Windows 10, Xamarin - 2.3.4.247
FormsToolKit - 1.1.18 IOS - MacBook Air 10.3
Your <AbsoluteLayout> overlaps your content and catches all input events. You'll have to try setting its IsVisible Property to false (or the InputTransparent property to try). At least as long as the Activity Indicator is not running.
(If that is not working you might try to handle it with an effect (or a custom renderer) that sets input transparancy on iOS specifically)
(You might also consider not placing it inside the scroll view, since it would get scrolled away eventually)

How to add fontAwesome icon to toolbar menu

How can I add a icon(fontAwesome) to my toolbar item? Referring to this link, I managed to set a fontawesome to my label. But how do I do that for toolbar itrm?
My code:
ToolbarItem Save = new ToolbarItem();
Save.Text = FontAwesome.FAFloppyO;
Save.Order = ToolbarItemOrder.Primary;
I also tried adding icon attribute to my toolbarItem but doesn't work.
I have managed to achieve this out-of-box using Iconize library for Xamarin Forms. It is quite easy to set up.
Now, to save you extra hours of frustrations, you need to:
Use IconNavigationPage as parent instead of NavigationPage.
Use IconToolbarItem instead of ToolbarItem.
The Icon property should be set, not the Text property (i.e. Icon="fa-user")
Let me know if this solves your issue.
You can use NavigationPage.TitleView instead of Toolbar or Toolbar item.
All you have to do is just adding fontawesome libraries to each platform and than set font familiy property according of target platform.
<NavigationPage.TitleView>
<StackLayout Orientation="Horizontal">
<Button HorizontalOptions="EndAndExpand" Text="">
<Button.FontFamily>
<OnPlatform x:TypeArguments="x:String">
<On Platform="iOS" Value="Font Awesome 5 Free" />
<On Platform="Android" Value="fa-solid-900.ttf#fa-solid" />
</OnPlatform>
</Button.FontFamily>
</Button>
</StackLayout>
this is the one of the basic usage. For better usage you can create your own static resources and apply to button or what ever other items.
This is a code sample from one of my project:
<!-- Toolbar -->
<NavigationPage.TitleView>
<Grid HeightRequest="50" BackgroundColor="{StaticResource DarkBackgroundColor}" Margin="0" Padding="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
<ColumnDefinition Width="50"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- Title -->
<Label Text="Inventory" Style="{StaticResource TitleViewTitleLabel}"/>
<Button Grid.Column="1" Text=""
Style="{StaticResource FontAwesomeButtonRegularTitleViewButton}"
Command="{Binding SyncDataCommand}"/>
<Button Grid.Column="2" Text=""
Style="{StaticResource FontAwesomeButtonRegularTitleViewButton}"
Command="{Binding ShowFunctionalityCommand}"/>
<Button Grid.Column="3" Text=""
Style="{StaticResource FontAwesomeButtonRegularTitleViewButton}"
Command="{Binding AddNewInventoryCommand}"/>
</Grid>
</NavigationPage.TitleView>

Categories

Resources