java - 在 Android 中向下滚动 RecyclerView

标签 java android json android-recyclerview

我想在 Android 应用程序中从 Flickr 下载图片并在我的 RecyclerView (GridLayoutManager) 中显示它们。这是我的代码,用于通过页面获取它(默认情况下页面 = 1)

public List<GalleryItem> fetchItems(Integer page){
    if (page==null) page=1;
    List<GalleryItem> items=new ArrayList<>();
    try {
        String url = Uri.parse("https://api.flickr.com/services/rest/")
                .buildUpon()
                .appendQueryParameter("method", "flickr.photos.getRecent")
                .appendQueryParameter("api_key", API_KEY)
                .appendQueryParameter("format", "json")
                .appendQueryParameter("nojsoncallback", "1")
                .appendQueryParameter("extras", "url_s")
                .appendQueryParameter("page",page.toString())
                .build().toString();
        String jsonString = getUrlString(url);
        Log.i(TAG, "Received JSON: " + jsonString);

        JSONObject jsonBody = new JSONObject(jsonString);
        parseItems(items,jsonBody);
}
    catch (JSONException jse){
        Log.e(TAG,"Failed to parse JSON",jse);
    }
    catch (IOException ioe){
        Log.e(TAG,"Failed to fetch items",ioe);
    }
    return items;
}

当我得到这些项目时,我将它们添加到 recyclerviews 适配器项目中,并观察我是否没有到达终点以获取本例中的新数据(使用 How to implement endless list with RecyclerView? 的帮助)

private RecyclerView mPhotoRecyclerView;
private List<GalleryItem> mItems=new ArrayList<>();

GridLayoutManager mGridLayoutManager;
int pastVisibleItems, visibleItemCount, totalItemCount,currentpage=1;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
    View v=inflater.inflate(R.layout.fragment_photo_gallery,container,false);

    mPhotoRecyclerView=(RecyclerView)v.findViewById(R.id.fragment_photo_gallery_recycler_view);
    mGridLayoutManager=new GridLayoutManager(getActivity(),3);
    mPhotoRecyclerView.setLayoutManager(mGridLayoutManager);
    mPhotoRecyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            if (dy>0) {
                visibleItemCount = mGridLayoutManager.getChildCount();
                totalItemCount = mGridLayoutManager.getItemCount();
                pastVisibleItems = mGridLayoutManager.findFirstVisibleItemPosition();
              //  ppastVisibleItems = mGridLayoutManager.findLastVisibleItemPosition();


                if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
                    currentpage++;
                    new FetchItemsTask().execute(new Integer[]{currentpage});
                }
            }
        }
    });
    setAdapter();
    return v;
}

private void setAdapter(){
    if(isAdded()){
        mPhotoRecyclerView.setAdapter(new PhotoAdapter(mItems));
    }
}

我的 AsyncTask 实现

private class FetchItemsTask extends AsyncTask<Integer,Void,List<GalleryItem>>{

        @Override
        protected List<GalleryItem> doInBackground(Integer... voids) {
//            try{
//
//                String result=new FlickrFetchr().getUrlString("https://www.bignerdranch.com");
//                Log.i(TAG,"Fetched contents of URL: "+result);
//            }
//            catch (IOException ioe){
//                Log.e(TAG,"Failed to fetch URL: "+ioe.getMessage(),ioe);
//            }
            return new FlickrFetchr().fetchItems(currentpage);
        }

        @Override
        protected void onPostExecute(List<GalleryItem> items) {
            mItems.addAll(items);
            setAdapter();
        }
    }

问题是我认为是 fragment

 if ((visibleItemCount + pastVisibleItems) >= totalItemCount) {
                currentpage++;
                new FetchItemsTask().execute(new Integer[]{currentpage});
            }

每次我花越来越多的时间向下 ScrollView 。第一次滚动:totalItemCount=100,效果很好。在下一个滚动中,pastVisibleItems 等于 0,totalItemCount =200(flickr 给出的页数为 100),因此重新下载新图片需要越来越多的时间。我尝试使用

if ((visibleItemCount + pastVisibleItems+(currentpage-1)*100) >= totalItemCount) {
                    currentpage++;
                    new FetchItemsTask().execute(new Integer[]{currentpage});
                }

但是回收器 View 一直显示第一页(。我怎样才能正确实现它?

这是我的适配器和 ViewHolder 代码

private class PhotoHolder extends RecyclerView.ViewHolder{
    private TextView mTitleTextView;
    public PhotoHolder(View itemView) {
        super(itemView);
        mTitleTextView=(TextView)itemView;
    }
    public void bindGalleryItem(GalleryItem item){
        mTitleTextView.setText(item.toString());
    }
}

private class PhotoAdapter extends RecyclerView.Adapter<PhotoHolder>{
    private List<GalleryItem> mGalleryItems;

    public PhotoAdapter(List<GalleryItem> galleryItems) {
        mGalleryItems=galleryItems;
    }

    @Override
    public PhotoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        TextView textView=new TextView(getActivity());
        return new PhotoHolder(textView);
    }

    @Override
    public void onBindViewHolder(PhotoHolder holder, int position) {
        holder.bindGalleryItem(mGalleryItems.get(position));
    }

    @Override
    public int getItemCount() {
        return mGalleryItems.size();
    }
}

最佳答案

我找到了答案,为什么 PastVisibleItems 设置为零的问题是因为在中生成了新的适配器实例

private void setAdapter(){
if(isAdded()){
    mPhotoRecyclerView.setAdapter(new PhotoAdapter(mItems));
}

}

我把它改成了

private void setAdapter(){
    if(isAdded()){

        if (mPhotoRecyclerView.getAdapter()==null)
            mPhotoRecyclerView.setAdapter(new PhotoAdapter(mItems));
        else
            mPhotoRecyclerView.getAdapter().notifyDataSetChanged();
    }
}

现在一切都运转良好!感谢您的关注)

关于java - 在 Android 中向下滚动 RecyclerView,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39677470/

相关文章:

java - 保存当前目录下的文件

java - 无法在 WebSphere 上加载以下字体

java - 编写 Java 代码需要域名吗?

java - 如何将 Spring Integration Consumer 配置为事件驱动?

android - 内存不足错误 : Android large Bitmap rotation (90°)

mysql - 在任何索引上搜索 MySQL JSON 字段

android - 更改 TimePicker 上的标题?

android - 如何在 Jetpack Compose 中实现以下布局?

java - CXF Rest 客户端不处理我的对象

javascript - 将\n 替换为 JSON 字符串中的 <br>