Issues with the Grid (Xamarin Forms) - xamarin

I am using the following code to make the impression that a solid color is masked with a square:
public Page1()
{
InitializeComponent();
var maskSide = 196;
var grid = new Grid {ColumnSpacing = 0, RowSpacing = 0};
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength((App.ScreenHeight - maskSide) / 2, GridUnitType.Absolute) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(maskSide, GridUnitType.Absolute) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength((App.ScreenWidth - maskSide) / 2, GridUnitType.Absolute) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(maskSide, GridUnitType.Absolute) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
grid.Children.Add(new BoxView { HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, BackgroundColor = Color.Lime }, 0, 0);
grid.Children.Add(new BoxView { HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, BackgroundColor = Color.Lime }, 0, 1);
grid.Children.Add(new BoxView { HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, BackgroundColor = Color.Lime }, 0, 2);
grid.Children.Add(new BoxView { HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, BackgroundColor = Color.Lime }, 1, 0);
grid.Children.Add(new BoxView { HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, BackgroundColor = Color.Transparent }, 1, 1);
grid.Children.Add(new BoxView { HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, BackgroundColor = Color.Lime }, 1, 2);
grid.Children.Add(new BoxView { HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, BackgroundColor = Color.Lime }, 2, 0);
grid.Children.Add(new BoxView { HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, BackgroundColor = Color.Lime }, 2, 1);
grid.Children.Add(new BoxView { HorizontalOptions = LayoutOptions.Fill, VerticalOptions = LayoutOptions.Fill, BackgroundColor = Color.Lime }, 2, 2);
grid.HorizontalOptions = LayoutOptions.Fill;
grid.VerticalOptions = LayoutOptions.Fill;
Content = grid;
}
I am setting device dimensions in Droid's MainActivity's OnCreate like this :
App.ScreenWidth = (int)(Resources.DisplayMetrics.WidthPixels / Resources.DisplayMetrics.Density);
App.ScreenHeight = (int)(Resources.DisplayMetrics.HeightPixels / Resources.DisplayMetrics.Density);
Here is the result:
However there are two issues with that:
As you can see, there are two issues:
For some reason, the masking square isn't located exactly in the middle.
There is a one (or maybe two) pixel gap between the last items in both, vertical and horizontal stacks.
I cannot understand, what is the problem. Any suggestions?

Grid can take care of this for you
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(maskSide, GridUnitType.Absolute) });
grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(maskSide, GridUnitType.Absolute) });
grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) });

Related

Xamarin.Forms: Relative Layout inside Grid layout not working properly

I want to create dynamic grid layout with one row with 2 column and another row with only one column with colspan 2.
And every column may contain on overlay image at top right corner.
For this i tried to add relative layout in grid layout but the issue is image tag in relative layout is not occupying complete width.
code to create relative layout
for (int i = 0; i < temp.Count; i++)
{
var data = temp[i];
var framelyt = new Frame { CornerRadius = 4, IsClippedToBounds = true, HasShadow = false, Padding = 0, HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.FillAndExpand };
Image imageStack = new Image { Source = "placeholder_image1", Margin = 0, Aspect = Aspect.Fill, HorizontalOptions = LayoutOptions.FillAndExpand };
Image cmpltimageStack = new Image { Source = "completed_icon", Aspect = Aspect.Fill, HeightRequest = 32, IsVisible=true };
RelativeLayout relativeLayout = new RelativeLayout { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.FillAndExpand, BackgroundColor = Color.Beige };
framelyt.Content = imageStack;
relativeLayout.Children.Add(framelyt, Constraint.RelativeToParent((parent) =>
{
return parent.Width;
}), Constraint.Constant(0)); relativeLayout.Children.Add(cmpltimageStack,
Constraint.RelativeToParent((parent) =>
{
return parent.Width - 50;
}),
Constraint.Constant(0));
gridStckActivity.Children.Add(relativeLayout, column, row);
if (column == 1)
{
column = 0;
isSingle = true;
row++;
}
else
{
column = 1;
}}
It was working on android device properly but on iOS it was leaving some space on right padding. After adding x,y and width constraint it worked properly on both device.
Here is the revised code.
for (int i = 0; i < temp.Count; i++)
{
var data = temp[i];
var framelyt = new Frame { CornerRadius = 4, IsClippedToBounds = true, HasShadow = false, Padding = 0, HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.FillAndExpand };
Image imageStack = new Image { Source = "placeholder_image1", Margin = 0, Aspect = Aspect.Fill, HorizontalOptions = LayoutOptions.FillAndExpand };
Image cmpltimageStack = new Image { Source = "completed_icon", Aspect = Aspect.Fill, HeightRequest = 32, IsVisible=true };
RelativeLayout relativeLayout = new RelativeLayout { HorizontalOptions = LayoutOptions.FillAndExpand, VerticalOptions = LayoutOptions.FillAndExpand, BackgroundColor = Color.Beige };
framelyt.Content = imageStack;
relativeLayout.Children.Add(framelyt, Constraint.Constant(0), Constraint.Constant(0),Constraint.RelativeToParent((parent) =>
{
return parent.Width;
}));
relativeLayout.Children.Add(cmpltimageStack,
Constraint.RelativeToParent((parent) =>
{
return parent.Width - 50;
}),
Constraint.Constant(0));
gridStckActivity.Children.Add(relativeLayout, column, row);
if (column == 1)
{
column = 0;
isSingle = true;
row++;
}
else
{
column = 1;
} }

Setting relative height for Grid children

I'm adding 2 children to a Grid like this:
private void pInitStackLayout()
{
grid1 = new Grid()
{
};
grid2 = new Grid()
{
};
biggrid = new Grid()
{
BackgroundColor = Color.Transparent,
Margin = new Thickness(0),
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.StartAndExpand,
Orientation = StackOrientation.Vertical,
};
biggrid.Children.Add(grid1,0,0);
biggrid.Children.Add(grid2,0,1);
this.Content = biggrid;
}
The ContentPage's (which is a Navigation Page) Content is the biggrid.
I would like to make it so that grid1 takes up 80% of the available height, and grid2 takes up 20% (or the rest).
How could I achieve this?
It's very simple actually, just set the RowDefinitions of biggrid.
// RowDefinitions isolated
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = new GridLength(8, GridUnitType.Star) },
new RowDefinition { Height = new GridLength(2, GridUnitType.Star) }
}
// RowDefinitions isolated
// Actual code
private void pInitStackLayout()
{
grid1 = new Grid()
{
};
grid2 = new Grid()
{
};
biggrid = new Grid()
{
RowDefinitions = new RowDefinitionCollection
{
new RowDefinition { Height = new GridLength(8, GridUnitType.Star) },
new RowDefinition { Height = new GridLength(2, GridUnitType.Star) }
},
BackgroundColor = Color.Transparent,
Margin = new Thickness(0),
HorizontalOptions = LayoutOptions.FillAndExpand,
VerticalOptions = LayoutOptions.StartAndExpand,
Orientation = StackOrientation.Vertical,
};
biggrid.Children.Add(grid1,0,0);
biggrid.Children.Add(grid2,0,1);
this.Content = biggrid;
}

tap doesn't work in ios xamarin.forms

I have 2 grids: one overlaps the other...in my android project it works well but in my ios device the tapgesturerecognizer doesn't work. the tap is in the topper grid.
I tried input transparent in the under grid and put one of them inside a ContentView (someone told that it can be the answer, but unfortunately, it's not)...but nothing seems to work...I'm desperate...2 days searching for it, it's a job question and I think I will have problems because of that
Please, if you can, try to help me.
It's only two grids in the row 0 and column 0 of the other grid...
There isn't an error on logs...But the click doesnt arrive in the function that it should arrive.
The code
private void CriaTela()
{
int row = 0;
int column = 0;
gridtextura.RowSpacing = 5;
gridtextura.ColumnSpacing = 15;
lstCategorias = lstCategorias.OrderBy(o => o.nome).ToList();
foreach (var item in lstCategorias)
{
Grid GridContent = new Grid
{
RowSpacing = 0,
Margin = new Thickness(0, 5, 0, 0),
VerticalOptions = LayoutOptions.FillAndExpand,
RowDefinitions =
{
new RowDefinition { Height = new GridLength(8, GridUnitType.Star) },
new RowDefinition { Height = new GridLength(2, GridUnitType.Star) }
}
};
var textura = new CachedImage();
textura.Source = "texturaCateg";
textura.HorizontalOptions = LayoutOptions.FillAndExpand;
textura.VerticalOptions = LayoutOptions.FillAndExpand;
textura.Aspect = Aspect.Fill;
GridContent.BindingContext = item;
Grid boxColorView = new Grid
{
RowSpacing = 0,
//InputTransparent = true,
VerticalOptions = LayoutOptions.FillAndExpand,
RowDefinitions =
{
new RowDefinition { Height = new GridLength(2, GridUnitType.Star) },
new RowDefinition { Height = new GridLength(8, GridUnitType.Star) }
}
};
boxColorView.Children.Add(new StackLayout { BackgroundColor = Color.FromHex(item.corFundo), VerticalOptions = LayoutOptions.FillAndExpand }, 0, 1 );
boxColorView.Children.Add(textura, 0, 1);
// boxColorView.Children.Add(new BoxView { VerticalOptions = LayoutOptions.FillAndExpand }, 0, 0);
gridtextura.Children.Add(boxColorView, column, row);
gridtextura.Children.Add(GridContent, column, row);
//Qual categoria foi escolhida?
var CliqueCategoria = new TapGestureRecognizer();
CliqueCategoria.NumberOfTapsRequired = 1;
CliqueCategoria.Tapped += (s, e) =>
{
CriaLoading();
var stacklayout = s as Grid;
categoriaEscolhida = (Categorias)stacklayout.BindingContext;
ChamaProdutos();
};
GridContent.GestureRecognizers.Add(CliqueCategoria);
if (item.imagem != null && item.imagem != "")
{
int initIndex = item.imagem.IndexOf(',');
string image = "";
image = item.imagem.Substring(initIndex + 1);
try
{
GridContent.Children.Add(new CachedImage { Source = ImageSource.FromStream(() => new MemoryStream(Convert.FromBase64String(image))), VerticalOptions = LayoutOptions.FillAndExpand }, 0, 0);
}
catch (Exception e)
{
GridContent.Children.Add(new CachedImage { Source = "error.png", VerticalOptions = LayoutOptions.FillAndExpand, HorizontalOptions = LayoutOptions.Fill, HeightRequest = 50, WidthRequest = 50 }, 0, 0);
}
}
GridContent.Children.Add(new Label { Text = item.nome, TextColor = Color.FromHex(item.corTexto), FontSize = Device.GetNamedSize(NamedSize.Micro, typeof(Label)), FontAttributes = FontAttributes.Bold, HorizontalTextAlignment = TextAlignment.Center, VerticalOptions = LayoutOptions.Start, HorizontalOptions = LayoutOptions.CenterAndExpand }, 0, 1 );
if (column == 0)
{
column = 1;
}
else
{
column = 0;
row++;
}
}
}

Incorrect word wrap in labels/pickers

Sometimes my text in labels or pickers in Android will wrap before the end of a label. It doesn't happen every time, but when it happens the text will initially appear correctly and then quickly rerender incorrectly. This only happens when the views are in a Grid, but I can't be sure that's the cause. Using the "show layout boundaries" option, I can see that the width of the label is correct and doesn't change, it's just the word wrap that doesn't properly.
relevant code in a ContentView subclass constructor:
Grid _contentGrid = new Grid()
{
RowDefinitions = new RowDefinitionCollection()
{
new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) },
new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) },
new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) },
new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) },
},
ColumnDefinitions = new ColumnDefinitionCollection()
{
new ColumnDefinition() { Width = 48 },
new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) },
},
BackgroundColor = Color.Transparent,
Padding = new Thickness(16, 16, 16, 16),
ColumnSpacing = 16,
RowSpacing = 8,
HorizontalOptions = LayoutOptions.FillAndExpand
};
Label _questionLabel = new Label()
{
Text = "Do you want to update the instrument setup?",
TextColor = Color.FromHex(Colours.TextGrey),
HorizontalOptions = LayoutOptions.FillAndExpand,
XAlign = TextAlignment.Start,
WidthRequest = 344
};
_contentGrid.Children.Add(_questionLabel, 0, 2, 3, 4);
DialogView dialogView = new DialogView()
{
TopView = TitleLabel,
MiddleView = _contentGrid,
BottomView = ButtonGrid,
TopColour = Color.FromHex(Colours.Blue),
MiddleColour = Color.White,
BottomColour = Color.White,
MiddleHeight = 150,
};
Grid Holder = new Grid()
{
ColumnDefinitions = new ColumnDefinitionCollection()
{
new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) },
new ColumnDefinition() { Width = 368 },
new ColumnDefinition() { Width = new GridLength(1, GridUnitType.Star) },
},
RowDefinitions = new RowDefinitionCollection()
{
new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) },
new RowDefinition() { Height = new GridLength(1, GridUnitType.Auto) },
new RowDefinition() { Height = new GridLength(1, GridUnitType.Star) },
},
BackgroundColor = Color.FromHex("b0000000")
};
Holder.Children.Add(dialogView, 1, 1);
this.Content = Holder;
The _questionLabel text only shows "Do you want"

Fill all the screen with StackLayout

I have a StackLayout coded like this:
StackLayout mainStackLayOut = new StackLayout{
BackgroundColor = Color.Blue,
//VerticalOptions = LayoutOptions.FillAndExpand,
//WidthRequest = width,
HorizontalOptions = LayoutOptions.FillAndExpand,
Orientation = StackOrientation.Vertical
};
But I want the StackLayout to fill all the screen width and height, also I have tree buttons added like this:
StackLayout buttonsStackLayOut = new StackLayout
{
BackgroundColor = Color.White,
//VerticalOptions = LayoutOptions.Fill,
HorizontalOptions = LayoutOptions.Fill,
Orientation = StackOrientation.Horizontal,
Spacing = 0
};
mainStackLayOut.Children.Add(buttonsStackLayOut);
Image doctorImage = new Image
{
WidthRequest = width / 3,
HeightRequest = 50,
BackgroundColor = Color.Gray,
Source = ImageSource.FromFile ("about.png")
};
buttonsStackLayOut.Children.Add(doctorImage);
How can I fill all the screensize?
In the most simple form I have managed to achieve what you require.
I set the content of the screen to the main stack layout.
var mainStackLayout = new StackLayout { BackgroundColor = Color.Blue};
var buttonsStackLayout = new StackLayout { BackgroundColor = Color.White, Orientation = StackOrientation.Horizontal , Spacing = 0 };
Image about = new Image { HeightRequest = 50, Source = ImageSource.FromFile("about.jpg") };
Image twitter = new Image { HeightRequest = 50, Source = ImageSource.FromFile("twitter.jpg") };
Image refresh = new Image { HeightRequest = 50, Source = ImageSource.FromFile("refresh.jpg") };
buttonsStackLayout.Children.Add(about);
buttonsStackLayout.Children.Add(twitter);
buttonsStackLayout.Children.Add(refresh);
mainStackLayout.Children.Add(buttonsStackLayout);
this.Content = mainStackLayout;

Resources