【发布时间】:2017-01-26 22:55:24
【问题描述】:
当我打开Fragment 时,我尝试显示ProgressBar,填充RecyclerView,将NotifyChange 更新为RecyclerView,然后隐藏ProgressBar。
现在 ProgressBar 没有旋转。我认为这与在 UI 线程上执行的 SetRecyclerViewItems 有关,但如果我不这样做,我会收到一条错误消息,提示 UI 只能在 UI 线程中更新。
片段:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
/* Initializing elements code removed */
SetRecyclerView();
return view;
}
public async override void OnStart()
{
base.OnStart();
ShowProgressBar();
await LoadAsync();
HideProgressBar();
}
private async Task LoadAsync()
{
await Task.Run(() => {
SetRecyclerViewItems();
});
}
private void SetRecyclerView()
{
mLayoutManager = new LinearLayoutManager(mRecyclerView.Context);
mRecyclerView.SetLayoutManager(mLayoutManager);
mAdapter = new TransactionsRecyclerAdapter(this.Activity, mTransactions, dateFormat);
mAdapter.ItemClick += MAdapter_ItemClick;
mRecyclerView.SetAdapter(mAdapter);
}
private void SetRecyclerViewItems(List<PaymentListItemViewModel> transactions = null)
{
Activity.RunOnUiThread(() => {
if (transactions == null)
transactions = GetTransactions();
mAdapter.NotifyChange(transactions);
SetTotal();
});
}
Adapter.NotifyChange
public void NotifyChange(List<PaymentListItemViewModel> transactions)
{
mTransactions = transactions;
NotifyDataSetChanged();
}
为什么 ProgressBar 不旋转?
我向适配器填充新数据的方式是否正确(发送新列表,然后发送NotifyDataSetChanged?
布局:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/login_background">
<RelativeLayout
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="center"
android:layout_centerInParent="true"
android:id="@+id/transactionsProgressBar">
<ProgressBar
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="@android:style/Widget.ProgressBar.Large" />
</RelativeLayout>
<LinearLayout
android:orientation="vertical"
android:minWidth="25px"
android:minHeight="25px"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/linearLayout4"
android:layout_weight="1">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerViewTransactions"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:scrollbars="vertical" />
</LinearLayout>
</LinearLayout>
在 OnCreateView 中:
mLayoutProgressBar = view.FindViewById<RelativeLayout>(Resource.Id.transactionsProgressBar);
显示/隐藏进度条:
private void ShowProgressBar()
{
mLayoutProgressBar.Visibility = ViewStates.Visible;
}
private void HideProgressBar()
{
mLayoutProgressBar.Visibility = ViewStates.Gone;
}
【问题讨论】:
-
显然这是因为 SetRecyclerViewItems 中的 RunOnUiThread 只是 Handler.post 的快捷方式,它立即返回并使所有异步、等待和任务无用
-
什么是 GetTransactions 和 SetTotal,它们需要多长时间?
-
这就是我的想法,但正如我所说,如果我不在 UI 线程中运行它会抛出一个异常,说“只能在 UI 线程中更改视图”。如何分别运行两个 UI 项(ProgressBar 和 SetRecyclerViewItems)?
-
@Luke 在创建适配器时填充了一个空列表,然后我使用 GetTransactions 获取要在 ReyclerView 中使用的数据。处理大约需要 1 秒。 SetTotal 目前是一个空方法。
-
你显然应该只在任务中运行 GetTransactions 并等待它的结果