Activity 指示器在所有代码执行完毕后才会显示
Activity Indicator not displaying until all code has executed
基本上,我有一个 activity 指示器,该指示器在该方法中的所有其他代码都已执行之前不会显示。我看过了,IsBusy 属性 在代码端(登录页面)和 xaml 绑定(登录 xaml)都设置为 true,所以我知道正确的值是最少被传递。
我很确定我已经正确设置了一切,只要 async / await 不会锁定任何东西。
我有一个 BaseViewModel class,我所有的视图模型都使用它。这是 IsBusy:
的代码
bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
set { SetProperty(ref isBusy, value); }
}
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName]string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
这是我的 XAML 登录页面。 activity 指示器位于 内容页面 标签内的单个 堆栈布局 内:
<ActivityIndicator IsRunning="{Binding IsBusy}"
IsVisible="{Binding IsBusy}"
HeightRequest="40"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand">
<ActivityIndicator.WidthRequest>
<OnPlatform x:TypeArguments="x:Double" iOS="100" Android="100" />
</ActivityIndicator.WidthRequest>
<ActivityIndicator.Color>
<OnPlatform x:TypeArguments="Color"
iOS="#2499CE" />
</ActivityIndicator.Color>
</ActivityIndicator>
这里是 LoginPageViewModel 代码。如果我理解正确,指示器应该在第一行设置为 true 后立即显示,然后在调用 API 并且用户未通过身份验证后消失。
public async void OnLogin()
{
IsBusy = true;
var isAuthenticated = await LoginPageValidation.IsAuthenticated(email, password);
if (!isAuthenticated )
{
IsBusy = false;
IsForgotPasswordLabelVisible = true;
DisplayUserAndPasswordMismatchPrompt();
return;
}
}
我确定问题很小,但我只是没有看到它。
编辑:添加 IsAuthenticated 方法
IsAuthenticated
public static async Task<bool> IsAuthenticated(string email, string password)
{
var isAuthenticated = false;
try
{
var payload = $"{{\n\t\"Email\":\"{email}\",\n\t\"Password\":\"{password}\"\n}}";
var response = await LoginApi.Authenticate(payload);
isAuthenticated = bool.Parse(response["isAuthenticated"].ToString());
}
catch (Exception e)
{
// log stuff here
}
return isAuthenticated;
}
验证 API 调用:
public static async Task<JObject> Authenticate(string payloadBody)
{
IRestResponse response = null;
try
{
var client = new RestClient($"{url}/authenticate");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("undefined", payloadBody, ParameterType.RequestBody);
response = client.Execute(request);
} catch (Exception e)
{
// log some bad stuff here
}
return JObject.Parse(response.Content);
}
然后确保您的视图模型实现了 INotifyPropertyChanged:
public bool IsBusy
{
set { isBusy = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsBusy))); }
get { return isBusy; }
}
通过你更新的Authenticate
方法代码,你可以改变
client.Execute;
到
client.ExecuteAsync
在这种情况下,您将按预期显示 ActivityIndicator
基本上,我有一个 activity 指示器,该指示器在该方法中的所有其他代码都已执行之前不会显示。我看过了,IsBusy 属性 在代码端(登录页面)和 xaml 绑定(登录 xaml)都设置为 true,所以我知道正确的值是最少被传递。
我很确定我已经正确设置了一切,只要 async / await 不会锁定任何东西。
我有一个 BaseViewModel class,我所有的视图模型都使用它。这是 IsBusy:
的代码bool isBusy = false;
public bool IsBusy
{
get { return isBusy; }
set { SetProperty(ref isBusy, value); }
}
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName]string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
这是我的 XAML 登录页面。 activity 指示器位于 内容页面 标签内的单个 堆栈布局 内:
<ActivityIndicator IsRunning="{Binding IsBusy}"
IsVisible="{Binding IsBusy}"
HeightRequest="40"
VerticalOptions="CenterAndExpand"
HorizontalOptions="CenterAndExpand">
<ActivityIndicator.WidthRequest>
<OnPlatform x:TypeArguments="x:Double" iOS="100" Android="100" />
</ActivityIndicator.WidthRequest>
<ActivityIndicator.Color>
<OnPlatform x:TypeArguments="Color"
iOS="#2499CE" />
</ActivityIndicator.Color>
</ActivityIndicator>
这里是 LoginPageViewModel 代码。如果我理解正确,指示器应该在第一行设置为 true 后立即显示,然后在调用 API 并且用户未通过身份验证后消失。
public async void OnLogin()
{
IsBusy = true;
var isAuthenticated = await LoginPageValidation.IsAuthenticated(email, password);
if (!isAuthenticated )
{
IsBusy = false;
IsForgotPasswordLabelVisible = true;
DisplayUserAndPasswordMismatchPrompt();
return;
}
}
我确定问题很小,但我只是没有看到它。
编辑:添加 IsAuthenticated 方法
IsAuthenticated
public static async Task<bool> IsAuthenticated(string email, string password)
{
var isAuthenticated = false;
try
{
var payload = $"{{\n\t\"Email\":\"{email}\",\n\t\"Password\":\"{password}\"\n}}";
var response = await LoginApi.Authenticate(payload);
isAuthenticated = bool.Parse(response["isAuthenticated"].ToString());
}
catch (Exception e)
{
// log stuff here
}
return isAuthenticated;
}
验证 API 调用:
public static async Task<JObject> Authenticate(string payloadBody)
{
IRestResponse response = null;
try
{
var client = new RestClient($"{url}/authenticate");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddParameter("undefined", payloadBody, ParameterType.RequestBody);
response = client.Execute(request);
} catch (Exception e)
{
// log some bad stuff here
}
return JObject.Parse(response.Content);
}
然后确保您的视图模型实现了 INotifyPropertyChanged:
public bool IsBusy
{
set { isBusy = value; PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(IsBusy))); }
get { return isBusy; }
}
通过你更新的Authenticate
方法代码,你可以改变
client.Execute;
到
client.ExecuteAsync
在这种情况下,您将按预期显示 ActivityIndicator