xamarin.forms scrollview keyboard appears and button also scroll - c#

Hi i have a weird problem.
I defined few labels and textbox for data entry purpose using xamarin.forms.
I wrapped them into scroll view so that when keyboard appears, they should scroll.
It is working fine. The control which has focus scroll to top and the keyboard appears when it get focus. but i also have couple of buttons at the bottom of my form. Now, the problem is, whenever keyboard appears, my bottom buttons are also scrolled. which looks weird. As button are for submit or cancel, it should be stay there in bottom.
following is my code:
var firstNameLabel = new Label { HorizontalOptions = LayoutOptions.Fill };
firstNameLabel.Text = "First Name";
var firstName = new Entry() { HorizontalOptions = LayoutOptions.FillAndExpand };
firstName.SetBinding (Entry.TextProperty,MyViewModel.FirstNamePropertyName);
var lastNameLabel = new Label { HorizontalOptions = LayoutOptions.Fill};
lastNameLabel.Text = "Last Name";
var lastName = new Entry() { HorizontalOptions = LayoutOptions.FillAndExpand };
lastName.SetBinding (Entry.TextProperty, MyViewModel.LastNamePropertyName);
---- other fields
Button btnSubmit = new Button
{
HorizontalOptions = LayoutOptions.Fill,
BackgroundColor = Color.FromHex("#22498a"),
TextColor = Color.White,
Text = "Submit"
};
var cancelButton = new Button { Text = Cancel", BackgroundColor = Color.FromHex("0d9c00"), TextColor = Color.White };
contactUsButton.Clicked += (object sender, EventArgs e) =>
{
// cancel operation
};
var cotrolStakeLayout = new StackLayout () {
Padding = new Thickness(Device.OnPlatform(5, 5, 5),0 , Device.OnPlatform(5, 5, 5), 0), //new Thickness(5,0,5,0),
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.Fill,
Orientation = StackOrientation.Vertical,
Children = { firstNameLabel, firstName, lastNameLabel, lastName, -- and other fields}
};
var scrollableContentLayout = new ScrollView (){
Content = cotrolStakeLayout,
Orientation = ScrollOrientation.Vertical,
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill
};
var buttonLayout = new StackLayout (){
Padding = new Thickness(Device.OnPlatform(5, 5, 5),0 , Device.OnPlatform(5, 5, 5), 0), //new Thickness(5,0,5,0),
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
Orientation = StackOrientation.Vertical,
Children= { btnSubmit , cancelButton }
};
var nameLayout = new StackLayout()
{
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
Orientation = StackOrientation.Vertical,
Children = {scrollableContentLayout,buttonLayout}
};
return nameLayout;
Any ideas what is wrong with it?

You have to change your layout to reach your target:
- Define a "Main-StackLayout"
- Create a "Button-StackLayout" for your Buttons (that should stay on top)
- Add your Buttons to the "Button-StackLayout"
- Add the "button-StackLayout to the "Main-StackLayout"
- Add the ScrollView to to "Main-StackLayout"
- Set content of the page to the "Main-StackLayout"
This should work: buttons stays on top, where (only) the ScrollView can be scrolled.

Related

Microsoft Android Emulator Shows Blank Form When Debugging

I am trying to run a Xamarin form called 'FormsApp' on my andriod emulator in visual studio. The Emulator boots up fine and renders. However, after clicking "start debugging" the form deploys to the emulator but only shows a blank white from.
https://i.imgur.com/AbkqDyJ.png
https://i.imgur.com/VttMKfh.png
I have tried playing around with my OpenGL ES Renderer settings and OpenGL ES API level settings as well. Switching to swiftshader/ANGLE D3D9/ and Compatibility (OpenGL ES 1.1/2.0) did not work. It's Still a blank white Screen when debugging.
namespace FormsApp
{
class ContentPageExample : ContentPage
{
public ContentPageExample()
{
Label labelLarge = new Label
{
Text = "Label",
FontSize = 40,
HorizontalOptions = LayoutOptions.Center
};
Label labelSmall = new Label
{
Text = "This control is great for\n" +
"displaying one or more\n" +
"lines of text.",
FontSize = 20,
HorizontalOptions = LayoutOptions.CenterAndExpand
};
Button button = new Button
{
Text = "Make It So",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Button)),
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Fill
};
button.Clicked += (sender, args) =>
{
button.Text = "It is so!";
};
Entry entry = new Entry
{
Placeholder = "Username",
VerticalOptions = LayoutOptions.Center,
Keyboard = Keyboard.Text
};
BoxView boxView = new BoxView
{
Color = Color.Silver,
WidthRequest = 150,
HeightRequest = 150,
HorizontalOptions = LayoutOptions.StartAndExpand,
VerticalOptions = LayoutOptions.Fill
};
Image image = new Image
{
Source = "monkey.png",
Aspect = Aspect.AspectFit,
HorizontalOptions = LayoutOptions.End,
VerticalOptions = LayoutOptions.Fill
};
var tapGestureRecognizer = new TapGestureRecognizer();
tapGestureRecognizer.Tapped += async (sender, e) =>
{
image.Opacity = .5;
await Task.Delay(200);
image.Opacity = 1;
};
image.GestureRecognizers.Add(tapGestureRecognizer);
StackLayout stackLayout = new StackLayout
{
Children =
{
labelLarge,
labelSmall,
button,
entry,
boxView,
image
},
HeightRequest = 1500
};
ScrollView scrollView = new ScrollView
{
//BackgroundColor = Color.White,
VerticalOptions = LayoutOptions.FillAndExpand,
Content = stackLayout
};
//this.BackgroundColor = Color.Black; //White
// Accomodate iPhone status bar.
this.Padding = new Thickness(10, Device.OnPlatform(20, 0, 0), 10, 5);
this.Content = scrollView;
}
}
}
No error messages..
Did you set the ContentPageExample as MainPage? I just test the ContentPageExample and it works well.
For example in class App:
public partial class App : Application
{
public App()
{
InitializeComponent();
MainPage = new ContentPageExample();
}
}

Remove extra space from FlexLayout

Question
I have a FlexLayout with following properties. Whenever any element is added to it(except the first one), extra space gets added automatically. How do I get rid of that extra space?
var flexLayout = new FlexLayout
{
Wrap = FlexWrap.Wrap,
JustifyContent = FlexJustify.Start,
AlignItems = FlexAlignItems.Center,
AlignContent = FlexAlignContent.Start,
BackgroundColor = Color.LightYellow,
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.Start
};
Here is the result -
Detailed Question
My scenario is to add multiple Flexlayouts inside a StackLayout which is child of a ScrollView.
Everything is working fine except Flexlayouts takes lot of unused white space, I want them to fit to children.
So far I have tried
1. Lot of permutation combinations of FlexLayout properties.
2. Putting Flexlayout inside StackLayout/ Grid with VerticalOptionsset to Start
XAML
<Grid>
<ScrollView HorizontalScrollBarVisibility="Never">
<StackLayout x:Name="RootPanel" BackgroundColor="Cyan" Padding="5"/>
</ScrollView>
</Grid>
C# Code behind
private void Draw()
{
string[] data = new string[] { "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1" };
for (int i = 0; i < 5; i++)
{
var tempLayout = new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.Start
};
var fButton = new Button { Text = "B", HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start, WidthRequest = 50, HeightRequest = 50 };
tempLayout.Children.Add(fButton);
var equals = new Label { Text = "=>", VerticalTextAlignment = TextAlignment.Center, HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.Start, WidthRequest = 50, HeightRequest = 50, BackgroundColor = Color.LemonChiffon };
tempLayout.Children.Add(equals);
var flexLayout = new FlexLayout
{
Wrap = FlexWrap.Wrap,
JustifyContent = FlexJustify.Start,
AlignItems = FlexAlignItems.Center,
AlignContent = FlexAlignContent.Start,
BackgroundColor = Color.LightYellow,
HorizontalOptions = LayoutOptions.FillAndExpand
};
foreach (var term in data)
{
var button = new Button { Text = term, HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start, HeightRequest = 36 };
flexLayout.Children.Add(button);
var label = new Label { Text = "and", VerticalTextAlignment = TextAlignment.Center, HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.Start, HeightRequest = 50, BackgroundColor = Color.LemonChiffon };
flexLayout.Children.Add(label);
}
//var grid = new Grid { HorizontalOptions = LayoutOptions.StartAndExpand, VerticalOptions = LayoutOptions.Start, BackgroundColor = Color.Red };
//grid.Children.Add(flexLayout);
tempLayout.Children.Add(flexLayout);
//Grid.SetColumn(tempLayout, 1);
//grid.Children.Add(tempLayout);
RootPanel.Children.Add(tempLayout);
}
}
Above code gives following result, screenshot is from a UWP app but the result is same for Android also -
I am expecting something like this, there is no empty space after array of buttons.
Cause: The parent layout of FlexLayout is a StackLayout .And StackLayout will fit the size of its child elements.
Solution:
Use Grid instead of Stacklayout
private void Draw()
{
string[] data = new string[] { "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1", "Button1" };
for (int i = 0; i < 5; i++)
{
var grid = new Grid
{
BackgroundColor = Color.Green
};
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(50) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(50) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
var fButton = new Button { Text = "B", HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start, WidthRequest = 50, HeightRequest = 50 };
grid.Children.Add(fButton, 0, 0);
var equals = new Label { Text = "=>", VerticalTextAlignment = TextAlignment.Center, HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.Start, WidthRequest = 50, HeightRequest = 50, BackgroundColor = Color.LemonChiffon };
grid.Children.Add(equals, 1, 0);
var flexLayout = new FlexLayout
{
Wrap = FlexWrap.Wrap,
JustifyContent = FlexJustify.SpaceAround,
AlignItems = FlexAlignItems.Start,
AlignContent = FlexAlignContent.Start,
BackgroundColor = Color.Red,
HorizontalOptions = LayoutOptions.FillAndExpand,
};
foreach (var term in data)
{
var button = new Button { Text = term, HorizontalOptions = LayoutOptions.Start, VerticalOptions = LayoutOptions.Start, HeightRequest = 36 };
flexLayout.Children.Add(button);
var label = new Label { Text = "and", VerticalTextAlignment = TextAlignment.Center, HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.Start, HeightRequest = 50, BackgroundColor = Color.LemonChiffon };
flexLayout.Children.Add(label);
}
grid.Children.Add(flexLayout, 2, 0);
RootPanel.Children.Add(grid);
}
}
Don't use GRID inside FlexLyout it will give a huge WHITE SPACE, Use StackLayout instead
Mark the StackLayout Spacing value to 0. There is a default spacing of 10 points. https://learn.microsoft.com/en-us/dotnet/api/xamarin.forms.stacklayout.spacing?view=xamarin-forms

How to change the shape of button from rectangle to Circle in xamarin using xaml

I have a rectangle button in my activity. Should I change to a circle shape. How can I achieve this using the XAML?
I usually use this enter link description here
change ShapeType
var box = new ShapeView
{
ShapeType = ShapeType.Box,
HeightRequest = 75,
WidthRequest = 75,
Color = Color.Navy,
HorizontalOptions = LayoutOptions.Center,
CornerRadius = 5,
BorderColor = Color.Red,
BorderWidth = 1f,
Content = new Label
{
Text = "Touch me!",
FontSize = Device.GetNamedSize(NamedSize.Micro, typeof (Label)),
TextColor = Color.White,
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill,
VerticalTextAlignment = TextAlignment.Center,
HorizontalTextAlignment = TextAlignment.Center,
},
};
var tap = new TapGestureRecognizer
{
Command = new Command(() => {
this.DisplayAlert("Touched", "This shape responds to touch!", "Ok");
})
};
box.GestureRecognizers.Add(tap);
I think this is only possible in IOS with cornerradius but i don't think this is possible for PCL or other Xamarin solutions with xaml. You probably have to make a custom renderer.

Entry control expands beyond StackLayout container

I'm using the following (test) code to dynamically create a Page Content. I'm expecting the Entry control to stay within the StackLayout bounds and clip its large Text value. Somehow this doesn't work like I want.
What am I doing wrong here?
public MyPage() {
InitializeComponent();
var stackMain = new StackLayout() {
Orientation = StackOrientation.Vertical,
Spacing = 2,
BackgroundColor = Color.Yellow
};
Content = stackMain;
Padding = new Thickness(15, Device.OnPlatform(25, 5, 5), 15, 10);
var label = new Label() {
Text = "Test:"
};
stackMain.Children.Add(label);
var stackEntry = new StackLayout() {
Orientation = StackOrientation.Horizontal
};
stackMain.Children.Add(stackEntry);
var entry = new Entry() {
Text = "Blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
IsEnabled = false,
HorizontalOptions = LayoutOptions.FillAndExpand
};
stackEntry.Children.Add(entry);
var button = new Button() {
Text = "Click me"
};
stackEntry.Children.Add(button);
}
What you need is an editor, Entries are one line only, the code below is tested and it fixes the Height by the size of the text:
public class App : Application
{
public App()
{
// The root page of your application
var content = new ContentPage
{
Padding = new Thickness(15, Device.OnPlatform(25, 5, 5), 15, 10),
Title = "test",
Content = new StackLayout
{
Spacing = 2,
BackgroundColor = Color.Yellow,
Children = {
new Label {
Text = "Test:"
},
new Editor {
Text = "Blaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
IsEnabled = false,
HorizontalOptions = LayoutOptions.Fill,
VerticalOptions = LayoutOptions.Fill
},
}
}
};
MainPage = new NavigationPage(content);
}
}
Hope this helps.
I just solved the same problem on an editor control!
The problem is here Orientation = StackOrientation.Horizontal,
you need to set orientation as StackOrientation.Vertical and it will wrap properly.
Note that I'm using Editor instead of Entry.

Xamarin Forms Automatic Image SlideShow/Carousel

I'm completely new to Xamarin Forms but I've managed to create a simple app that has multiple pages and I am able to navigate between pages.
I've added images, buttons and other basic controls successfully and it looks pretty good.
My problem is that I cannot figure out how to create an automatic carousel of multiple images on a page. Any google searches return the CarouselPage which enables a user to swipe the screen to change pages.
I'm considering a horizontal scroller with the 3 images but it doesn't really have the same effect - the user will have to move themselves through the images!
Has anyone found a way of doing this? Any hints or tips would be great!
You can code a combination of a c# timer, a carrousel page, and contentPage's with images on the background I have done something similar but using buttons to navigate the carrousel page:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Xamarin.Forms;
namespace SEEForgeX.Views
{
class CarouselView : CarouselPage
{
ContentPage image1,image2,image3,image4;
public CarouselView()
{
NavigationPage.SetHasNavigationBar(this, false);
string btnPrevTitle = "< Prev";
string btnNextTitle = "Next >";
Color btnColor = Color.FromRgba(0, 0, 0, 0.5);
Color btnTextColor = Color.White;
LayoutOptions btnPosY = LayoutOptions.EndAndExpand;
LayoutOptions btnPrevPosX = LayoutOptions.StartAndExpand;
LayoutOptions btnNextPosX = LayoutOptions.EndAndExpand;
Font buttonFont = Font.SystemFontOfSize(16, FontAttributes.Bold);
int btnWidth = 100;
string exitBtnImg = "close.png";
Button nextBtn1 = new Button
{
Text = btnNextTitle,
BackgroundColor = btnColor,
TextColor = btnTextColor,
VerticalOptions = btnPosY,
HorizontalOptions = btnNextPosX,
Font = buttonFont,
WidthRequest = btnWidth
};
Button prevBtn2 = new Button
{
Text = btnPrevTitle,
BackgroundColor = btnColor,
TextColor = btnTextColor,
VerticalOptions = btnPosY,
HorizontalOptions = btnPrevPosX,
Font = buttonFont,
WidthRequest = btnWidth
};
image1 = new ContentPage
{
BackgroundImage = "slide_01.jpg",
Content = new StackLayout
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Orientation = StackOrientation.Vertical,
Padding = 0,
Children = {
new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.StartAndExpand,
Padding = new Thickness(0,10,10,0),
Children = { exitBtn1 }
},
new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.EndAndExpand,
Padding = 20,
Children = { nextBtn1 }
}
}
},
};
image2 = new ContentPage
{
BackgroundImage = "slide_02.jpg",
Content = new StackLayout
{
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.FillAndExpand,
Orientation = StackOrientation.Vertical,
Padding = 0,
Children = {
new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.StartAndExpand,
Padding = new Thickness(0,10,10,0),
Children = { exitBtn2 }
},
new StackLayout
{
Orientation = StackOrientation.Horizontal,
VerticalOptions = LayoutOptions.EndAndExpand,
Padding = 20,
Children = {prevBtn2, nextBtn2}
}
}
},
};
//This is the children of the parent view is like adding stacklayout.children.add(foo) but since my parent class is a CarouselPage I can access Children its children
Children.Add(image1);
Children.Add(image2);
void prevBtn2_Clicked(object sender, EventArgs e)
{
this.CurrentPage = image1;
}
void nextBtn1_Clicked(object sender, EventArgs e)
{
this.CurrentPage = image2;
}
private async void exitBtn_Clicked(object sender, EventArgs e)
{
//await Navigation.PopModalAsync();
await Navigation.PopModalAsync();
}
I am not implementing the timer but it should not be difficult, maybe you can even use a loop.

Categories