我正在尝试在收集数据时实施定制的旋转加载轮。我目前面临的问题是,如果我在代码中的某个位置使activityImage.IsVisible为false,则轮子永远不会开始旋转。
我正在做的是将图像设置为可见true一旦我进入页面并收集数据直到数据被收集并且我将其设置为false然后带有图像的while循环应该停止旋转。
但是使用我当前的代码,图像变得可见并且看起来不可见,但图像不会旋转。
这就是我正在使用的:
收集数据:
public async void GetData ()
{
var getData = await phpApi.getData(category);
activityImage.IsVisible = true;
loadLoadingWheel();
foreach (var items in getData["results"])
{
...gathering data
}
activityImage.IsVisible = false;
}
图像旋转功能:
async Task loadLoadingWheel()
{
while (activityImage.isVisible)
{
await activityImage.RelRotateTo(500, 1000, Easing.SinOut);
}
}
为什么车轮不旋转?如果我完全移除activityImage.IsVisible = false;
轮子旋转但显然轮子没有被移除/一旦数据被收集就停止旋转。
答案 0 :(得分:1)
从它看起来,您尝试在后台线程上更新UI。您只能更新主线程上的UI。我做了一些非常相似的事情,让我自己的动画发生。这非常笨拙,其他人可能有更好的解决方案。事实上,我会把钱投给有更好解决方案的人。这些内容可能适合您:
private CancellationTokenSource animateTimerCancellationTokenSource;
async void StartAnimationTimer(CancellationTokenSource tokenSource)
{
try
{
//maintain a reference to the token so we can cancel when needed
animateTimerCancellationTokenSource = tokenSource;
int idleTime = 1000; //ms
await Task.Delay(TimeSpan.FromMilliseconds(idleTime), tokenSource.Token);
//Do something here
Device.BeginInvokeOnMainThread(() =>
{
if (activityImage.isVisible)
{
activityImage.RelRotateTo(500, 1000, Easing.SinOut);
//Do this if you want to have it possibly happen again
StartAnimationTimer(new CancellationTokenSource());
}
});
}
catch (TaskCanceledException ex)
{
//if we cancel/reset, this catch block gets called
Debug.WriteLine(ex);
}
// if we reach here, this timer has stopped
}
要取消动画再次发生,您可以运行此功能。
if (animateTimerCancellationTokenSource != null)
{
animateTimerCancellationTokenSource.Cancel();
animateTimerCancellationTokenSource.Dispose();
animateTimerCancellationTokenSource = null;
}
这里的关键是这个人:Device.BeginInvokeOnMainThread(() => { });
您需要在主线程上完成所有UI工作。这允许您从后台线程调用主线程上的东西,这是您async
方法正在使用的方法。
所以你最终会得到这个
public async void GetData ()
{
var getData = await phpApi.getData(category);
activityImage.IsVisible = true;
StartAnimationTimer(new CancellationTokenSource());
foreach (var items in getData["results"])
{
...gathering data
}
activityImage.IsVisible = false;
if (animateTimerCancellationTokenSource != null)
{
animateTimerCancellationTokenSource.Cancel();
animateTimerCancellationTokenSource.Dispose();
animateTimerCancellationTokenSource = null;
}
}