Reputation: 1029
For my Xamarin.Forms project I need to animate two Xamarin Frame items in parallel, but I just don't understand the example where they use:
async void OnAnimateLabelButtonClicked(object sender, EventArgs e)
{
...
await Task.WhenAll(
label.ColorTo(Color.Red, Color.Blue, c => label.TextColor = c, 5000),
label.ColorTo(Color.Blue, Color.Red, c => label.BackgroundColor = c, 5000));
...
}
Task.WhenAll
which - in my humble opinion - does not guarantee that it runs on the GUI main thread, as no Device.BeginInvokeOnMainThread()
is to be seen.
According to this forums.xamarin.com entry, the preferred way to use multiple animations at a time is via:
Animation a = new Animation();
a.Add(0, 1, new Animation(f => this.GuidanceLabel.Opacity = f, 1, 0, Easing.SinInOut, null));
a.Add(0, 1, new Animation(f => this.EnableAccess.Opacity = f, 1, 0, Easing.SinOut, null));
a.Commit(
owner:this.GuidanceLabel,
name:"DoubleFader",
length:400,
finished:(x, y) =>
{
this.SetPhotoAccessDeniedState();
this.GuidanceLabel.FadeTo(1, 400, Easing.CubicIn);
});
So, I suppose, I have to wrap my animation in a Device.BeginInvokeOnMainThread()
to make it work properly, and for my special animation case, the workflow would be:
Frame1.TranslateYto (-90, duration1);
Frame1.Content.IsVisible = true; // Was formerly false
Frame1.TranslateYto (0, duration2);
And for Frame2 the same in parallel.
So I have tried:
Device.BeginInvokeOnMainThread(() =>
{
Animation a = new Animation();
a.Add(0, 1, new Animation(v => frame1.RotationY = v, 0, -90));
a.Add(0, 1, new Animation(v => frame2.RotationY = v, 0, -90));
a.Commit(
owner: frame1,
name: "flip1",
length: 50,
finished: (x, y) =>
{
frame1.Content.IsVisible = false;
frame2.Content.IsVisible = false;
});
a = new Animation();
a.Add(0, 1, new Animation(v => frame1.RotationY = v, -90, 0));
a.Add(0, 1, new Animation(v => frame2.RotationY = v, -90, 0));
a.Commit(
owner: frame1,
name: "flip2",
length: 250);
});
But it crashes with a NullReferenceExecption...
Maybe someone can shed some more light on the problem?
Upvotes: 1
Views: 1192
Reputation: 10346
I add two Frame control in window and create same animation as you, but I don't have any issue. Here is my code.
<StackLayout>
<Frame
x:Name="frame1"
HorizontalOptions="CenterAndExpand"
VerticalOptions="FillAndExpand">
<Label
HorizontalOptions="CenterAndExpand"
Text="this is test!!!!!!!"
VerticalOptions="CenterAndExpand" />
</Frame>
<Frame x:Name="frame2" HorizontalOptions="CenterAndExpand" VerticalOptions="EndAndExpand">
<Label
HorizontalOptions="CenterAndExpand"
Text="this is test22222222222222!!!!!!!"
VerticalOptions="CenterAndExpand" />
</Frame>
<Button
x:Name="btn1"
Clicked="btn1_Clicked"
HeightRequest="50"
Text="btn1"
WidthRequest="300" />
</StackLayout>
private void btn1_Clicked(object sender, EventArgs e)
{
Device.BeginInvokeOnMainThread(() => {
Animation a = new Animation();
a.Add(0, 1, new Animation(v => frame1.RotationY = v, 0, -90));
a.Add(0, 1, new Animation(v => frame2.RotationY = v, 0, -90));
a.Commit(
owner: frame1,
name: "flip1",
length: 50,
finished: (x, y) =>
{
frame1.Content.IsVisible = false;
frame2.Content.IsVisible = false;
});
a = new Animation();
a.Add(0, 1, new Animation(v => frame1.RotationY = v, -90, 0));
a.Add(0, 1, new Animation(v => frame2.RotationY = v, -90, 0));
a.Commit(
owner: frame1,
name: "flip2",
length: 250);
});
}
Upvotes: 3