【问题标题】:RecyclerView is scrolling to up automatically and flickeringRecyclerView 自动向上滚动并闪烁
【发布时间】:2018-08-24 07:40:01
【问题描述】:

基本上我使用RecyclerViewgridAdapter 从服务器加载图像。但问题是RecyclerView 的项目以一种古怪的方式闪烁。我已经尝试了所有可能的解决方案,但到目前为止都没有奏效。

我尝试将glide 版本从4.4.0 更新为4.8.0,但它是徒劳的。我还尝试禁用RecyclerView 的动画,但这无济于事。谁能帮我解决这个问题?

代码:

GridLayoutManager gridLayoutManager = new GridLayoutManager(v.getContext(),3);
gridLayoutManager.setSmoothScrollbarEnabled(true);
gridLayoutManager.setItemPrefetchEnabled(true);
gridLayoutManager.setInitialPrefetchItemCount(20);

posts_rView.setLayoutManager(gridLayoutManager);
posts_rView.setItemAnimator(null);
posts_rView.setHasFixedSize(true);

gridPostAdapter=new StarredAdapter(timelineDataList);
posts_rView.setAdapter(gridPostAdapter);

数据更新代码:

private  Emitter.Listener handlePosts = new Emitter.Listener(){

    @Override
    public void call(final Object... args){
        try {
            JSONArray jsonArray=(JSONArray)args[0];
            Needle.onMainThread().execute(() -> {
                timelineDataList.clear();
                swipeRefreshLayout.setRefreshing(false);

                for(int i=0;i<jsonArray.length();i++){
                    try {
                        //JSONArray arr=jsonArray.getJSONArray(i);
                        JSONObject ob=jsonArray.getJSONObject(i);

                        post_username=ob.getString("_pid");
                        post_fullname=ob.getString("owner_fullname");

                        if(ob.has("owner_profPic"))post_profPic=ob.getString("owner_profPic");
                        else post_profPic="";

                        post_time=ob.getString("time");

                        post_link=ob.getString("img_link");
                        likes_counter=ob.getString("likes_counter");
                        comments_counter=ob.getString("comments_counter");
                        if(ob.has("caption")) post_caption=ob.getString("caption");
                        else post_caption=null;

                        //Skipping Private Posts
                        if(ob.getString("private_post_stat").equals("yes")&&!post_username.equals(my_username)) {
                            continue;
                        }
                        else
                            private_post_stat = ob.getString("private_post_stat");

                        comment_disabled=ob.getString("comment_disabled");

                        share_disabled=ob.getString("share_disabled");

                        download_disabled=ob.getString("download_disabled");

                        if(ob.has("short_book_content")) short_book_content=ob.getString("short_book_content");
                        else short_book_content=null;
                        society_name_adp=ob.getString("society");

                        addTimelineData(post_username,post_fullname,post_profPic,post_time,post_link,post_caption,
                                private_post_stat,comment_disabled,share_disabled,download_disabled,likes_counter,comments_counter,short_book_content,society_name_adp);

                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

                RecyclerView.Adapter adapter=posts_rView.getAdapter();
                posts_rView.setAdapter(null);
                posts_rView.setAdapter(adapter);
            });
        } catch (Exception e) {
            Log.e("error",e.toString());
        }
    }
};

private void addTimelineData(String username,String fullname,String post_profPic,String time,String img_link,String caption,
                             String private_post_stat,String comment_disabled,String share_disabled,String download_disabled,String likes_counter,
                             String comments_counter,String short_book_content,String society_name_adp){
    boolean isRepeated = false;
    for(TimelineData data:timelineDataList){
        if (data.getTime().equals(time)) {
            isRepeated = true;
        }
    }

    if(!isRepeated){
        timelineDataList.add(new TimelineData(username,fullname,post_profPic,time,img_link,caption,private_post_stat,comment_disabled,share_disabled,download_disabled,likes_counter,comments_counter,short_book_content,society_name_adp));
        gridPostAdapter.notifyDataSetChanged();
        // posts_rView.scrollToPosition(gridPostAdapter.getItemCount()-1);
       // posts_rView.scrollToPosition(0);
    }

     //gridPostAdapter.notifyItemInserted(timelineDataList.size()-1);
}

适配器类:

@Override
public void onBindViewHolder(StarViewHolder holder, int position) {

    //loading img
    Glide.with( parent.getContext()).asBitmap().load(arrayList.get(position)).apply(new RequestOptions()
        .override(200, 200)
        .dontAnimate()
        .placeholder(new ColorDrawable(Color.parseColor("#20001919"))))
        .thumbnail(0.1f)
        .into(holder.img);
}

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

@Override
public long getItemId(int position) {
    return position;
}

@Override
public int getItemViewType(int position) {
    return position;
}

【问题讨论】:

  • 为什么你将 recyclerview 适配器设置为 null 并再次设置适配器 RecyclerView.Adapter adapter=posts_rView.getAdapter(); posts_rView.setAdapter(null);
  • 请在此处也发布项目布局

标签: java android gridview android-recyclerview


【解决方案1】:

我还不太明白为什么在您的情况下会出现闪烁和重新定位到第一个元素,因为我没有看到您的 RecyclerView 的更新策略。但是,我想提出一些可能会解决问题的建议。

  1. 我建议您在设置GridLayoutManager 时删除setInitialPrefetchItemCountsetItemPrefetchEnabled 配置。如果您的嵌套 RecyclerView 不是您的情况,这将有所帮助。
  2. 每次从服务器更新数据时,您都在设置适配器。我猜您在滚动项目时正在调用更新操作代码。你不应该这样做。此外,请在每次更新数据集时删除设置 RecyclerView 的适配器。只需在每次更新后使用notifyDataSetChanged。不要清除timelineDataList 而是附加新项目,然后在您的适配器上调用notifyDataSetChanged
  3. 每次插入列表后,您都在 addTimelineData 中调用 notifyDataSetChanged。这应该仅在将所有元素添加到列表后完成。

所以我想提出以下代码来设置您的适配器并更新您的RecyclerView。请注意,我没有测试代码,您可能需要修改一些可能出现的错误。

设置布局管理器和适配器的代码。

GridLayoutManager gridLayoutManager = new GridLayoutManager(v.getContext(),3);
posts_rView.setLayoutManager(gridLayoutManager);
posts_rView.setHasFixedSize(true);

gridPostAdapter = new StarredAdapter(timelineDataList);
posts_rView.setAdapter(gridPostAdapter);

更新列表的代码。

private  Emitter.Listener handlePosts = new Emitter.Listener(){

    @Override
    public void call(final Object... args){
        try {
            JSONArray jsonArray = (JSONArray)args[0];
            Needle.onMainThread().execute(() -> {

                // Do not clear the list. Just append the new data in the list instead
                // timelineDataList.clear();

                swipeRefreshLayout.setRefreshing(false);

                for(int i = 0; i < jsonArray.length(); i++){
                    try {
                        JSONObject ob = jsonArray.getJSONObject(i);

                        post_username = ob.getString("_pid");
                        post_fullname = ob.getString("owner_fullname");
                        if(ob.has("owner_profPic")) post_profPic = ob.getString("owner_profPic");
                        else post_profPic = "";

                        post_time = ob.getString("time");

                        post_link = ob.getString("img_link");
                        likes_counter = ob.getString("likes_counter");
                        comments_counter = ob.getString("comments_counter");
                        if(ob.has("caption")) post_caption = ob.getString("caption");
                        else post_caption = null;

                        //Skipping Private Posts
                        if(ob.getString("private_post_stat").equals("yes")&&!post_username.equals(my_username)) {
                            continue;
                        }
                        else
                            private_post_stat = ob.getString("private_post_stat");

                        comment_disabled = ob.getString("comment_disabled");
                        share_disabled = ob.getString("share_disabled");
                        download_disabled = ob.getString("download_disabled");

                        if (ob.has("short_book_content")) short_book_content = ob.getString("short_book_content");
                        else short_book_content = null;

                        society_name_adp = ob.getString("society");
                        addTimelineData(post_username, post_fullname, post_profPic, post_time, post_link,post_caption, private_post_stat, comment_disabled, share_disabled, download_disabled, likes_counter, comments_counter, short_book_content, society_name_adp);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }

                gridPostAdapter.notifyDataSetChanged();
            });

        } catch (Exception e) {
            Log.e("error",e.toString());
        }
    }
};

private void addTimelineData(String username, String fullname, String post_profPic, String time, String img_link, String caption, String private_post_stat, String comment_disabled, String share_disabled, String download_disabled, String likes_counter, String comments_counter, String short_book_content, String society_name_adp) {

    boolean isRepeated = false;
    for(TimelineData data:timelineDataList){
        if (data.getTime().equals(time)) {
            isRepeated = true;
        }
    }

    if(!isRepeated){
        timelineDataList.add(new TimelineData(username,fullname,post_profPic,time,img_link,caption,private_post_stat,comment_disabled,share_disabled,download_disabled,likes_counter,comments_counter,short_book_content,society_name_adp));

        // Do not call notifyDataSetChanged each time you are adding an item. This will be called in the call function above. So remove this line.
        // gridPostAdapter.notifyDataSetChanged();
    }
}

尝试在服务器端 API 中添加一些分页(如果还没有的话),这样您就可以在向下滚动时获取下一个 20 个数据集,而不是再次获取整个数据。

希望对您有所帮助。

【讨论】:

  • 先生非常感谢您的启发,但请您告诉我如何在服务器端 api 中进行分页以获取下一个 20 个数据集
  • 很高兴知道我可以提供帮助。是的,关于分页,这完全是另一个讨论。但是,我只是给你一个提示。尝试从客户端发送一个额外的参数页码,例如 1,以便服务器理解,它需要发送前 20 个数据。要获取下一个 20,请从客户端发送第 2 页,依此类推...
  • 再次感谢您的大力帮助
  • @ReazMurshed 我有同样的问题,正如你所说,我已经嵌套了图像的 recyclerview 并且它闪烁了很多,所以我尝试删除图像 recyclerview 但同样发生,我正在为 recyclerview 使用反向布局,你认为这可能是问题吗?
  • 用反向布局设置 RecylerView 实际上应该不是问题。没有看到代码,虽然很难理解你的问题。如果您在某处发布了问题,请在此处发布链接 - 我会尝试看看!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-08
  • 2010-11-17
  • 1970-01-01
  • 1970-01-01
  • 2018-06-20
相关资源
最近更新 更多