OnResume 页面内容不更新
OnResume Page Content not updating
我有一个 Android 小部件按钮,当按下该按钮时,它会将一条记录插入到 SQLite 数据库中。
我在这种情况下使用该应用程序时遇到问题:
- 用户暂停应用程序以使用其设备主屏幕上的小部件。
- 用户按下插入新记录的小部件按钮。
- 用户恢复 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;
});
}
}
我有一个 Android 小部件按钮,当按下该按钮时,它会将一条记录插入到 SQLite 数据库中。
我在这种情况下使用该应用程序时遇到问题:
- 用户暂停应用程序以使用其设备主屏幕上的小部件。
- 用户按下插入新记录的小部件按钮。
- 用户恢复 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;
});
}
}