首页 > 解决方案 > 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 {

}

标签: androidandroid-recyclerviewonscrolllisteneronscrollchanged

解决方案


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

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
                                                }
                                        }
                                    });
                                            }

推荐阅读