RecylerView 的 onScrollChanged() 在 Android 中无法检测到屏幕底部



我正在实现一项功能,在该功能中,我需要再次点击 API 才能在列表到达末尾时获取数据。我已经使用RecyclerViewonScrollListener来检测它是否到达终点,但代码仅在我打开屏幕时第一次运行,但当它到达屏幕结束时不起作用。 如何检查列表何时到达末尾。

片段代码:

@SuppressLint("RestrictedApi")
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_home, container, false);
initScrollListener();
}

private void initScrollListener() {
list.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();
Toast.makeText(getActivity(), "Loading", Toast.LENGTH_SHORT).show();
if (!isLoading) {
if (linearLayoutManager != null && linearLayoutManager.findLastCompletelyVisibleItemPosition() == rowsArrayList.size() - 1) {
//bottom of list!
loadMore();
isLoading = true;
}
}
}
});
}

private void loadMore() {
rowsArrayList.add(null);
postListAdapter.notifyItemInserted(rowsArrayList.size() - 1);

Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
rowsArrayList.remove(rowsArrayList.size() - 1);
int scrollPosition = rowsArrayList.size();
postListAdapter.notifyItemRemoved(scrollPosition);
int currentSize = scrollPosition;
int nextLimit = currentSize + 10;
while (currentSize - 1 < nextLimit) {
rowsArrayList.add("Item " + currentSize);
currentSize++;
}
postListAdapter.notifyDataSetChanged();
isLoading = false;
}
}, 2000);

}

适配器代码:

public class PostListAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
Context context;
List<StoriesDatum> storiesDatumList;
StoriesDatum storiesDatum;
FragmentHome fragmentHome;
int qty;
View itemView;
private final int VIEW_TYPE_ITEM = 0;
private final int VIEW_TYPE_LOADING = 1;

public PostListAdapter(Context context, List<StoriesDatum> storiesDatumList, FragmentHome fragmentHome) {
this.context = context;
this.storiesDatumList = storiesDatumList;
this.fragmentHome = fragmentHome;
}

@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
if (viewType == VIEW_TYPE_ITEM) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_post, parent, false);
return new MyViewHolder(view);
} else {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_loading, parent, false);
return new LoadingViewHolder(view);
}
}

@Override
public void onBindViewHolder(@NonNull final RecyclerView.ViewHolder holder, final int position) {
if (holder instanceof MyViewHolder) {
populateItemRows((MyViewHolder) holder, position);
} else if (holder instanceof LoadingViewHolder) {
showLoadingView((LoadingViewHolder) holder, position);
}

}
@Override
public long getItemId(int position) {
return position;
}
@Override
public int getItemViewType(int position) {
return storiesDatumList.get(position) == null ? VIEW_TYPE_LOADING : VIEW_TYPE_ITEM;
}

@Override
public int getItemCount() {
return storiesDatumList.size();
}
private class LoadingViewHolder extends RecyclerView.ViewHolder {
ProgressBar progressBar;
public LoadingViewHolder(@NonNull View itemView) {
super(itemView);
progressBar = itemView.findViewById(R.id.progressBar);
}
}
private void showLoadingView(LoadingViewHolder viewHolder, int position) {
//ProgressBar would be displayed
}
private void populateItemRows(MyViewHolder myViewHolder, final int position) {
String item = storiesDatumList.get(position).toString();
storiesDatum = storiesDatumList.get(position);
myViewHolder.txtCommunityName.setText(storiesDatum.getComTitle());
myViewHolder.txtPostTitle.setText(storiesDatum.getTitle());
String comm_photo = String.valueOf(storiesDatum.getComImage());
if (comm_photo == null || comm_photo.equals("null") || comm_photo.equals("")) {
myViewHolder.ivImage.setImageResource(R.mipmap.top_communities_circle);
} else {
if (comm_photo.startsWith("https://") || comm_photo.startsWith("http://")) {
long interval = 5000 * 1000;
Glide.with(context).load(comm_photo)
.into(myViewHolder.ivImage);
} else {
Glide.with(context).load(Constants.image_url + comm_photo)
.into(myViewHolder.ivImage);
}
}
myViewHolder.txtNamePosted.setText("Posted by " + storiesDatum.getUsername());
String created_date = storiesDatum.getCreatedAt();
//call date
String corecDate = fragmentHome.createDate(created_date);
myViewHolder.txtTime.setText(corecDate);
myViewHolder.txtCommentCount.setText(storiesDatum.getCommentsCount() + " Comments");
myViewHolder.txtLikeCount.setText(storiesDatum.getStoryemojiCount() + " Reactions");

/*change code for adapter*/
myViewHolder.tvPost.setText(storiesDatum.getSnapshots());
if (storiesDatum.getStoryBody() != null) {
myViewHolder.tvBody.setVisibility(View.VISIBLE);
myViewHolder.tvBody.setText(storiesDatum.getStoryBody());
} else {
myViewHolder.tvBody.setVisibility(View.GONE);
}
if (storiesDatum.getStoryType() == 2) {
myViewHolder.videoPost.setVisibility(View.GONE);
myViewHolder.youTubePlayerView.setVisibility(View.GONE);
if (storiesDatum.getStoryUpload() == null && (storiesDatum.getStoryUrl() != null)) {
myViewHolder.ivImageViaLink.setVisibility(View.VISIBLE);
myViewHolder.ivPostImage.setVisibility(View.GONE);
String story_url = storiesDatum.getStoryUrl().toString();
Log.e("TAG", "onResponse:story1 " + story_url);
if (story_url.startsWith("https://") || story_url.startsWith("http://")) {
Glide.with(context).load(story_url)
.into(myViewHolder.ivImageViaLink);
} else {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
//.error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
}
} else if (storiesDatum.getStoryUrl() == null && (storiesDatum.getStoryUpload() != null)) {
myViewHolder.ivImageViaLink.setVisibility(View.GONE);
myViewHolder.ivPostImage.setVisibility(View.VISIBLE);

String story_url = storiesDatum.getStoryUpload().toString();
Log.e("TAG", "onResponse:story2 " + story_url);
if (story_url.startsWith("https://") || story_url.startsWith("http://")) {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
//.error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivPostImage);
} else {
Glide.with(context).load(Constants.image_url + story_url)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivPostImage);
}
} else {
myViewHolder.ivImageViaLink.setVisibility(View.VISIBLE);
myViewHolder.ivPostImage.setVisibility(View.VISIBLE);
String story_upload = storiesDatum.getStoryUpload().toString();
Log.e("TAG", "onResponse:story3 " + story_upload);
if (story_upload.startsWith("https://") || story_upload.startsWith("http://")) {
Glide.with(context).load(story_upload)
//.placeholder(R.mipmap.top_communities_circle)
//.error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivPostImage);
} else {
Glide.with(context).load(Constants.image_url + story_upload)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivPostImage);
}

String story_url = storiesDatum.getStoryUrl().toString();
Log.e("TAG", "onResponse:story4 " + story_url);
if (story_url.startsWith("https://") || story_url.startsWith("http://")) {
Glide.with(context).load(story_url)
//.placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
} else {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
//  .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
}
}
} else if (storiesDatum.getStoryType() == 3) {

myViewHolder.videoPost.setVisibility(View.GONE);
myViewHolder.youTubePlayerView.setVisibility(View.GONE);
if (storiesDatum.getStoryUpload() == null && (storiesDatum.getStoryUrl() != null)) {
myViewHolder.ivImageViaLink.setVisibility(View.VISIBLE);
myViewHolder.btn_play.setVisibility(View.VISIBLE);
myViewHolder.ivPostImage.setVisibility(View.GONE);
String story_url1 = storiesDatum.getStoryUrl().toString();
String[] cutLink = story_url1.split("frameborder");
String[] cutLink1 = cutLink[0].split("embed/");
String link = cutLink1[1];
final String played_link = link.split(""")[0];
String story_url = "https://img.youtube.com/vi/" + played_link + "/0.jpg";
Log.e("TAG", "onResponse:story1 " + story_url);
if (story_url.startsWith("https://") || story_url.startsWith("http://")) {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
} else {
Glide.with(context).load(story_url)
//  .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
}
} else if (storiesDatum.getStoryUrl() == null && (storiesDatum.getStoryUpload() != null)) {
myViewHolder.ivImageViaLink.setVisibility(View.GONE);
myViewHolder.ivPostImage.setVisibility(View.VISIBLE);
myViewHolder.play.setVisibility(View.VISIBLE);

String story_url = storiesDatum.getStoryUpload().toString();
Log.e("TAG", "onResponse:story2 " + story_url);

} else {
myViewHolder.ivImageViaLink.setVisibility(View.VISIBLE);
myViewHolder.ivPostImage.setVisibility(View.VISIBLE);
myViewHolder.btn_play.setVisibility(View.VISIBLE);
myViewHolder.play.setVisibility(View.VISIBLE);
String story_upload = storiesDatum.getStoryUpload().toString();
Uri videoURI;
videoURI = Uri.parse(Constants.image_url + story_upload);

Log.e("TAG", "onResponse:story3 " + videoURI);

String story_url1 = storiesDatum.getStoryUrl().toString();
String[] cutLink = story_url1.split("frameborder");
String[] cutLink1 = cutLink[0].split("embed/");
String link = cutLink1[1];
final String played_link = link.split(""")[0];
String story_url = "https://img.youtube.com/vi/" + played_link + "/0.jpg";

Log.e("TAG", "onResponse:story4 " + story_url);
if (story_url.startsWith("https://") || story_url.startsWith("http://")) {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
} else {
Glide.with(context).load(story_url)
// .placeholder(R.mipmap.top_communities_circle)
// .error(R.drawable.ic_launcher_background)
.into(myViewHolder.ivImageViaLink);
}
}
// viewHolder.tvItem.setText(item);
myViewHolder.txtCommunityName.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
storiesDatum = storiesDatumList.get(position);
fragmentHome.sendToCommunityPage(storiesDatum.getComTitle(), storiesDatum.getCommunityId(), storiesDatum.getComImage());
}
});

myViewHolder.txtNamePosted.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
storiesDatum = storiesDatumList.get(position);
fragmentHome.sendToUserProfile(storiesDatum.getUserId(), storiesDatum.getUsername(), storiesDatum.getProfile_pic());
}
});
myViewHolder.ivAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
storiesDatum = storiesDatumList.get(position);
fragmentHome.addCommunity(storiesDatum.getCommunityId());
}
});

Log.e("tag", "jpined_favourite" + storiesDatum.getJoined() + storiesDatum.getFav());
if (storiesDatum.getJoined() == 0) {
myViewHolder.ivAdd.setVisibility(View.VISIBLE);
} else {
myViewHolder.ivAdd.setVisibility(View.GONE);
}
if (storiesDatum.getFav() == 1) {
myViewHolder.ivFav.setImageResource(R.mipmap.mark_as_favorite_filled);
} else {

myViewHolder.ivFav.setImageResource(R.mipmap.mark_favorite);
}

myViewHolder.txtComment.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
fragmentHome.openCommentbox();
}
});
myViewHolder.ivFav.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
storiesDatum = storiesDatumList.get(position);
if (storiesDatum.getFav() == 0) {
fragmentHome.addFavt(storiesDatum.getCommunityId().toString(), "markfav");
} else {
fragmentHome.addFavt(storiesDatum.getCommunityId().toString(), "unmarkfav");
}
}
});
myViewHolder.relativeLayout.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//fragmentHome.sendToSinglePost();
StoriesDatum storiesDatum1 = storiesDatumList.get(position);
fragmentHome.sendToSinglePost(storiesDatum1.getId().toString());
}
});

myViewHolder.relativeShare.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
StoriesDatum storiesDatum1 = storiesDatumList.get(position);
fragmentHome.sharepost(storiesDatum1.getSlugid(), storiesDatum1.getSlug());
}
});
}
}
public class MyViewHolder extends RecyclerView.ViewHolder {
}

使用此方法

RecyclerView.OnScrollListener onScrollListener = new RecyclerView.OnScrollListener()    {
@Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
if (dy > 0) //check for scroll down
{
if (!mNoMoreLoad) {
if ((mLayoutManager.getChildCount() +
mLayoutManager.findFirstVisibleItemPosition()) >=  mLayoutManager.getItemCount()) {
mPage++;
mNoMoreLoad = true;
loadMore(mPage);
}
}
}
}

private void loadMore(int mPage) {
if (Utils.getInstance().isNetworkAvailable(getActivity())) {
hit api with page number
}
}

获得响应后,使用数据限制检查新数据的大小

if (response.getData().size() < Constants.DATA_LIMIT) {
mNoMoreLoad = true;
} else {
mNoMoreLoad = false;
}

您可以通过以下方式执行此操作:

recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override
public void onScrollStateChanged( RecyclerView recyclerView, int newState) {
if(!recyclerView.canScrollVertically(1))
Log.e(TAG,TAG+"<<end-333->>"); //Here is one way 
super.onScrollStateChanged(recyclerView, newState);
}
@Override
public void onScrolled( RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
LinearLayoutManager linearLayoutManager = (LinearLayoutManager) recyclerView.getLayoutManager();

Log.e(TAG,TAG+"<<end-->>"+linearLayoutManager.findLastVisibleItemPosition()); 
if(linearLayoutManager.findLastVisibleItemPosition() == linearLayoutManager.getItemCount()-1)
{
Log.e(TAG,TAG+"<<end-22->>"+linearLayoutManager.findLastVisibleItemPosition()); //Here is another way
}
}
});
}

最新更新