我在布局中具有 recyclerview :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:baselineAligned="false"
android:orientation="vertical">
<android.support.v7.widget.RecyclerView
android:id="@+id/advertising_list_view_right"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:divider="@null"
android:dividerHeight="0dp"
android:scrollbars="none" />
<TextView
android:id="@+id/empty_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:text="@string/no_records"
android:visibility="gone" />
</LinearLayout>
我的 CustomAdapter 是:
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
private final List<Ad> dataList;
private final Context context;
CustomAdapter(Context context, List<Ad> dataList) {
this.context = context;
this.dataList = dataList;
}
class CustomViewHolder extends RecyclerView.ViewHolder {
final View mView;
private final TextView adTitle;
private final TextView adLocation;
private final TextView adPrice;
private final ImageView coverImage;
CustomViewHolder(View itemView) {
super(itemView);
mView = itemView;
adTitle = mView.findViewById(R.id.title);
adLocation = mView.findViewById(R.id.text_view_key_4);
adPrice = mView.findViewById(R.id.price_text_view);
coverImage = mView.findViewById(R.id.company_image_view);
coverImage.layout(0, 0, 0, 0);
}
}
@NonNull
@Override
public CustomViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.advertising_list_item, parent, false);
return new CustomViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull CustomViewHolder holder, int position) {
holder.adTitle.setText(dataList.get(position).getTitle());
holder.adLocation.setText(dataList.get(position).getParish());
if (dataList.get(position).getPrice().length() == 0) {
holder.adPrice.setText(R.string.agreement);
} else {
holder.adPrice.setText(dataList.get(position).getPrice() + " تومان");
}
GlideApp.with(context)
.load(dataList.get(position).getPicture())
.error(R.drawable.default_pic)
.diskCacheStrategy(DiskCacheStrategy.ALL)
.override(dataList.get(position).getPictureWidth(), dataList.get(position).getPictureHeight())
.placeholder(R.drawable.default_pic)
.centerCrop()
.into(holder.coverImage);
}
@Override
public int getItemCount() {
return dataList.size();
}
}
为了使我的 recyclerview 永无止境,我使用了此类:
abstract class EndlessRecyclerViewScrollListener extends RecyclerView.OnScrollListener {
// The minimum amount of items to have below your current scroll position
// before loading more.
private int visibleThreshold = 1;
// The current offset index of data you have loaded
private int currentPage = 0;
// The total number of items in the dataset after the last load
private int previousTotalItemCount = 0;
// True if we are still waiting for the last set of data to load.
private boolean loading = true;
// Sets the starting page index
private final int startingPageIndex = 0;
private RecyclerView.LayoutManager mLayoutManager;
public EndlessRecyclerViewScrollListener(LinearLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
}
public EndlessRecyclerViewScrollListener(GridLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
}
public EndlessRecyclerViewScrollListener(StaggeredGridLayoutManager layoutManager) {
this.mLayoutManager = layoutManager;
visibleThreshold = visibleThreshold * layoutManager.getSpanCount();
}
private int getLastVisibleItem(int[] lastVisibleItemPositions) {
int maxSize = 0;
for (int i = 0; i < lastVisibleItemPositions.length; i++) {
if (i == 0) {
maxSize = lastVisibleItemPositions[i];
} else if (lastVisibleItemPositions[i] > maxSize) {
maxSize = lastVisibleItemPositions[i];
}
}
return maxSize;
}
// This happens many times a second during a scroll, so be wary of the code you place here.
// We are given a few useful parameters to help us work out if we need to load some more data,
// but first we check if we are waiting for the previous load to finish.
@Override
public void onScrolled(RecyclerView view, int dx, int dy) {
int lastVisibleItemPosition = 0;
int totalItemCount = mLayoutManager.getItemCount();
if (mLayoutManager instanceof StaggeredGridLayoutManager) {
int[] lastVisibleItemPositions = ((StaggeredGridLayoutManager) mLayoutManager).findLastVisibleItemPositions(null);
// get maximum element within the list
lastVisibleItemPosition = getLastVisibleItem(lastVisibleItemPositions);
} else if (mLayoutManager instanceof GridLayoutManager) {
lastVisibleItemPosition = ((GridLayoutManager) mLayoutManager).findLastVisibleItemPosition();
} else if (mLayoutManager instanceof LinearLayoutManager) {
lastVisibleItemPosition = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition();
}
// If the total item count is zero and the previous isn't, assume the
// list is invalidated and should be reset back to initial state
if (totalItemCount < previousTotalItemCount) {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = totalItemCount;
if (totalItemCount == 0) {
this.loading = true;
}
}
// If it’s still loading, we check to see if the dataset count has
// changed, if so we conclude it has finished loading and update the current page
// number and total item count.
if (loading && (totalItemCount > previousTotalItemCount)) {
loading = false;
previousTotalItemCount = totalItemCount;
}
// If it isn’t currently loading, we check to see if we have breached
// the visibleThreshold and need to reload more data.
// If we do need to reload some more data, we execute onLoadMore to fetch the data.
// threshold should reflect how many total columns there are too
if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount && dy > 0) {
currentPage++;
onLoadMore(currentPage, totalItemCount, view);
loading = true;
}
if (!loading && (lastVisibleItemPosition + visibleThreshold) > totalItemCount) {
currentPage++;
onLoadMore(currentPage, totalItemCount, view);
loading = true;
}
}
// Call this method whenever performing new searches
public void resetState() {
this.currentPage = this.startingPageIndex;
this.previousTotalItemCount = 0;
this.loading = true;
}
// Defines the process for actually loading more data based on page
protected abstract void onLoadMore(int page, int totalItemsCount, RecyclerView view);
}
以及使用它们的代码:
/*Method to generate List of data using RecyclerView with custom adapter*/
private void generateDataList(final List<Ad> photoList) {
StaggeredGridLayoutManager staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
adapter = new CustomAdapter(getActivity(), photoList);
recyclerView.setAdapter(adapter);
EndlessRecyclerViewScrollListener scrollListener;
scrollListener = new EndlessRecyclerViewScrollListener(staggeredGridLayoutManager) {
@Override
public void onLoadMore(int page, int totalItemsCount, RecyclerView view) {
// Triggered only when new data needs to be appended to the list
// Add whatever code is needed to append new items to the bottom of the list
loadNextDataFromApi(page);
}
};
recyclerView.addOnScrollListener(scrollListener);
}
private void loadNextDataFromApi(int offset) {
loadingSnackBar.show();
Call<List<Ad>> call = service.getAllPhotosprime(offset + 1);
Callback<List<Ad>> callback = new Callback<List<Ad>>() {
@Override
public void onResponse(@NonNull Call<List<Ad>> call, @NonNull Response<List<Ad>> response) {
if (response.code() == 200) {
loadingSnackBar.dismiss();
adList.addAll(response.body());
adapter.notifyItemInserted(adList.size() - 1);
adapter.notifyDataSetChanged();
} else {
call.clone().enqueue(this);
}
}
@Override
public void onFailure(@NonNull Call<List<Ad>> call, @NonNull Throwable t) {
loadingSnackBar.dismiss();
call.clone().enqueue(this);
Toast.makeText(getActivity(), "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
};
call.enqueue(callback);
}
如何在 recyclerview 的底部添加进度条,并在每次 onLoadMoreListener 调用时使其可见?我想将进度栏设置在屏幕底部的中心,而不是 recyclerview 中卡片的底部。
答案 0 :(得分:0)
You can user default prograssbar by placing it on Layout file like below xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/colorback"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main">
<android.support.v7.widget.RecyclerView
android:id="@+id/recycleViewVideo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/prograssbar" />
<ProgressBar
android:id="@+id/prograssbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_above="@id/adView"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:visibility="visible" />
<LinearLayout
android:id="@+id/adView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:orientation="horizontal" />
</RelativeLayout>
And in main code from where you call API just handle hide/show.