问题
In my app, I send a volley request which fetches list items one-by-one, not all at once. I want to implement a progressbar at the end of the recyclerview when the data is being fetched. The class 'updateAdapter' updates the adapter and I was thinking of making the progress bar visible in the recyclerview scroll listener. But I have no idea how to do this in my code.
updateAdapter.java
//THIS CLASS UPDATES THE RECYCLER VIEW
public class updateAdapter{
private FetchWpApi fetch;
private int totalItemCount;
private int prevLastvisible=0;
private int fpage=1;
private Context context;
private RecyclerView recyclerView;
private ArrayList<sItem> list= new ArrayList<>();
private LinearLayoutManager manager;
private ProgressBar progressBar;
//CONSTRUCTOR FOR updateAdapter
public updateAdapter(RecyclerView recyclerView, final Context context, String url, LinearLayoutManager manager){
this.context=context;
this.recyclerView=recyclerView;
fetch=new FetchWpApi(url,context);
this.manager=manager;
}
public void fetchAndPut()
{
if(recyclerView.getAdapter()==null) {
fetch.fetchApiData(fpage, new FetchWpApi.Callback() {
@Override
public void onSuccess(sItem sitem) {
list.add(sitem);
if (list.size() == 1 || recyclerView.getAdapter() == null) {
ItemAdapter adapter = new ItemAdapter(context, list);
recyclerView.setAdapter(adapter);
} else if (list.size() > 1 && recyclerView.getAdapter() != null) {
recyclerView.getAdapter().notifyDataSetChanged();
recyclerView.getAdapter().notifyItemRangeChanged(0, recyclerView.getAdapter().getItemCount());
}
}
@Override
public void onFail(String msg) {
Toast.makeText(context, "FAILED PRIMARY LOAD", Toast.LENGTH_LONG).show();
}
});
}
recyclerView.addOnItemTouchListener(
//Not important
);
//SCROLL LISTENER ATTACHED TO THE RECYCLER VIEW
//SHOW PROGRESS BAR HERE?
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener()
{
@Override
public void onScrolled(final RecyclerView recyclerView, int dx, int dy)
{
if(dy > 0) //check for scroll down
{
totalItemCount = manager.getItemCount();
int lastVisibleItemPosition = ((LinearLayoutManager) manager).findLastVisibleItemPosition();
if( (lastVisibleItemPosition+1)==totalItemCount && totalItemCount%10==0 && lastVisibleItemPosition>prevLastvisible)
{
//SET VISIBILITY OF THE PROGRESS BAR IN THE LAST CARD ITEM TO VISIBLE ??
fpage++;
//loading = false;
Log.v("...", "Last Item !");
//Do pagination.. i.e. fetch new data
prevLastvisible=lastVisibleItemPosition;
fetch.fetchApiData(fpage,new FetchWpApi.Callback(){
@Override
public void onSuccess(sItem sitem){
list.add(sitem);
recyclerView.getAdapter().notifyDataSetChanged();
recyclerView.getAdapter().notifyItemRangeChanged(0, recyclerView.getAdapter().getItemCount());
}
@Override
public void onFail(String msg){
Toast.makeText(context,"FAILED ONLOAD",Toast.LENGTH_LONG).show();
}
});
}
}
}
});
}
}
The progressbar which I want to display is in this cardview:
finalcard.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.CardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cvItem"
android:layout_gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
>
<!--<LinearLayout-->
<!--android:id="@+id/linearlayout"-->
<!--android:layout_width="match_parent"-->
<!--android:layout_height="wrap_content"-->
<!--android:layout_margin="10dp"-->
<!-->-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<TextView
android:id="@+id/tvTitle"
android:textColor="#000"
android:text="Sample text Sampletext sample text sample text sample text"
android:layout_alignParentStart="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toStartOf="@+id/ivMainImage"
android:layout_marginTop="15dp"
android:paddingStart="16dp"
android:paddingEnd="2dp"
android:maxLines="4"
android:textSize="20sp"
android:layout_gravity="start"
/>
<TextView
android:id="@+id/dateText"
android:text="DATE"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingStart="16dp"
android:paddingEnd="0dp"
android:layout_gravity="start"
android:layout_below="@id/tvTitle"
android:ellipsize="marquee"/>
<ImageView
android:id="@+id/ivMainImage"
android:layout_width="140dp"
android:layout_height="130dp"
android:layout_gravity="end"
android:layout_alignParentEnd="true"
android:layout_margin="15dp"
android:src="@android:drawable/btn_star"
android:scaleType="centerCrop"
/>
<View
android:id="@+id/view"
android:layout_width="match_parent"
android:layout_height="2dp"
android:background="#0C000000"
android:layout_below="@id/ivMainImage"
/>
<ProgressBar
style="?android:attr/progressBarStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/progressBar2"
android:layout_below="@id/view"
android:visibility="gone"
/>
</RelativeLayout>
回答1:
Fix your progress bar below your recycler view instead of card view. Set visible progress bar when call web service, and set visibility Gone after complete service call
//Progress bar setVisibility - Visible
progressbar.setVisibility(View.VISIBLE);
fetch.fetchApiData(fpage, new FetchWpApi.Callback() {
@Override
public void onSuccess(sItem sitem) {
progressbar.setVisibility(View.GONE);
list.add(sitem);
recyclerView.getAdapter().notifyDataSetChanged();
recyclerView.getAdapter().notifyItemRangeChanged(0, recyclerView.getAdapter().getItemCount());
}
@Override
public void onFail(String msg) {
progressbar.setVisibility(View.GONE);
Toast.makeText(context, "FAILED ONLOAD", Toast.LENGTH_LONG).show();
}
});
回答2:
I think you can follow this link to add header or footer Recyclerview
offically. And you add footer as progressbar to load more data, and remove footer when you finish loading data.
回答3:
There are 2 ways:
1. Put the progress bar in the bottom of the screen and when you are bottom of the RecyclerView
by int last = layoutManager.findLastVisibleItemPosition();
it just display and when you get the response then hide it;
2. In your adapter:
- add a dummy row to the last position of your list.
check in adapter when the position is last then show the progress bar:
if(position == list.size - 1) { // create a layout which only have progress bar View row = LayoutInflater.from(viewGroup.getContext()).inflate( R.layout.progressbar, viewGroup, false); } else { View row = LayoutInflater.from(viewGroup.getContext()).inflate( R.layout.layout_list, viewGroup, false); }
来源:https://stackoverflow.com/questions/42523527/adding-progressbar-at-the-end-of-recyclerview