第二十六章:自定义布局(四)

简介: 无限约束现在这里有一些标记,起初看起来与前面的例子非常相似,但有很大的不同:<ContentPage __ Padding="20"> <StackLayout> <Label Text="Sample text" /> __ </StackLayout></ContentPage>ContentPage仍然使用参数(0,0,360,640)进行初始布局调用,而LayoutChildren覆盖的参数是(20,20,320,600)。

无限约束
现在这里有一些标记,起初看起来与前面的例子非常相似,但有很大的不同:

<ContentPage __ Padding="20">
    <StackLayout>
        <Label Text="Sample text" />
        __
    </StackLayout>
</ContentPage>

ContentPage仍然使用参数(0,0,360,640)进行初始布局调用,而LayoutChildren覆盖的参数是(20,20,320,600)。它有一个孩子,StackLayout。 StackLayout具有LayoutOptions.Fill的Horizo​​ntalOptions和VerticalOptions的默认设置,这意味着StackLayout可以相对于ContentPage定位,布局调用为(20,20,320,600)。
这导致StackLayout获得一个参数为(0,0,320,600)的LayoutChildren调用。 StackLayout如何确定其子女的大小和位置?
正如我们从第4章开始使用StackLayout所知道的那样,垂直StackLayout为其子级提供与其自身相同的水平大小,但是根据子级需要提供垂直大小。这意味着StackLayout必须在调用Layout之前在其所有子节点上调用GetSizeRequest。但是它应该用GetSizeRequest调用指定什么约束?
最初的冲动可能是StackLayout在其子节点上调用GetSizeRequest,其约束条件反映了它自己的大小(320,600)。但那不对。 StackLayout不会将其子项限制在自己的高度。它允许孩子成为他们需要的任何高度。这意味着高度约束实际上应该是无限的。
这是事实。 StackLayout在其子节点上调用GetSizeRequest,其高度为(320,∞),或者就.NET而言(320,Double.PositiveInfinity)。
这很重要:传递给GetSizeRequest和OnSizeRequest的约束可以从0到Double.PositiveInfinity。 但是,GetSizeRequest和OnSizeRequest永远不会通过返回SizeRequest值并将属性设置为Double.PositiveInfinity来请求无限维。
让我们尝试另一种常见的布局模式:

<ContentPage __ Padding="20">
    <ScrollView>
        <StackLayout>
            <Label Text="Sample text" />
            __
        </StackLayout>
    </ScrollView>
</ContentPage>

像往常一样,ContentPage使用边界矩形(0,0,360,640)调用Layout,并调用其参数为(20,20,320,600)的LayoutChildren方法。 ScrollView具有LayoutOptions.Fill的默认Horizo​​ntalOptions和VerticalOptions设置,因此页面不需要知道ScrollView的大小。该页面简单地调用ScrollView的Layout方法,其边界矩形为(20,20,320,600)。
然后ScrollView调用其LayoutChildren方法,参数为(0,0,320,600)。它需要确定其子项的大小(StackLayout),因此它调用StackLayout的GetSizeRequest方法。约束应该是什么?
在一般情况下,StackLayout的高度将大于ScrollView的高度。这就是为什么你在可视树中包含ScrollView的原因!如果要成功滚动其子项,ScrollView需要知道该高度。因此,ScrollView使用(320,Double.PositiveInfinity)的约束调用StackLayout的GetSizeRequest方法。这转换为使用相同的约束参数调用OnSizeRequest,StackLayout覆盖并处理这些参数。
您还可以将无限约束视为自动调整指示。垂直StackLayout请求具有无限高度约束的子大小以获取子请求的高度。类似地,行高或行宽为GridLength.Auto的Grid单元格的子节点将看到无限的heightConstraint或widthConstraint,或两者。具有LayoutBounds高度或宽度Auto的AbsoluteLayout的子项也将看到无限的heightConstraint或widthConstraint。
有时,受约束和不受约束的词语用于指代这些差异。当元素接收到具有非无限参数的GetSizeRequest方法的调用时,它会受到约束。该元素被约束为特定大小。当一个元素调用GetSizeRequest并且一个或两个参数等于Double.PositiveInfinity时,该元素是不受约束的。有时,部分约束这个术语用于引用带有一个Double.PositiveInfinity参数的GetSizeRequest调用,而术语完全约束则表明两个参数都不是无限的。
通过从Layout 派生编写自己的自定义布局类时,必须覆盖OnSizeRequest和LayoutChildren方法,并且必须注意在某些情况下,OnSizeRequest的一个或两个约束参数将为Double.PositiveInfinity。 但是,OnSizeRequest绝不能请求无限大小。

目录
相关文章
|
6月前
|
定位技术 iOS开发
自动布局xib页面的机型匹配精典问题及解决方案
自动布局xib页面的机型匹配精典问题及解决方案
42 0
|
iOS开发
iOS动画开发之三——UIView的转场切换
iOS动画开发之三——UIView的转场切换
378 0
|
JavaScript Android开发
第二十六章:自定义布局(十)
不允许无约束的尺寸!有时您希望在屏幕上看到所有内容,可能是一系列大小统一的行和列。您可以使用带有星号定义的所有行和列定义的Grid执行类似的操作,以使它们具有相同的大小。唯一的问题是您可能还希望行数和列数基于子节点数,并针对屏幕空间的最佳使用进行了优化。
835 0
|
存储 缓存 JavaScript
第二十六章:自定义布局(九)
编码的一些规则从上面的讨论中,您可以为自己的Layout 衍生物制定几个规则:规则1:如果布局类定义了诸如间距或方向等属性,则这些属性应由可绑定属性支持。 在大多数情况下,这些可绑定属性的属性更改处理程序应调用InvalidateLayout。
2070 0
|
JavaScript Android开发
第二十六章:自定义布局(八)
失效假设您已在页面上组装了一些布局和视图,并且由于某种原因,代码隐藏文件(或者可能是触发器或行为)会更改Button的文本,或者可能只是字体大小或属性。 该更改可能会影响按钮的大小,这可能会对页面其余部分的布局更改产生连锁反应。
3421 0
|
JavaScript Android开发
第二十六章:自定义布局(七)
垂直和水平定位简化在VerticalStack中,LayoutChildren覆盖的末尾是一个switch语句,它有助于根据子级的HorizontalOptions属性设置水平定位每个子级。 这是整个方法: public class VerticalStack : Layout<View> { ...
872 0
|
JavaScript Android开发
第二十六章:自定义布局(十二)
更多附加的可绑定属性附加的可绑定属性也可以在XAML中设置并使用Style设置。 为了了解它是如何工作的,让我们检查一个名为CartesianLayout的类,它模仿一个二维的,四象限的笛卡尔坐标系。
540 0
|
JavaScript Android开发
第二十六章:自定义布局(六)
从Layout派生 我们现在拥有足够的知识来创建我们自己的布局类。布局中涉及的大多数公共和受保护方法都是由非泛型布局类定义的。 Layout 类派生自Layout,并将泛型类型约束为View及其派生类。
765 0
|
JavaScript Android开发
第二十六章:自定义布局(十一)
重叠的子项Layout 类可以在其子项上调用Layout方法,以便子项重叠吗?是的,但这可能会在你的脑海中提出另一个问题:什么决定孩子们的呈现顺序?哪些孩子看似坐在前台,可能部分或完全掩盖了背景中显示的其他孩子?在某些图形环境中,程序员可以访问名为Z-index的值。
643 0