2017-05-23 12 views
0

現在、データを収集するときに、カスタム製の回転ローディングホイールを実装しようとしています。私が現在直面している問題は、コードのどこかでactivityImage.IsVisibleをfalseにすると、ホイールが回転しないことです。イメージはwhileループでは回転しません。Xamarinフォーム

私が行っているのは、ページに入り、データが収集され、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;を完全に取り除くと、ホイールが回転しますが、データが収集されるとホイールが取り外されたり回転が停止したりすることは明らかです。

答えて

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 
} 

アニメーションをもう一度やりなおすには、これを実行してください。 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; 
    } 
} 
+0

で終わるだろう非常にうまく動作するようです! –

関連する問題