OnResume 页面内容不更新

OnResume Page Content not updating

我有一个 Android 小部件按钮,当按下该按钮时,它会将一条记录插入到 SQLite 数据库中。

我在这种情况下使用该应用程序时遇到问题:

  1. 用户暂停应用程序以使用其设备主屏幕上的小部件。
  2. 用户按下插入新记录的小部件按钮。
  3. 用户恢复 Xamarin.Forms 页面。

当页面恢复时,会自动调用OnAppearing。但是,内容没有更新。 labelDailyCount 应该更新以显示新的每日计数,因为 UpdateDailyCount() 被正确调用。

记录被正确插入数据库(如移动到不同的页面,然后返回首页,记录显示)。当用户暂停应用程序时,计时器继续 运行,但在恢复页面时,UI 不会更新。

如果我将 Device.BeginInvokeOnMainThread(() => UpdateDailyCount()); 放在 Device.BeginInvokeOnMainThread(() => CalculateTimeDifference()); 之后,那么 UI 会正确更新,但这并不理想,因为 UpdateDailyCount() 会每秒被调用。

private Book latestBook;  

protected override void OnAppearing() 
{      
    base.OnAppearing();      
    latestBook = App.Database.GetRecentBookDate().FirstOrDefault();  
    UpdateDailyCount();
    Device.StartTimer(TimeSpan.FromSeconds(1), () =>       
    {          
       Device.BeginInvokeOnMainThread(() => CalculateTimeDifference());          
       return true; 
    }); 
}  

void BtnAdd_Clicked(object sender, EventArgs e) {       
     Book book = new Book        
     {           
         BookSaveTime = DateTime.Now       
     };       
     App.Database.SaveBook(book);       
     latestBook = book;
}  

void CalculateTimeDifference() {        
     if (latestBook == null) 
     {         
         this.labelTimeSince.Text = "-";        
     }        
     else        
     {           
         var timeDifference = DateTime.Now - latestBook.BookSaveTime;  
         this.labelTimeSince.Text = timeDifference.ToString("HH:mm:ss");        
     } 
}

void UpdateDailyCount() {        
     int dailyCount = App.Database.GetDailyCount();
     this.labelDailyCount.Text = dailyCount.ToString();
} 

为什么 labelDailyCount.Text 在页面恢复时没有更新 - 尽管 UpdateDailyCount() 被正确调用。?

回答

ContentPage.OnAppearing 当用户从后台恢复应用程序时不会触发。

您需要覆盖 Application.OnResume 以处理用户从后台恢复应用程序时的事件:

public class App : Application
{
    // ...

    protected override async void OnResume()
    { 
        base.OnResume();

        // Handle app resuming from background
    }

    // ...
}

解决方案

我建议在 Application 中创建一个 Resumed 事件,然后您可以从任何 ContentPage.

订阅它
public class App : Application
{
    // ...

    public static event EventHandler Resumed;

    protected override async void OnResume()
    {
        base.OnResume();

        Resumed?.Invoke(this, EventArgs.Empty);
    }

    // ...
}

class BookPage : ContentPage
{
    public BookContentPage()
    {
        InitializeComponent();

        App.Resumed += HandleResumed;
    }

    void HandleResumed(object sender, System.EventArgs e)
    {
        latestBook = App.Database.GetRecentBookDate().FirstOrDefault();  
        UpdateDailyCount();
        Device.StartTimer(TimeSpan.FromSeconds(1), () =>       
        {          
           Device.BeginInvokeOnMainThread(() => CalculateTimeDifference());          
          return true; 
        }); 
    }
}