在动画制作之前获取Xamarin.Forms ContentView的高度

时间:2018-03-23 15:09:28

标签: xamarin xamarin.forms

我试图在Xamarin.Forms中创建一个从页面顶部开始动画的通知。我非常接近,但在我在页面上设置动画之前,我无法获得ContentView的高度。我已经制作了一个xamarin workbook来演示我的问题,可以在android模拟器上运行。 (猜测它可以在ios / wpf上进行一些修改)

The workbook is available here

问题出在cut :: [[a]] -> [[a]] cut = map (\xs -> drop ((min(length xs)) - length xs) xs) ,我首先将整个内容视图的可见性设置为可见(红色背景)。绿色通知会立即呈现在其最终位置,尽管在设置动画之前设置它在屏幕外的位置的尝试不同。这仅在第一次在页面上动画通知时发生,因为在屏幕上显示动画并再次隐藏后,它的高度可用。

我可以通过将高度偏移硬编码为50来解决这个问题,但为了实现可变高度的一致动画,这并不是要削减它。我还可以创建一个计算行数的方法,然后根据它来动态设置高度,但我希望有一种实际渲染方法,并以某种方式得到组件的实际高度,而不会让用户看到它直到我从我想要的地方开始动画。

ToastNotificationView.AnimateIn()

在InitializeComponent方法中创建布局以支持xamarin工作簿。这可能是出于此问题的目的。

public class ToastNotificationView: ContentView {
    // The notification item to be animated in/out
    private StackLayout MainStackLayout;
    public ToastNotificationView() {
        InitializeComponent(); // Let's pretend workbooks supports xaml

        //Subscribing to notification events
        NotificationService.NotificationAppearing += AnimateIn;
        // TODO: Find out how to unsubscribe in contentview without access to life cycle hooks
    }
    private async void OnDismissClicked(object sender, EventArgs e) {
        await AnimateOut();
    }
    private async Task AnimateOut() {
        await MainStackLayout.TranslateTo(0, -MainStackLayout.Height, 1000);
        IsVisible = false;
    }
    private async void AnimateIn(object sender, EventArgs e) {
        // Make the entire view visible
        IsVisible = true;

        // First time, height is always zero, so we can't set it like this
        MainStackLayout.TranslationY = -MainStackLayout.Height;

        // Attempting to await a 1ms animation to get a height does not result in correct height either
        await MainStackLayout.TranslateTo(0, 0, 1);
        await MainStackLayout.TranslateTo(0, -MainStackLayout.Height, 1);

        //Still does not animate in on initial animation
        await MainStackLayout.TranslateTo(0, 0, 1000);
    }
}

1 个答案:

答案 0 :(得分:1)

您可以使用Measure获取身高:

private async void AnimateIn(object sender, EventArgs e)
{
    var parent = (VisualElement)Parent;
    SizeRequest sizeRequest = MainStackLayout.Measure(parent.Width, parent.Height);

    MainStackLayout.TranslationY = -sizeRequest.Request.Height;

    IsVisible = true;

    await MainStackLayout.TranslateTo(0, 0, 1000);
}