How to reduce space between content in Flex layout, if content is placed in row direction? - xaml

My questions are:
How to reduce space between two rows?
How to reduce space between items, if number of items are less than privous row items?
My xaml code:
<FlexLayout Wrap="Wrap" AlignItems="Start" Direction="Row" JustifyContent="SpaceAround" HorizontalOptions="StartAndExpand">
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
<Image Source="icon.png"/>
</FlexLayout>
Output:
What I want is:

I ran into this issue and eventually I found out the reason.
The reason why it will look like this is that the flex layout will expand itself to the maximum in default like what a Grid does, regardless of the children.
The spacing is based on the area left after allocating all the children. You got a lot of area left vertically so the space between rows got larger. If you use Xamarin.UWP or Xamarin.WPF and resize the app window you can see the space between rows is changing.
So, HorizontalOptions="StartAndExpand" is unnecessary.
Add VerticalOptions="Start" to the flex layout (Or sometimes if you wrap the flex layout inside another auto-expand control like ScrollView, then add this to the parent ScrollView) and the problem is solved, at least in my case.
When it comes to the third line, I just added JustifyContent="Start" AlignItems="Start".
Edit:
Apply Margin property to each item, to get space between items.

Set
AlignContent="Start"
in FlexLayout.
By setting this property, the child elements are aligned without row space.
http://tecsack.com/xamarin-forms-flex-layout/

I've never used FlexLayout in Xamarin, but from my HTML/CSS days I would suggest that your issue is with JustifyContent="SpaceAround". Try to change SpaceAround to FlexStart

By default FlexLayout doesn't have RowSpacing or other parameter. What you need to do is define column nubers eg. 4, then dived your FlexLayout width by your column number and programmatically add elements to your FlexLayout. You can use OnSizeChanged event to do that and start adding child items to FlexLayout. Then you should set:
Direction: Row
Wrap: Wrap
FlowDirection: LeftToRight
JustifyContent: Start
AlignItems: Start
Some Example of code could be:
private void FlexGallery_SizeChanged(object sender, EventArgs e)
{
//imageDimension = Math.Round(FlexGallery.Width / 4) ..round it with desired method
foreach (var it in documents.OrderBy(a => a.DateCreated))
{
if (Path.GetExtension(it.Url) == ".png" || Path.GetExtension(it.Url) == ".jpg")
{
Image img = new Image
{
HeightRequest = imageDimension,
WidthRequest = imageDimension,
Margin = new Thickness(5, 5, 5, 5),
Source = ImageSource.FromUri(new Uri(it.Url))
};
FlexGallery.Children.Add(img);
}
else
{
}
}
}
Where imageDimension is your FlexLayout divided by desired numbers of columns, and rounded with Math.Round.
Approach by adding it programmatically is different from approach where number of items is alerady known and defined in xaml.
This approach is only for items with scale factor 1:1 .
You should get something like this (this is tabbed view so ignore white line at center):

Related

How to set a background image with XAML/.NET Maui that has AspectFill behavior but left aligned?

I am working an app that uses an image as its background, and I want it to fill the entire window regardless of size. The image source is square-ish, like this:
The simplest way to do this is using AspectFill like this:
<Image
Source="image_source.png"
Aspect="AspectFill"/>
But that results in the image being centered, like this:
When what I need is for the image to be left aligned, like this:
I almost had some success using this:
<AbsoluteLayout>
<Image
Source="image_source.png"
AbsoluteLayout.LayoutFlags="HeightProportional"
AbsoluteLayout.LayoutBounds="0,0,Autosize,1"/>
</AbsoluteLayout>
but the problem there became when I had a screen like a tablet or foldable which is wider horizontally, it ended up getting letterboxed like this:
When what I would want would just be a regular AspectFill like this:
Is there any way to get this behavior with the existing Aspect options? If not, is there a way to extend the Aspect enum and the Renderer to make the image perform the same as AspectFill, but locked to the left edge of the image instead of the center?
I'm using XAML with .NET Maui, so if there is a solution in C# I'm open to that too
Was able to get a solution from Reddit, so I'm posting it here for anyone who stumbles across this:
My final XAMl ended up being
<Grid>
<Image
x:Name="backgroundImage"
Source="image_source.png"
Aspect="AspectFill"
HorizontalOptions="Start"/>
</Grid>
And I added this to the code-behind:
protected override void OnSizeAllocated (double pageWidth, double pageHeight) {
base.OnSizeAllocated(pageWidth, pageHeight);
const double aspectRatio = 1600 / 1441.0; // Aspect ratio of the original image
backgroundImage.WidthRequest = Math.Max(pageHeight * aspectRatio, pageWidth);
}

How can I adapt the width of an Image retrieved by URL to a View container in React Native?

I would like to retrieve an image from an url, and insert it inside a View adapting the size to the container.
This is an expo where I tried to do it.
https://snack.expo.io/Hk1rsfaHU
How you can see there are 3 columns having the same width(flex 1), in the first there is the image.
I wish this Image was contained inside the View, adapting the width to the container and maintaining the correct aspect ratio.
Any suggestions?
You need to change src to source in your <Image />:
<Image source={{uri: 'https://i2.wp.com/www.xpeppers.com/wp-content/uploads/2016/06/react-native-preview.png?resize=580%2C357'}}
resizeMode='contain' style={styles.image}
/>
Output:
Working Demo:
https://snack.expo.io/SJdlzQTr8

Change part of a label in Titanium or Alloy / Appcelerator

I want to change part of a label dynamically.
This is my code:
<View top="0" height="115">
<Label id="lblMiles" left="15" textAlign="right" right="15" top="0" height="55">
{distance} Miles
</Label>
</View>
I want to be able to change the {distance} portion dynamically.
However currently I can only change the whole thing like this:
$.lblMiles.text = "10 Miles";
In HTML we normally use a span tag like so:
<div id="lblMiles"><span id="distance"></span> Miles</div>
How can I do something similar in Alloy?
If it were up to me, i wouldn't worry about updating only half the label, just reset the whole text,
$.lblMiles.text = "10 Miles";
// and then later on to update it to 15
$.lblMiles.text = "15 Miles";
if for some reason you need to update only half, then you could use two labels and put them in a view with layout set to horizontal.
something looking like this :
<View top="0" height="115">
<View height="Ti.UI.SIZE" width="Ti.UI.SIZE" layout="horizontal">
<Label id="dynamicLabel" />
<Label id="lblMiles" > Miles</Label>
</View>
</View>
and then in your code, just update the dynamic label setting the actual value:
$.dynamicLabel.text = "15";
Now to position the labels on the screen you should play on the attributes of their container's left, right, top and bottom.
You can do this by two three ways
Have two different labels and set it from controller
You can use attributed strings as well.
More reference is here http://docs.appcelerator.com/platform/latest/#!/guide/Attributed_Strings

Using Br tag in Xamarin Forms

I'm using Xamarin Forms. I use a BoxView for making spaces between lines but I don't know if I'm doing right. What is the proper way to using a br tag in Xamarin ? Is there an alternative way for it? I'm using this:
<StackLayout>
<Label Text="Line 1"></Label>
<BoxView HeightRequest="100"></BoxView>
<Label Text="Line 2"></Label>
</StackLayout>
Thank you for the replies, for a conclusion; I thought the simpliest alternative should be like this,
and normally, I'll use a Grid, for spacing.
<StackLayout>
<Label Text="10"></Label>
<StackLayout HeightRequest="100"></StackLayout>
<Label Text="20"></Label>
</StackLayout>
If you are already using a StackLayout, you can set 'spacing' between each element in the Stackayout, example :
<StackLayout Spacing="10">
Some other options can be found in the Xamarin Forum though... https://forums.xamarin.com/discussion/29700/label-and-n
you can follow the example bellow or use [GRID ][1]
StackLayout linesSTK= new StackLayout {
VerticalOptions = LayoutOptions.Center,
HorizontalOptions =LayoutOptions.CenterAndExpand,
Children = {
new Label { Text = "Line 1" },
new Label { Text = "Line 2" },
new Label { Text = "Line 3" }
}
};
There are multiple ways to do this depending on your requirements.
You can set the Margin property on your Label, also you can set the Spacing on your StackLayout which tells the StackLayout to put some space between the items in it.
Another way would be to change your StackLayout to a Grid. With this you have some more fine grained control because you can not only set the Spacing like on a StackLayout but you can also play with the row height and column widths. Within the Grid columns and rows you can nest a StackLayout for more control on how they should behave in there.
For more information on the Grid check the extensive guide in the Xamarin Documentation.

XAML : Binding FontSize to the Height of Control

Within a Xamarin.Form page, I am trying to bind the FontSize of a label to the height of that same label.
I seen examples in WPF that do this:
FontSize="{Binding ElementName=CurrentPresenter, Path=Height}"
But I can not seem to get anything to work like that in Forms, i.e.:
<Label
Text="X"
FontSize="{Binding ElementName=CurrentPresenter, Path=RequestedHeight}"
HorizontalTextAlignment="Center"
AbsoluteLayout.LayoutBounds="0.1, 0.5, 0.33, 0.66"
AbsoluteLayout.LayoutFlags="All" />
(I will use a data converter to adjust the font size so based upon screen DPI, I can auto-adjust, but for now, I'm just trying to bind it to a control's height to get something other than default system font size)
This way appears to work fine, not sure about the runtime layout performance though...
FYI: This does not work within the XAML Designer, only runtime
<Label
Text="X"
x:Name="foo"
BindingContext="{x:Reference Name=foo}"
FontSize="{Binding Path=Height}"
HorizontalTextAlignment="Center"
AbsoluteLayout.LayoutBounds="0.1, 0.5, 0.33, 0.66"
AbsoluteLayout.LayoutFlags="All" />
Not exactly related to OP question but searching "Xaml height based on another control" has hardly any results in Google so posting this in case it helps someone else.
To change the size of smaller buttons to match the size of a larger button like in the following picture
There are several ways to do this without using code behind but if the layout you are trying to use is being difficult here following is another option. To change the size of the smaller buttons without changing the binding of those controls you can give the buttons names in XAML and then do something like this in the code behind:
public HomeOpenPage ()
{
InitializeComponent ();
RefreshButton.PropertyChanging += RefreshButton_PropertyChanging;
}
private void RefreshButton_PropertyChanging(object sender, PropertyChangingEventArgs e)
{
if (RefreshButton.Width != -1)
{
var width = RefreshButton.Width;
CSVButton.WidthRequest = width;
EndButton.WidthRequest = width;
}
}
protected override void OnDisappearing()
{
RefreshButton.PropertyChanging -= RefreshButton_PropertyChanging;
base.OnDisappearing();
}