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"
Related
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;
} }
I have a grid with only one row with the height of GridLength.Star.
In the first column I have an svg that fills the cell.
In the second column I have a label.
The svg is a square and should take the place to fill it in vertical and horizontal direction but not more.
The label should take the rest of the width.
I tried to set
column1.Width = GridLength.Auto;
column2.Width = GridLength.Star;
but it will always be devided in the middle.
So I got:
svg..........|label........
instead of (what I want):
svg|label..................
Any ideas?
UPDATE
Label label = new Label();
SvgCachedImage svgImage = new SvgCachedImage();
svgImage.HorizontalOptions = LayoutOptions.CenterAndExpand;
svgImage.VerticalOptions = LayoutOptions.CenterAndExpand;
Grid grid = new Grid();
grid.Children.Add( svgImage );
grid.Children.Add( label );
RowDefinition row = new RowDefinition();
ColumnDefinition column1 = new ColumnDefinition();
ColumnDefinition column2 = new ColumnDefinition();
row.Height = GridLength.Star;
grid.RowDefinitions = new RowDefinitionCollection { row1 };
column1.Width = GridLength.Auto;
column2.Width = GridLength.Star;
grid.ColumnDefinitions = new ColumnDefinitionCollection { column1, column2 };
UPDATE 2
Sorry it is no Fill but a CenterAndExpand
I got the answer. I simply need to set the height of the svg to its widthRequest:
svgImage.WidthRequest = svgImage.Height;
column1.Width = GridLength.Auto;
column2.Width = GridLength.Star;
grid.Children.Add( svgImage, 0, 0 );
grid.Children.Add( label, 1, 0 );
Well, its very simple actually the reason behind it is the GridLength.Auto you have there all you need to do is change the Grid column definitions into something like this:
XAML
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/> // svg
<ColumnDefinition Width="4*"/> // label
</Grid.CoulmnDefinitions>
C#
Grid grid= new Grid
{
ColumnDefinitions =
{
new RowDefinition { Height = new GridLength(1, GridUnitType.Star) },
new RowDefinition { Height = new GridLength(4, GridUnitType.Star) },
}
}
grid.Children.Add(svgImage, 0, 0);
grid.Children.Add(label, 0, 1);
Move:
grid.Children.Add( svgImage );
grid.Children.Add( label );
to after you've set up your row/column definitions, and then change to:
grid.Children.Add(svgImage, 0, 0);
grid.Children.Add(label, 0, 1);
You basically have to tell the grid which row/column to put your elements. By adding them to the grid before initialising the column definitions, the ColumnDefinitions have defaulted to GridLength.Star.
I've tidied up your code. Note that I have changed the Height assignments.
Label label = new Label()
{
Text = "Some text" // Just some placeholder text
};
SvgCachedImage svgImage = new SvgCachedImage()
{
HorizontalOptions = LayoutOptions.CenterAndExpand,
VerticalOptions = LayoutOptions.CenterAndExpand
};
Grid grid = new Grid();
// NOTE: use GridLength class to set the Height/Width of rows/columns
RowDefinition row = new RowDefinition()
{
Height = new GridLength(1, GridUnitType.Star)
}
ColumnDefinition column1 = new ColumnDefinition()
{
Width = new GridLength(1, GridUnitType.Auto)
}
ColumnDefinition column2 = new ColumnDefinition()
{
Width = new GridLength(1, GridUnitType.Star)
}
// Use existing instances of the definitions
grid.RowDefinitions.Add(row1);
grid.ColumnDefinitions.Add(column1);
grid.ColumnDefinitions.Add(column2);
grid.Children.Add(svgImage, 0, 0);
grid.Children.Add(label, 1, 0);
As I was typing this out I noticed that you had simply set the Width property to GridLength.Star/Auto. According to the docs, you should be using the GridLength class, not the Enum.
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;
}
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++;
}
}
}
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) });