Xamarin.forms 表单:在数据加载期间,当IsBusy为true时,如何至少显示一次乐透动画?
在我的Xamarin.Forms项目中,我想在API调用期间或在Xamarin.forms 表单:在数据加载期间,当IsBusy为true时,如何至少显示一次乐透动画?,xamarin.forms,mvvm,loading,lottie,lottie-xamarin,Xamarin.forms,Mvvm,Loading,Lottie,Lottie Xamarin,在我的Xamarin.Forms项目中,我想在API调用期间或在WebView中加载网站期间显示乐蒂动画 为此,我将乐蒂动画的IsVisible属性限定为我的视图模型的IsBusy属性:这很有效 <lottie:AnimationView Animation="resource://lottie_loading.json?assembly=MyApp" AnimationSource="EmbeddedResource"
WebView
中加载网站期间显示乐蒂动画
为此,我将乐蒂动画的IsVisible
属性限定为我的视图模型的IsBusy
属性:这很有效
<lottie:AnimationView Animation="resource://lottie_loading.json?assembly=MyApp"
AnimationSource="EmbeddedResource"
BackgroundColor="Transparent"
AutoPlay="True"
RepeatMode="Infinite"
IsVisible="{Binding IsBusy}">
但是加载持续时间有时非常短,因此我想找到一种方法,在隐藏乐蒂动画之前,完整地显示乐蒂动画
=>可能吗?实现这一目标的更好方法是什么?
我想在API调用期间显示乐透动画
在Web视图中加载网站期间:
但装载时间有时很短
加载持续时间取决于完全加载数据/webview的时间。如果您很快加载数据/webview,加载持续时间应该很短。我找到了另一种可行的方法,即使这个解决方案有点繁重并且可以改进 首先,根据建议,我创建了2个
触发器
:
public class PlayLottieAnimationTriggerAction : TriggerAction<AnimationView>
{
protected override void Invoke(AnimationView sender)
{
Debug.WriteLine($"PlayLottieAnimationTriggerAction()");
sender.PlayAnimation();
}
}
public class StopLottieAnimationTriggerAction : TriggerAction<AnimationView>
{
protected override void Invoke(AnimationView sender)
{
Debug.WriteLine($"StopLottieAnimationTriggerAction()");
sender.StopAnimation();
}
}
在我的ViewModel中,我声明了一个属性ShowAnimation
,它与IsBusy
和命令onfinishedanimation
相关,如下所示:
<forms:AnimationView
x:Name="animationView"
BackgroundColor="Transparent"
AutoPlay="True"
IsVisible="{Binding ShowAnimation}"
Animation="resource://lottie_4squares_apricot_blond.json?assembly=Example.Forms"
AnimationSource="EmbeddedResource"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<forms:AnimationView.Triggers>
<MultiTrigger TargetType="forms:AnimationView">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding ShowAnimation}" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<triggers:LottieTriggerAction />
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<actions:StopLottieAnimationTriggerAction />
</MultiTrigger.ExitActions>
</MultiTrigger>
</forms:AnimationView.Triggers>
<forms:AnimationView.Behaviors>
<behaviors:EventToCommandBehavior
EventName="OnFinishedAnimation"
Command="{Binding OnFinishedAnimationCommand}"
CommandParameter="{x:Reference animationView}"/>
</forms:AnimationView.Behaviors>
</forms:AnimationView>
private bool _showAnimation;
public bool ShowAnimation
{
get => _showAnimation;
set => Set(ref _showAnimation, value);
}
public ICommand OnFinishedAnimationCommand
{
get
{
return new Xamarin.Forms.Command<object>(async (object sender) =>
{
if (sender != null)
{
await OnFinishedAnimation(sender);
}
});
}
}
private Task OnFinishedAnimation(object sender)
{
var view = sender as AnimationView;
if (IsBusy)
{
view.PlayAnimation();
}
else
{
ShowAnimation = false;
}
return Task.CompletedTask;
}
private Task WebViewNavigatingAsync(WebNavigatingEventArgs eventArgs)
{
IsBusy = true;
ShowLoadingView = true;
return Task.CompletedTask;
}
private async Task WebViewNavigatedAsync(WebNavigatedEventArgs eventArgs)
{
IsBusy = false;
}
private async Task GetNewsAsync(bool forceRefresh = false)
{
try
{
ShowErrorView = false;
ErrorKind = ServiceErrorKind.None;
IsBusy = true;
ShowLoadingView = true;
var _news = await _dataService.GetNews(forceRefresh);
News = new ObservableCollection<News>(_news);
}
catch (Exception ex)
{
ErrorKind = ServiceErrorKind.ServiceIssue;
}
finally
{
IsBusy = false;
await SetServiceError();
}
但是,由于在出现问题(超时、无法访问服务器等)时,我还显示了一个错误视图和一个重新加载/重试按钮,因此我必须添加一些代码:
private async Task WebViewNavigatedAsync(WebNavigatedEventArgs eventArgs)
{
IsBusy = false;
// for display loading animation on Refresh
while (ShowLoadingView)
await Task.Delay(50);
SetServiceError();
}
如果加载程序与数据加载相关,则ShowLoadingView
属性设置如下:
<forms:AnimationView
x:Name="animationView"
BackgroundColor="Transparent"
AutoPlay="True"
IsVisible="{Binding ShowAnimation}"
Animation="resource://lottie_4squares_apricot_blond.json?assembly=Example.Forms"
AnimationSource="EmbeddedResource"
VerticalOptions="FillAndExpand"
HorizontalOptions="FillAndExpand">
<forms:AnimationView.Triggers>
<MultiTrigger TargetType="forms:AnimationView">
<MultiTrigger.Conditions>
<BindingCondition Binding="{Binding ShowAnimation}" Value="True" />
</MultiTrigger.Conditions>
<MultiTrigger.EnterActions>
<triggers:LottieTriggerAction />
</MultiTrigger.EnterActions>
<MultiTrigger.ExitActions>
<actions:StopLottieAnimationTriggerAction />
</MultiTrigger.ExitActions>
</MultiTrigger>
</forms:AnimationView.Triggers>
<forms:AnimationView.Behaviors>
<behaviors:EventToCommandBehavior
EventName="OnFinishedAnimation"
Command="{Binding OnFinishedAnimationCommand}"
CommandParameter="{x:Reference animationView}"/>
</forms:AnimationView.Behaviors>
</forms:AnimationView>
private bool _showAnimation;
public bool ShowAnimation
{
get => _showAnimation;
set => Set(ref _showAnimation, value);
}
public ICommand OnFinishedAnimationCommand
{
get
{
return new Xamarin.Forms.Command<object>(async (object sender) =>
{
if (sender != null)
{
await OnFinishedAnimation(sender);
}
});
}
}
private Task OnFinishedAnimation(object sender)
{
var view = sender as AnimationView;
if (IsBusy)
{
view.PlayAnimation();
}
else
{
ShowAnimation = false;
}
return Task.CompletedTask;
}
private Task WebViewNavigatingAsync(WebNavigatingEventArgs eventArgs)
{
IsBusy = true;
ShowLoadingView = true;
return Task.CompletedTask;
}
private async Task WebViewNavigatedAsync(WebNavigatedEventArgs eventArgs)
{
IsBusy = false;
}
private async Task GetNewsAsync(bool forceRefresh = false)
{
try
{
ShowErrorView = false;
ErrorKind = ServiceErrorKind.None;
IsBusy = true;
ShowLoadingView = true;
var _news = await _dataService.GetNews(forceRefresh);
News = new ObservableCollection<News>(_news);
}
catch (Exception ex)
{
ErrorKind = ServiceErrorKind.ServiceIssue;
}
finally
{
IsBusy = false;
await SetServiceError();
}
请毫不犹豫地告诉我们可以做些什么来优化它。是否有帮助?比如
等待任务。延迟(500)。配置等待(false)
在数据加载方法中可能是这样,但这并不完美,我无法对WebView执行此操作。在更新IsBusy的值之前,将延迟添加到“OnNavigated”中。另外,随着加载时间的变化,这并不完美,您必须在全长动画和真实加载时间之间找到平衡。我的解决方案对您有效吗?如果是,请您接受(单击☑️ 在这个答案的左上角),这样我们就可以帮助更多有同样问题的人:)。您还可以标记自己的解决方案:)。