I have a problem about some Gesture Recognizer into my Xamarin Forms project.
I was working to set three Image into a grid layer to see a viewfinder with Zxing Forms library to go into specific page and manage the flash camera device.
After I compiled and build my project, into Android device works perfectly, besided Ios that when I touch an image of them they didn't work not at all. I don't make any mistake to write the code.
Tap recognizer for example are wrote like these:
var settingsGestureRecognizer = new TapGestureRecognizer();
settingsGestureRecognizer.NumberOfTapsRequired = 1;
settingsGestureRecognizer.Tapped += async(s, e) =>
{
// handle the tap
NavigationPage nav = new NavigationPage(new SettingsPage());
await Navigation.PushModalAsync(nav);
};
And also, I add it into a button of a StackLayout like these
settingsImage = new Image
{
Source = ImageSource.FromFile(ConstantStringCollector.iconSettings),
Aspect = Aspect.AspectFit,
WidthRequest = 45,
HeightRequest = 45,
MinimumHeightRequest = 45,
MinimumWidthRequest = 45,
IsEnabled = true
};
settingsImage.GestureRecognizers.Add(settingsGestureRecognizer);
And then there is my personal layout
StackLayout stackLayoutBottom = new StackLayout
{
IsEnabled = true,
IsVisible = true,
IsClippedToBounds = true,
Padding = new Thickness(20, 20),
BackgroundColor = Color.Black,
Opacity = 0.8,
VerticalOptions = LayoutOptions.FillAndExpand,
Orientation = StackOrientation.Horizontal,
Children = {
infoImage,
flashImage,
settingsImage
}
};
Someone could help me?
if what you're trying to tap is visible, then I'd look at whether it is getting input, one option is to turn on InputTransparent for all the items except for the image and see if that lets your image recieve you input.
see: InputTransparent
Can you Try this
NavigationPage nav = new NavigationPage(new SettingsPage());
var settingsGestureRecognizer = new TapGestureRecognizer();
settingsGestureRecognizer.NumberOfTapsRequired = 1;
settingsGestureRecognizer.Tapped += async(s, e) =>
{
await Navigation.PushModalAsync(nav);
};
Related
I have made side menu using Rg.Plugins.Popups for Xamarin.
Everything is ok, but appearing animation doesn't work for some reason. As you can see menu just appears out of nowhere when it should look like disappearing animation.
FilterMenuCommand = new Command(() =>
{
var contentView = new ReportsPageFilterMenuContentView(this);
PopupNavigation.Instance.PushAsync(new ReportsPageFilterMenuPopupPage(contentView, this));
});
My PopupPage class:
public partial class ReportsPageFilterMenuPopupPage : PopupPage
{
public ReportsPageFilterMenuPopupPage(ReportsPageFilterMenuContentView contentView, ReportsViewModel viewModel)
{
InitializePageComponent(contentView, viewModel);
}
protected void InitializePageComponent(ReportsPageFilterMenuContentView contentView, ReportsViewModel viewModel, float width = 340.0f)
{
BindingContext = viewModel;
var moveAnimation = new MoveAnimation
{
DurationIn = 800,
DurationOut = 600,
EasingIn = Easing.SinIn,
EasingOut = Easing.SinOut,
HasBackgroundAnimation = true,
PositionIn = MoveAnimationOptions.Right,
PositionOut = MoveAnimationOptions.Right,
};
Animation = moveAnimation;
Resources["DecimalConverter"] = new DecimalConverter();
var frame = new Frame
{
WidthRequest = width,
CornerRadius = 0,
Padding = new Thickness(24, 20, 24, 20),
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.StartAndExpand,
BackgroundColor = Color.White
};
var gridRowDefinitions = new RowDefinitionCollection
{
new RowDefinition {Height = GridLength.Auto}, new RowDefinition {Height = GridLength.Star}
};
var grid = new Grid
{
RowDefinitions = gridRowDefinitions
};
var stackLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
BackgroundColor = Color.White
};
Grid.SetRow(stackLayout, 0);
Grid.SetRow(contentView, 1);
var label = new Label
{
FontFamily = "Roboto",
FontAttributes = FontAttributes.Bold,
FontSize = 20,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.Start,
Margin = new Thickness(1),
Text = MainResource.Filters
};
var imageButton = new ImageButton
{
Source = (FileImageSource)#"Assets/cross.png",
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.EndAndExpand,
Margin = new Thickness(1),
Command = viewModel.CloseCommand
};
stackLayout.Children.Add(label);
stackLayout.Children.Add(imageButton);
grid.Children.Add(stackLayout);
grid.Children.Add(contentView);
frame.Content = grid;
Content = frame;
}
}
Xamarin.Forms version: 4.6.0.800
Rg.Plugins.Popup version: 2.0.0.3
If you have any clue or idea where to even start fixing this problem, please, share it with me in comments.
I use your code and test on the following simulators
Android phone
Android tablet
iOS iPhone
iOS iPad
It works fine , the appearing and disappearing animation works as expected .
I would suggest you update Xamarin.Forms and Rg.Plugins.Popup version package to the latest .
I'm able to add a Vertical and Horizontal StackView programmatically to my main view but the view is not performing any stacking type layout.
Here is what I have so far:
// create vertical stack
var viewSize = new CGSize(200, 150);
var viewLocation = new CGPoint(0, 0);
var viewRectangle = new CGRect(viewLocation, viewSize);
var frame = new CGRect(0, 0, 200, 20);
var stackView = new NSStackView(viewRectangle);
var button1 = new NSButton(frame) {
Title = "Button 1"
};
var frame2 = new CGRect(0, 10, 200, 20);
var button2 = new NSButton(frame2) {
Title = "Button 2"
};
// show background to help see size and position
stackView.WantsLayer = true;
stackView.Layer.BackgroundColor = new CGColor(150, 0, 150, 1);
stackView.Orientation = NSUserInterfaceLayoutOrientation.Vertical;
stackView.Alignment = NSLayoutAttribute.Top;
stackView.Distribution = NSStackViewDistribution.Fill;
stackView.Spacing = 10;
stackView.AddSubview(button1);
stackView.AddSubview(button2);
stackView.NeedsLayout = true;
frame1.AddSubview(stackView);
Screenshot below.
The top view is a manually created Vertical Stack in Interface Builder. The bottom is the programmatic one created from the code above:
Update:
I found some example code in the Xamarin iOS documentation:
https://learn.microsoft.com/en-us/xamarin/ios/user-interface/controls/uistackview
There are some properties I can't find but some of it is working.
The main enabling difference is that you need to use the addArrangedSubViews() method instead of addSubviews() method.
stackView.AddArrangedSubview(button);
Visual Studio for Mac using Xamarin and C#
I have this code:
stackRecentList.Children.Add(
new Frame {
BackgroundColor = Color.White,
Margin = new Thickness(30, 20, 30, 0),
Padding = new Thickness(10),
CornerRadius = 5,
HasShadow = true
}
);
Basically I am adding a <Frame> to my stacklayout. I want to add a <Label> to that <Frame> there for it becomes the <StackLayout>'s grandchild. How do I do it in Xamarin Forms Android?
Generally speaking a StackLayout has only its Children to care of, and it's now every child task to organize its own children. Now your frame has to care of its children by itself.
A Frame has a unique property: Content.
Follow this snippet to create your UI in code behind:
Frame frame = new Frame
{
BackgroundColor = Color.White,
Margin = new Thickness(30, 20, 30, 0),
Padding = new Thickness(10),
CornerRadius = 5,
HasShadow = true
};
var sl = new StackLayout();
sl.Children.Add(new Label() { Text = "test" });
frame.Content = sl;
stackRecentList.Children.Add(
frame
);
I recommand you to add a StackLayout to Frame's Content(Do not add the Label to Frame's Content directly, If you have other controls want to add the Frame in later).
Here is running screenshot.
Am trying to do the front end XAML code in C#. When I try to bind the activity indicator with IsBusy Am not able to achieve it.
I want the activity indicator to pop up when the page is busy.
This post is to Show How can we achieve a basic screen with scrollview and a indicator in backend C# code.
the Layout assigned to the scroll Content is any basic layout which we design as per the requirement.
Here is my code sample:
#region render
scroll = new ScrollView
{
Content = layout
};
AbsoluteLayout.SetLayoutBounds(scroll, new Rectangle(0, 0, 1, 1));
AbsoluteLayout.SetLayoutFlags(scroll, AbsoluteLayoutFlags.All);
AbsoluteLayout screenMask = new AbsoluteLayout { BackgroundColor = Color.FromHex("#22000000") };
screenMask.BindingContext = this;
screenMask.SetBinding(IsVisibleProperty, "IsBusy", BindingMode.OneWay);
AbsoluteLayout.SetLayoutBounds(screenMask, new Rectangle(0.5, 0.5, 1, 1));
AbsoluteLayout.SetLayoutFlags(screenMask, AbsoluteLayoutFlags.All);
ActivityIndicator indicator = new ActivityIndicator { Color = Color.Black };
indicator.BindingContext = this;
indicator.SetBinding(IsVisibleProperty, "IsBusy",BindingMode.OneWay);
indicator.SetBinding(ActivityIndicator.IsRunningProperty, "IsBusy");
AbsoluteLayout.SetLayoutBounds(indicator, new Rectangle(0.5, 0.5, 0.1, 0.1));
AbsoluteLayout.SetLayoutFlags(indicator, AbsoluteLayoutFlags.All);
Content = new AbsoluteLayout
{
Children = { scroll, screenMask, indicator }
};
#endregion
Hope this helps many people.
I have something like this so far for my view:
public StackLayout OffersSlideViewCarouselChild(Offer offer)
{
Image productImage = new Image
{
Source = ImageSource.FromUri(new Uri(offer.Image.Replace("https://", "http://"))),
HeightRequest = 270,
WidthRequest = 270,
Aspect = Aspect.AspectFit
};
var topStackLayout = new StackLayout
{
Spacing = 0
};
topStackLayout.Children.Add(productImage);
StackLayout contentStackLayout = new StackLayout
{
Spacing = 0,
Padding = new Thickness(5, 10, 5, 10),
Orientation = StackOrientation.Vertical
};
var savedBtn = SavedButtonLayout(offer.IsSelected, offer.Id);
var redeemBtn = RedeemBtnLayout(offer.Id);
var timeRemainingLabel = TimeRemainingLayout(offer, offer.Id);
contentStackLayout.Children.Add(new UILabel(16) {
Text = offer.ProductName,
TextColor = ColorHelper.FromHex(CoreTheme.COLOR_OFFERCELL_PRODUCT_TEXT),
FontFamily = CoreTheme.FONT_FAMILY_DEFAULT_BOLD,
WidthRequest = DeviceDisplaySettings.defaultwidth,
VerticalTextAlignment = TextAlignment.Center
});
contentStackLayout.Children.Add(new UILabel(14)
{
Text = offer.Headline,
TextColor = ColorHelper.FromHex(CoreTheme.COLOR_OFFERCELL_PRODUCT_TEXT),
FontFamily = CoreTheme.FONT_FAMILY_DEFAULT_BOLD,
WidthRequest = DeviceDisplaySettings.defaultwidth,
VerticalTextAlignment = TextAlignment.Center
});
contentStackLayout.Children.Add(new UILabel(14) {
Text = offer.LongRewardsMessage,
TextColor = ColorHelper.FromHex(CoreTheme.COLOR_DEAL_PAGE_LONG_REWARD_MESSAGE_RED),
FontFamily = CoreTheme.FONT_FAMILY_DEFAULT_BOLD,
WidthRequest = DeviceDisplaySettings.defaultwidth,
VerticalTextAlignment = TextAlignment.Center
});
if (!string.IsNullOrEmpty(offer.PowerMessage)) {
var htmlText = string.Format("<html><body style='color:#9b9b9b'>{0}</body></html>", offer.PowerMessage.Replace(#"\", string.Empty));
var browser = new WebView() {
//HeightRequest = (DeviceDisplaySettings.defaultheight > 600) ? 500 : 400,
HeightRequest = 800,
Source = new HtmlWebViewSource() { Html = htmlText },
};
browser.Navigating += OnNavigating;
contentStackLayout.Children.Add(browser);
}
var nestedStackLayout = new StackLayout()
{
VerticalOptions = LayoutOptions.FillAndExpand
};
nestedStackLayout.Children.Add(topStackLayout);
nestedStackLayout.Children.Add(timeRemainingLabel);
nestedStackLayout.Children.Add(contentStackLayout);
var mainScrollView = new ScrollView()
{
Padding = new Thickness(0, 0, 0, 10),
VerticalOptions = LayoutOptions.FillAndExpand,
Orientation = ScrollOrientation.Vertical,
Content = nestedStackLayout
};
var mainStackLayout = new StackLayout()
{
Spacing = 5,
Padding = new Thickness(0, 0, 0, 0),
VerticalOptions = LayoutOptions.Fill,
HorizontalOptions = LayoutOptions.Fill,
Orientation = StackOrientation.Vertical,
Children = { savedBtn, mainScrollView, redeemBtn }
};
return mainStackLayout;
}
private StackLayout SavedButtonLayout(bool isSelected, int offerid)
{
int buttonsToShow = 2;
bool displaySaveButton = true;
if (IsPremisesOffer (offerid)) {
buttonsToShow = 3;
displaySaveButton = false;
}
btnShare = new UIFieldDefinition(_pageFieldDefinition.ShareButtonDefinition);
btnShare.Text = "SHARE";
btnShare.ClassId = offerid.ToString();
btnShare.WidthRequest = (DeviceDisplaySettings.defaultwidth / buttonsToShow) - 40;
btnShare.BackgroundColor = Color.FromRgb(167, 188, 33);
btnShare.VerticalContentAlignment = TextAlignment.Center;
btnShare.HandleClick(btnShare_Clicked);
btnSave = new UIFieldDefinition(_pageFieldDefinition.SaveButtonDefinition);
btnSave.Text = isSelected ? "UNSAVE" : "SAVE";
btnSave.ClassId = offerid.ToString();
btnSave.WidthRequest = (DeviceDisplaySettings.defaultwidth / buttonsToShow) - 40;
btnSave.BackgroundColor = Color.FromRgb(167, 188, 33);
btnSave.VerticalContentAlignment = TextAlignment.Center;
btnSave.HandleClick(btnSave_Clicked);
rl = new StackLayout {
Spacing = 10,
Orientation = StackOrientation.Horizontal,
BackgroundColor = Color.FromRgb(196, 221, 57),
Padding = new Thickness(40, 5, 5, 5),
WidthRequest = DeviceDisplaySettings.defaultwidth
};
rl.Children.Add(btnShare);
if (displaySaveButton) rl.Children.Add(btnSave);
return rl;
}
public UIFieldDefinition RedeemBtnLayout(int offerid)
{
int buttonsToShow = 1;
btnRedeem = new UIFieldDefinition(_pageFieldDefinition.RedeemButtonDefinition);
btnRedeem.Text = "REDEEM NOW";
btnRedeem.ClassId = offerid.ToString();
btnRedeem.WidthRequest = (DeviceDisplaySettings.defaultwidth / buttonsToShow) - 10;
// btnRedeem.HorizontalOptions = LayoutOptions.FillAndExpand;
// btnRedeem.VerticalOptions = LayoutOptions.EndAndExpand;
btnRedeem.HandleClick(btnRedeem_Clicked);
return btnRedeem;
}
However, I am noticing that the Redeem button does not even display on the view (It's supposed to be fixed on the bottom).
The scrollview works but the buttom is missing. Why?
Please let me know if you need further code details.
Moving here from comments above. There are two separate issues from what I can tell, and as far as I can tell, are unrelated:
The WebView, nested inside the ScrollView, is not big enough to fully display the content.
The button that is supposed to be at the bottom of the screen is not displaying.
For both of them, the answer is probably in how you are setting HeightRequest. There have been a lot of suggestions by myself and other commenters to change or get rid of some of the HeightRequest settings, and I'm not sure of the current state of your source code. So assuming those are still there:
For solving the WebView issue, read How can I add HTML to a Stacklayout inside a Scrollview in Xamarin forms?. This will let you figure out the right HeightRequest to use. The short answer is that depending on exactly what you want to happen, you may need a custom renderer. Note that the HeightRequest for the WebView will not affect any layout outside of the ScrollView.
For solving the issue of the button not appearing, get rid of the HeightRequest setting on the ScrollView, and the VerticalOptions on the StackLayout created in SavedButtonLayout.
I am assuming you did the experiment suggested above to make sure that the redeemBtn will render if placed before the ScrollView, and it does show up then. If not, you first need to fix that.
If you have "fixed" this by changing the HeightRequest then your real problem is the fixed pixel size of all your views and layouts, I recommend you DON'T use fixed pixel sizes for different screen resolution this will be a bigger problem later, What you can do is get the Screen size and do the math to fit all your elements of the view, one way to get the width and height of the screen is on the OnSizeChanged event of Pages (Like ContentPage), something like this:
SizeChanged += SizeChanged;
void SizeChanged (object sender, EventArgs e)
{
Layout.WidthRequest = Width * 0.3;
Layout.HeightRequest = Height * 0.35;
}
Your layout is pretty busy. A few things:
Set VerticalOptions to EndAndExpand for redeemBtn.
Set VerticalOptions to StartAndExpand for savedBtn.
Set VerticalOptions to Fill for mainScrollView.
Set VerticalOptions to FillAndExpand for mainRelLayout.
Set VerticalOptions and HorizontalOptions to Fill for
mainStackLayout.
I think that will get you to where you want to be.
The options that include "Expand" will grow the element to accommodate the desired height of its contents.