第二十一章:变换(六)

两个按钮的Clicked处理程序每个都启动一个独立的动画。 第一个Button的Clicked处理程序将其Scale属性从1设置为5并再次返回,而第二个Button的Clicked处理程序将其FontSize属性设置为1到5的比例因子,然后再返回。
这是关于中途的Scale属性的动画:
2019_01_11_092557
正如您所看到的,Button的缩放不会考虑屏幕上可能出现的任何其他内容,而在iOS和Windows 10 Mobile屏幕上,您实际上可以通过Button的透明区域看到顶部BoxView元素,而 opaque Android Button完全隐藏了顶级BoxView。 顶部按钮下面的BoxView实际上位于按钮的顶部,并且在所有三个平台上都可见。
在三个平台上,FontSize属性的动画增加处理方式略有不同:
2019_01_11_092741
在iOS上,Button文本在中间被截断,Button按钮保持相同的高度。在Android上,Button文本换行,放大的Button将两个BoxView元素推到一边。 Windows运行时按钮也会截断文本,但方式与iOS不同,与Android一样,增加的Button高度也会推动两个BoxView元素。
动画“缩放”属性不会影响布局,但动画化FontSize属性显然会影响布局。
ButtonScaler中实现的小动画系统可以独立和同时为两个按钮设置动画,但它仍然存在严重的缺陷。当该Button正在设置动画时,尝试点击按钮。将为该Button启动一个新动画,这两个动画将相互干扰。
有几种方法可以解决这个问题。一种可能性是将CancellationToken值作为AnimateAndBack方法的参数包含在内,以便可以取消该方法。 (您可以将相同的CancellationToken值传递给Task.Delay调用。)这将允许Button的Clicked处理程序在开始新动画之前取消任何正在进行的动画。
另一个选项是AnimateAndBack返回Task对象。这允许按钮的Clicked处理程序将await运算符与AnimateAndBack一起使用。在AnimateAndBack完成动画时,Button可以在调用AnimateAndBack之前轻松禁用自身并重新启用自身。
无论如何,如果您希望通过短暂增加和减少按钮大小来向用户实施反馈,那么动画缩放比使用FontSize更安全,更有效。您将在下一章动画和第23章“触发器和行为”中看到其他技术。
Scale属性的另一个用途是调整元素大小以适合可用空间。 您可能会在第5章“处理大小”结束时回想起FitToSizeClock程序。您可以使用Scale属性执行非常类似的操作,但不需要进行估计或递归计算。
ScaleToSize程序的XAML文件包含缺少某些文本的标签,并且还缺少“缩放”设置以使标签更大:

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="ScaleToSize.ScaleToSizePage"
             SizeChanged="OnSizeChanged">
 
    <Label x:Name="label"
           HorizontalOptions="Center"
           VerticalOptions="Center"
           SizeChanged="OnSizeChanged" />
</ContentPage>

ContentPage和Label都安装了SizeChanged处理程序,它们都使用相同的处理程序。 此处理程序只是将Label的Scale属性设置为页面宽度和高度的最小值除以Label的宽度和高度:

public partial class ScaleToSizePage : ContentPage
{
    public ScaleToSizePage()
    {
        InitializeComponent();
        UpdateLoop();
    }
    async void UpdateLoop()
    {
        while (true)
        {
            label.Text = DateTime.Now.ToString("T");
            await Task.Delay(1000);
        }
    }
    void OnSizeChanged(object sender, EventArgs args)
    {
        label.Scale = Math.Min(Width / label.Width, Height / label.Height);
    }
}

因为设置Scale属性不会触发另一个SizeChanged事件,所以不存在触发无限递归循环的危险。 但使用Task.Delay的实际无限循环使Label更新为当前时间:
2019_01_11_093255
当然,将手机侧向转动会使标签更大:
2019_01_11_093310
在这里,您可以检测到与Android和Windows运行时相比,iOS中Scale属性的实现略有不同。 在Android和Windows上,生成的文本看起来好像是用大字体绘制的。 但是,iOS屏幕上的文字看起来有点模糊。 当操作系统光栅化预分频标签时,会出现这种模糊,这意味着操作系统将其转换为位图。 然后根据“比例”设置扩展位图。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值