微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

OnResume 页面内容未更新

如何解决OnResume 页面内容未更新

我有一个 Android Widget 按钮,按下该按钮会将记录插入 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
    }

    // ...
}

解决方案

我建议在 Resumed 创建一个 Application 事件,然后您可以从任何 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; 
        }); 
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。