框架和BoxView
两个简单的矩形视图通常用于演示目的:
BoxView是一个填充矩形。 它从View派生并定义了一个Color属性,其默认设置为Color.Default,默认情况下是透明的。
框架显示围绕某些内容的矩形边框。 框架通过ContentView从布局派生,从中继承Content属性。 Frame的内容可以是单个视图或包含一堆视图的布局。 从VisualElement中,Frame继承了BackgroundColor属性,该属性在iPhone上是白色的,但在Android和Windows Phone上是透明的。 从Layout中,Frame继承Padding属性,将它初始化为20个单位,以给内容留出一点喘息空间。 框架本身定义了默认情况下为true的HasShadow属性(但阴影仅在iOS设备上显示)以及默认情况下为透明但不影响iOS阴影的OutlineColor属性,该阴影始终为黑色,并且在HasShadow为 设置为true。
框架轮廓和BoxView默认情况下都是透明的,所以你可能会有点不确定如何在不使用不同平台的颜色的情况下对它们着色。 一个不错的选择是Color.Accent,无论如何保证显示。 或者,您可以控制着色背景以及框架轮廓和BoxView。
如果BoxView或Frame的大小没有任何限制 - 也就是说,如果它不在StackLayout中,并且其HorizontalOptions和VerticalOptions设置为LayoutOptions-.Fill的默认值,则这些视图会展开以填充其容器。
例如,下面是一个程序,其中心标签设置为Frame的Content属性:
点击(此处)折叠或打开
public class FramedTextPage : ContentPage
{
public FramedTextPage()
{
Padding = new Thickness(20);
Content = new Frame
{
OutlineColor = Color.Accent,
Content = new Label
{
Text = "I've been framed!",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
}
};
}
}
标签以框架为中心,但框架填充了整个页面,如果页面没有在所有边上都填充20,您甚至可能无法清楚地看到框架:
要显示居中的框架文本,您需要将Frame(而不是Label)上的HorizontalOptions和VerticalOptions属性设置为LayoutOptions.Center:
点击(此处)折叠或打开
public class FramedTextPage : ContentPage
{
public FramedTextPage()
{
Padding = new Thickness(20);
Content = new Frame
{
OutlineColor = Color.Accent,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
Content = new Label
{
Text = "I've been framed!",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label))
}
};
}
}
现在,该框架将文本(但框架的20个单元的默认填充)包含在页面的中心:
本章示例代码中包含的FramedText版本可以自由地为每件事物提供自定义颜色:
点击(此处)折叠或打开
public class FramedTextPage : ContentPage
{
public FramedTextPage()
{
BackgroundColor = Color.Aqua;
Content = new Frame
{
OutlineColor = Color.Black,
BackgroundColor = Color.Yellow,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
Content = new Label
{
Text = "I've been framed!",
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
FontAttributes = FontAttributes.Italic,
TextColor = Color.Blue
}
};
}
}
结果在所有三个平台上看起来大致相同:
尝试将BoxView设置为ContentPage的Content属性,如下所示:
点击(此处)折叠或打开
public class SizedBoxViewPage : ContentPage
{
public SizedBoxViewPage()
{
Content = new BoxView
{
Color = Color.Accent
};
}
}
一定要设置颜色属性,以便您可以看到它。 BoxView会填充其容器的整个区域,就像Label使用默认的HorizontalOptions或VerticalOptions设置一样:
它甚至是iOS状态栏的底层!
现在尝试设置BoxView的HorizontalOptions和VerticalOptions属性
除了Fill之外的其他内容,如下面的代码示例所示:
点击(此处)折叠或打开
public class SizedBoxViewPage : ContentPage
{
public SizedBoxViewPage()
{
Content = new BoxView
{
Color = Color.Accent,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center
};
}
}
在这种情况下,BoxView将采用40单位平方的默认尺寸:
BoxView现在是40单位平方,因为BoxView将其WidthRequest和HeightRequest属性初始化为40.这两个属性需要一点解释:
VisualElement定义宽度和高度属性,但这些属性是只读的。
VisualElement还定义了可设置和可获取的WidthRequest和HeightRequest属性。通常,所有这些属性都被初始化为-1(这实际上意味着它们是未定义的),但是某些View衍生物(如BoxView)会将WidthRequest和HeightRequest属性设置为特定值。
在页面组织完其子项的布局并呈现所有视觉效果后,“宽度”和“高度”属性将指示每个视图的实际尺寸 - 视图在屏幕上占用的区域。由于宽度和高度是只读的,因此仅供参考。 (第5章“处理大小”介绍了如何处理这些值。)
如果你想要一个视图是一个特定的大小,你可以设置WidthRequest和HeightRequest属性。但是,这些属性表明(如他们的名字所示)要求的尺寸或首选尺寸。如果允许视图填充其容器,则这些属性将被忽略。
通过覆盖OnSizeRequest方法,BoxView将其默认大小设置为值40。如果没有其他人对此问题有任何意见,您可以将这些设置视为BoxView希望的大小。您已经看到,当允许BoxView填充页面时,忽略WidthRequest和HeightRequest。如果HorizontalOptions设置为LayoutOptions.Left,Center或Right,或者BoxView是水平StackLayout的子项,则WidthRequest将启动。 HeightRequest行为相似。
以下是本章代码中包含的SizedBoxView程序的版本:
点击(此处)折叠或打开
public class SizedBoxViewPage : ContentPage
{
public SizedBoxViewPage()
{
BackgroundColor = Color.Pink;
Content = new BoxView
{
Color = Color.Navy,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
WidthRequest = 200,
HeightRequest = 100
};
}
}
现在我们得到一个具有特定大小和明确设置的颜色的BoxView:
让我们在增强的颜色列表中使用Frame和BoxView。 ColorBlocks程序有一个页面构造器,它几乎与ReflectedColors中的构造器完全相同,除了它调用名为CreateColorView的方法而不是CreateColorLabel。 这是该方法:
点击(此处)折叠或打开
class ColorBlocksPage : ContentPage
{
...
View CreateColorView(Color color, string name)
{
return new Frame
{
OutlineColor = Color.Accent,
Padding = new Thickness(5),
Content = new StackLayout
{
Orientation = StackOrientation.Horizontal,
Spacing = 15,
Children =
{
new BoxView
{
Color = color
},
new Label
{
Text = name,
FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)),
FontAttributes = FontAttributes.Bold,
VerticalOptions = LayoutOptions.Center,
HorizontalOptions = LayoutOptions.StartAndExpand
},
new StackLayout
{
Children =
{
new Label
{
Text = String.Format("{0:X2}-{1:X2}-{2:X2}",
(int)(255 * color.R),
(int)(255 * color.G),
(int)(255 * color.B)),
VerticalOptions = LayoutOptions.CenterAndExpand,
IsVisible = color != Color.Default
},
new Label
{
Text = String.Format("{0:F2}, {1:F2}, {2:F2}",
color.Hue,
color.Saturation,
color.Luminosity),
VerticalOptions = LayoutOptions.CenterAndExpand,
IsVisible = color != Color.Default
}
},
HorizontalOptions = LayoutOptions.End
}
}
}
};
}
}
CreateColorView方法返回一个Frame,其中包含一个带有指示颜色的BoxView的水平StackLayout,用于指定颜色名称的Label以及用于RGB合成和Hue,Saturation和Luminosity值的另外两个Label视图的另一个StackLayout。 RGB和HSL显示对Color.Default值没有意义,所以在这种情况下,内部StackLayout的IsVisible属性设置为false。 StackLayout仍然存在,但在页面呈现时忽略它。
该程序不知道哪个元素将决定每个颜色项目的高度 - BoxView,具有颜色名称的标签或具有RGB和HSL值的两个Label视图 - 因此它将确定所有Label视图的中心。 正如你所看到的,BoxView在高度上展开以适应文本的高度:
现在这是一个可滚动的颜色列表,开始是我们可以引以为豪的事情。