Le Mot Juiced
Le Mot Juiced

Reputation: 3859

RelativeLayout in Xamarin: Can't make a square

I've grabbed the sample project from here: https://developer.xamarin.com/samples/xamarin-forms/BoxView/ListViewColors/

I'm trying to make visual changes, in particular I'm trying to get the color squares to be rounded circles. The color squares are BoxViews in the original, and they use WidthRequest and HeighRequest, both set to 50. This succeeds in making them square. But:

  1. BoxViews don't have a CornerRadius property, so I've made them Frames instead.
  2. I don't want to use points, I want to use RelativeLayout values, so I've tried to set both width and height using Factor=0.1 of the ItemTemplate's Frame.
  3. It doesn't work! No matter what I do, the colored frames are just a weird oblong shape--they're not even square anymore.

What am I doing wrong?

    <ListView SeparatorVisibility="None"
              BackgroundColor="Transparent"
              ItemsSource="{x:Static local:NamedColor.All}"
                  RelativeLayout.WidthConstraint="{ConstraintExpression 
                Type=RelativeToParent,
                Property=Width,
                Factor=1}">
        <ListView.RowHeight>
            <OnPlatform x:TypeArguments="x:Int32">
                <On Platform="iOS, Android" Value="80" />
                <On Platform="UWP" Value="90" />
            </OnPlatform>
        </ListView.RowHeight>

        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <ContentView Padding="5">
                        <Frame x:Name="itemFrame"
                               BackgroundColor="#bbffffff"
                               Padding="8"
                               CornerRadius="10"
                               HasShadow="false">
                            <StackLayout Orientation="Horizontal">
                                <Frame x:Name="colorFrame"
                                    CornerRadius="20"
                                    OutlineColor="Transparent"
                                    BackgroundColor="{Binding Color}"
                                    HasShadow="false"
                                RelativeLayout.WidthConstraint="{ConstraintExpression
                                    Type=RelativeToView,
                                    ElementName=itemFrame,
                                    Property=Width,
                                    Factor=0.1}"
                                RelativeLayout.HeightConstraint="{ConstraintExpression 
                                    Type=RelativeToView,
                                    ElementName=itemFrame,
                                    Property=Width,
                                    Factor=0.1}"/>
                                <StackLayout>
                                    <Label Text="{Binding FriendlyName}"
                                           FontSize="22"
                                           VerticalOptions="StartAndExpand" />
                                    <Label Text="{Binding RgbDisplay, StringFormat='RGB = {0}'}"
                                           FontSize="16"
                                           VerticalOptions="CenterAndExpand" />
                                </StackLayout>
                            </StackLayout>
                        </Frame>
                    </ContentView>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
        </RelativeLayout>
</ContentPage>    

Upvotes: 1

Views: 382

Answers (1)

Sparsha Bhattarai
Sparsha Bhattarai

Reputation: 703

The padding in the outer frame seems to have interfered with the shape of your circle, rendering it into an elliptical figure. Removing the padding works and you can obtain a circular shape from your frame.

The corner radius property for a frame usually doesn't render for UWP application. So, you'll need to make a custom renderer for your frame to obtain the circle. As for your listview you can use the following code:

<ListView.ItemTemplate>
    <DataTemplate>
         <ViewCell>
            <ContentView Padding="5">
                <RelativeLayout VerticalOptions="FillAndExpand">
                     <Frame OutlineColor="Accent" CornerRadius="6" HorizontalOptions="FillAndExpand" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width,Factor=1,Constant=0}" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height,Factor=1,Constant=0}" >
                         <StackLayout Orientation="Horizontal" HorizontalOptions="FillAndExpand" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width,Factor=1,Constant=0}" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height,Factor=1,Constant=0}" >
                              <Frame BackgroundColor="{Binding Color}" CornerRadius="60" RelativeLayout.HeightConstraint ="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.6, Constant=0}" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height,Factor=0.6,Constant=0}"/>
                              <StackLayout HorizontalOptions="FillAndExpand">
                                   <Label Text="{Binding FriendlyName}" FontSize="22" VerticalOptions="StartAndExpand" />
                                   <Label Text="{Binding RgbDisplay, StringFormat='RGB = {0}'}" FontSize="16" VerticalOptions = "CenterAndExpand" />
                              </StackLayout>
                         </StackLayout>
                     </Frame>
                </RelativeLayout>
            </ContentView>
        </ViewCell>
    </DataTemplate>
</ListView.ItemTemplate>

For frame, custom renderer for UWP:

public class CustomFrame:FrameRenderer
{
     protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
     {
            base.OnElementChanged(e);

            if (Control != null)
            {
                var frame = e.NewElement;
                Windows.UI.Color frameBG = Windows.UI.Color.FromArgb(
                    (byte)(frame.BackgroundColor.A * 255),
                    (byte)(frame.BackgroundColor.R * 255),
                    (byte)(frame.BackgroundColor.G * 255),
                    (byte)(frame.BackgroundColor.B * 255));

                Control.CornerRadius = new Windows.UI.Xaml.CornerRadius(frame.CornerRadius);
                Control.Background = new SolidColorBrush(frameBG);
                frame.BackgroundColor = Xamarin.Forms.Color.Transparent;
            }
     }
}

Upvotes: 2

Related Questions