Reputation: 2833
When I open a Fragment
I try to show a ProgressBar
, populate a RecyclerView
, update NotifyChange
to RecyclerView
and then hide the ProgressBar
.
Right now the ProgressBar isn't spinning. I think it has to do with SetRecyclerViewItems being executed on the UI Thread but if I don't do that I get an error saying that the UI can only be updated in the UI thread.
Fragment:
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();
}
Why isn't the ProgressBar spinning?
Is the way I'm populating new data to the Adapter correct (sending in a new list and then NotifyDataSetChanged
?
Layout:
<?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>
In OnCreateView:
mLayoutProgressBar = view.FindViewById<RelativeLayout>(Resource.Id.transactionsProgressBar);
Show/Hide ProgressBar:
private void ShowProgressBar()
{
mLayoutProgressBar.Visibility = ViewStates.Visible;
}
private void HideProgressBar()
{
mLayoutProgressBar.Visibility = ViewStates.Gone;
}
Upvotes: 2
Views: 614
Reputation: 33068
You put the loading onto a separate thread by using Task.Run()
but in there you marshal back to the UI thread to update your adapter (Activity.RunOnUiThread()
), this will block the UI thread and your spinner stops running.
Depending on what your SetTotal()
method is doing, you should only have the call to mAdapter.NotifyChange(transactions);
being executed on the UI thread.
Upvotes: 2