【问题标题】:Xamarin Forms Redraw StackLayout on Device Orientation ChangeXamarin Forms 在设备方向更改时重绘 StackLayout
【发布时间】:2019-02-12 08:54:34
【问题描述】:

在我的 MainPage.xaml(这是一个 ContentPage)中,我有一个 GradientColorStack

<local:GradientColorStack x:Name="ColorStack" StartColor="#FF0000" EndColor="#FFFF00">

这个类有 StackLayout 作为一个基类,它呈现一个有渐变颜色填充的背景。我从here 得到这个想法。

public class GradientColorStack : StackLayout

问题是在设备方向改变时,背景颜色填充没有重新绘制。因此,在横向时,有一个用黑色填充的大间隙,您可以通过 GradientColorStack 看到 ContentPage 背景。

有没有办法强制 GradientColorStack 在设备方向更改时重新绘制?

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    iOS 版本

    我在渲染器类中添加了以下方法:

    protected override void OnElementPropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        SetNeedsDisplay();
        base.OnElementPropertyChanged(sender, e);
    }
    

    这会导致在屏幕方向事件上调用同一类的Draw() 方法。在Draw() 中,我现在找到现有的 CAGradientLayer(如果存在)并将其从超级层中删除,然后让Draw() 例程然后计算一个新的 CAGradientLayer像往常一样,然后它像往常一样将其添加到 NativeView.Layer.Sublayers 集合中。

    感谢@SHUBHAM SHARMA 提供使用SetNeedsDisplay() 的提示,但还需要this post 才能使解决方案正常工作。


    安卓版

    事实证明,Android 版本已经可以正确重绘渐变层(请参阅tutorial)。我认为这是因为我的渲染器类中的以下方法:

    protected override void OnElementChanged(ElementChangedEventArgs<StackLayout> e)
    {
        base.OnElementChanged(e);
    
        if (e.OldElement != null || Element == null)
        {
            return;
        }
    
        var stack = e.NewElement as GradientColorStack;
        this.StartColor = stack.StartColor;
        this.EndColor = stack.EndColor;
    }
    

    【讨论】:

    • 请注意,这里的 OnElementPropertyChanged 代码在 any 属性更改时调用 SetNeedsDisplay。对于在慢速设备上运行的复杂显示,可能想在方法中放置一个断点,找出e.PropertyName 发送的内容(旋转手机时可能触发多个,不确定) ,然后选择一个属性来执行 SetNeedsDisplay。 if (e.PropertyName == ...) SetNeedsDisplay();我不确定这是否重要——也许只是一个重新布局——只是提一下,以防它在旋转时可能有助于提高性能。或者避免其他时间不必要的重绘。
    【解决方案2】:

    您可以在 android Renderer 中使用 ForceLayout() 和在 iOS Renderer 中使用 SetNeedDisplay() 因为这些功能正在强制刷新布局。

    【讨论】:

    • 好的,但是我使用渲染器中的什么方法或事件处理程序来调用它们? iOS 和 Android 都是 GradientColorStackRenderer : VisualElementRenderer
    • 您可以在设备的方向改变时使用,例如在 iOS 中的 ViewDidLoad() 和在 Android 中,您必须创建委托并立即编写 forclayout() 并在 OnConfigurationChanged(Configuration newConfig) 上调用它mainActivity 上的函数。
    • 抱歉,这些信息不够具体,我无法使用。例如,我尝试将 ViewDidLoad() 添加到我的 iOS GradientColorStackRenderer 类并得到 GradientColorStackRenderer.cs(30,30): Error CS0115: 'GradientColorStackRenderer.ViewDidLoad()': no proper method found to override (CS0115) (MyProject.iOS)
    猜你喜欢
    • 2016-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 2017-12-09
    • 1970-01-01
    相关资源
    最近更新 更多