Rg.Plugins.Popup
Rg.Plugins.Popup copied to clipboard
Popup page flickers on appearing
🐛 Bug Report
If the popup page has a ListView in its content, and ItemsSource of that ListView gets set in OnSizeAllocated()
or OnAppearingAnimationBegin
, the appearing animation gets broken and the page flickers: at first the page is shown in the center of the screen for a short moment, and then the actual animation starts. The behavior is pretty much the same as in #404
It can be reproduced with the latest X.F 5.0.0.2196 and Rg.Plugins.Popup 2.0.0.14.
The reproduction sample: RgPopupAppearingBug.zip
public class BuggedPopup : PopupPage
{
private readonly ListView _listView;
private bool _isInitialized;
public BuggedPopup()
{
CloseWhenBackgroundIsClicked = false;
Animation = new MoveAnimation
{
PositionIn = MoveAnimationOptions.Bottom,
PositionOut = MoveAnimationOptions.Bottom,
DurationIn = 400,
DurationOut = 300,
EasingIn = Easing.SinOut,
EasingOut = Easing.SinIn,
HasBackgroundAnimation = true
};
_listView = new ListView(ListViewCachingStrategy.RecycleElementAndDataTemplate)
{
BackgroundColor = Color.Transparent,
HasUnevenRows = true,
ItemTemplate = new DataTemplate(() =>
{
var label = new Label();
label.FontAttributes = FontAttributes.Bold;
label.SetBinding(Label.TextProperty, new Binding("."));
return new ViewCell
{
View = label
};
})
};
Content = new Frame
{
HeightRequest = 300,
WidthRequest = 500,
HorizontalOptions = LayoutOptions.Center,
VerticalOptions = LayoutOptions.Center,
BorderColor = Color.Red,
Content = new StackLayout
{
Orientation = StackOrientation.Vertical,
Children =
{
new Button
{
Text = "Close",
Command = new Command(() => this.Navigation.PopPopupAsync())
},
_listView
}
}
};
}
protected override void OnAppearingAnimationBegin()
{
if (!_isInitialized)
{
/*
* This is the key place.
*
* Setting ItemsSource in OnSizeAllocated or OnAppearingAnimationBegin
* breaks the appearing animation.
*/
_isInitialized = true;
_listView.ItemsSource = Enumerable.Repeat(
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
30)
.ToList();
}
base.OnAppearingAnimationBegin();
}
}
https://user-images.githubusercontent.com/2004960/138688360-3120e2f5-fb5b-4203-a683-588dc5d5b21a.mp4
Expected behavior
The page appearing animation is smooth.
Reproduction steps
Open attached project, run, and click "Show Popup".
Configuration
Version: 2.0.0.14
Platform:
- [x] :iphone: iOS
- [ ] :robot: Android
- [ ] :checkered_flag: WPF
- [ ] :earth_americas: UWP
- [ ] :apple: MacOS
- [ ] :tv: tvOS
- [ ] :monkey: Xamarin.Forms
I am also experiencing this issue
Same here, was also in 2.0.0.13
.
Any update on this? we have users reporting this happens quite frequently now... Ive started looking into a little more and seems like it has something to do with this line taskList.Add(content.TranslateTo(_defaultTranslationX, _defaultTranslationY, DurationIn, EasingIn)); seems similar to issue #404
Same here guys
Yep, I see this also. Happens on all my popups, not just those with ListViews.
Has anyone been able to solve this? This happens on every popup for us. Thanks.
Still happening on 2.1.0 as well, just an FYI
any workaround?
Any update on a fix for this? I took an approach of overriding the MoveAnimation and adding a Task.Delay to the OnAppearing and it didn't seem to help. Pretty annoying bug that takes away a clean user-experience.
I am having this issue as well. Has anyone migrated to a different nuget due to this issue?
I am having this issue as well. Has anyone migrated to a different nuget due to this issue?
You don't really have to use this plugin, just remove it from your solution and make the same functionality with only xamarin
I had the same problem here - iOS would flicker not on every popup, but maybe 1 out of every 3 or so. The approach that I took was to extend the animation class we are using to be a custom animation:
public class SystemDialogAnimation: MoveAnimation
The thing you need to change is in the Appearing method, so if you override that and set another task to update opacity, you can avoid the flicker. I think the issue happens where timing can be out of order, so a call to make the page visible happens right before the call to execute the animation, resulting in a couple of frames where the popup is visible in the initial position.
public override Task Appearing(View content, PopupPage page)
{
var taskList = new List<Task>
{
base.Appearing(content, page)
};
if (content != null)
{
// set initial opacity
page.Opacity = 0;
var topOffset = GetTopOffset(content, page);
var leftOffset = GetLeftOffset(content, page);
if (PositionIn == MoveAnimationOptions.Top)
{
content.TranslationY = -topOffset;
}
else if (PositionIn == MoveAnimationOptions.Bottom)
{
content.TranslationY = topOffset;
}
else if (PositionIn == MoveAnimationOptions.Left)
{
content.TranslationX = -leftOffset;
}
else if (PositionIn == MoveAnimationOptions.Right)
{
content.TranslationX = leftOffset;
}
// quickly make the page opaque to cover up the misplaced frames
taskList.Add(page.FadeTo(100, 1));
taskList.Add(content.TranslateTo(_defaultTranslationX, _defaultTranslationY, DurationIn, EasingIn));
}
ShowPage(page);
return Task.WhenAll(taskList);
}
I'll create a PR to hopefully get this pulled in, but in the meantime this might be able to get you by.
@jlbeard84 works like a charm, thanks!
@jlbeard84 you're such a bro, I implemented this and it works. It's still required even with v2.1 NuGet package.
@jlbeard84 thank u