加载新数据时,RecyclerView滚动顶部 [英] RecyclerView scrolling top when loading new data

查看:86
本文介绍了加载新数据时,RecyclerView滚动顶部的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对RecyclerView有问题.我对它实现了OnScrollListener,当用户到达列表末尾时,它应该根据索引来加载新数据(索引1加载前8个索引2加载后8个索引,依此类推),但是问题是适配器开始加载新数据后立即将其滚动到顶部:(

I have a problem with RecyclerView. I implemented OnScrollListener to it and when user reach end of list it should load a new data depending on index (index 1 loading first 8 index 2 loading second 8 etc) But problem is as soon as adapter start loading new data it scroll me to top :(

这是我调用服务器的函数中的代码:

This is my code from function where I'm calling server:

  public void showlist() {
    progressBar = new ProgressDialog(getActivity());
    progressBar.setMessage("Please wait ...");
    progressBar.show();
    NetworkSDK.getInstance().getNews(size, offset, new Callback<List<News>>() {
        @Override
        public void onResponse(Call<List<News>> call, Response<List<News>> response) {
            if (response.code() == 401) {
                Intent intent = new Intent(getContext(), MainPreLogin.class);
                intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
                progressBar.dismiss();
                startActivity(intent);
                SharedData.getInstance().removeString("token");


            }
            if (response.isSuccess()) {
                newsAdapter = new NewsAdapterRecycler(listNews);

                if (response.body().size() == 0) {
                    progressBar.dismiss();
                    Toast.makeText(getActivity(), R.string.noMorenews, Toast.LENGTH_SHORT).show();



                } else {
                    for (int i = 0; i < response.body().size(); i++) {
                        newsAdapter.insert(newsAdapter.getItemCount() + 1, response.body().get(i));
                    }
                    newsList.setAdapter(newsAdapter);
                    newsAdapter.notifyDataSetChanged();
                    progressBar.dismiss();



                }

            }
        }

        @Override
        public void onFailure(Call<List<ba.project.models.News>> call, Throwable t) {
            Toast.makeText(getContext(), R.string.errorNoconnection, Toast.LENGTH_LONG).show();
            progressBar.dismiss();


        }
    });

}

这是我的适配器:

public class NewsAdapterRecycler extends RecyclerView.Adapter<NewsAdapterRecycler.MyViewHolder> {

private static int selectedItem = -1;
ArrayList<News> newslist;
Context context;

public NewsAdapterRecycler(ArrayList<News> newslist) {

    this.newslist = newslist;

}

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    context = parent.getContext();
    View itemView = LayoutInflater.from(parent.getContext())
            .inflate(R.layout.single_news_layout, parent, false);
    return new MyViewHolder(itemView);
}

@Override

public void onBindViewHolder(MyViewHolder holder, int position) {
    View view = null;
    Log.d("Pozicija News",String.valueOf(position));
    News news = newslist.get(position);
    holder.shortText.setText(news.getIntro());
    holder.name.setText(news.getSubject());
    if (news.getImagePath().equals(""))
        Picasso.with(context).load(R.drawable.logo_Def).fit().centerCrop().into(holder.picture);
    else
        Picasso.with(context).load(news.getImagePath()).fit().centerCrop().into(holder.picture);



    holder.date.setText(news.getShortDate());

    if (selectedItem == position)
        holder.itemView.setSelected(true);

}

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


public void insert(int position, News data) {
    newslist.add(position - 1, data);
    notifyItemInserted(position);
}

public class MyViewHolder extends RecyclerView.ViewHolder {
    TextView name;
    TextView shortText;
    TextView date;
    ImageView picture;

    public MyViewHolder(View view) {
        super(view);
        this.name=(TextView)view.findViewById(R.id.news_title);
        this.shortText=(TextView)view.findViewById(R.id.news_desc);
        this.picture=(ImageView)view.findViewById(R.id.news_image);
        this.date=(TextView)view.findViewById(R.id.news_date);
    }
}

}

这是我的scrolllsitener

This is my scrolllsitener

  newsList.addOnScrollListener(new RecyclerView.OnScrollListener() {

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            super.onScrolled(recyclerView, dx, dy);
            visibleItemCount = newsList.getChildCount();
            totalItemCount = mLayoutManager.getItemCount();
            firstVisibleItem = mLayoutManager.findFirstVisibleItemPosition();
            Log.d("Visibleitem", String.valueOf(visibleItemCount));
            Log.d("totalItem", String.valueOf(totalItemCount));
            Log.d("firstvisibleitem", String.valueOf(firstVisibleItem));
            if (restarting) {
                previousTotal = 0;
                visibleThreshold = 5;

            }
            if (loading) {
                if (totalItemCount > previousTotal) {
                    loading = false;

                    previousTotal = totalItemCount;
                }
            }
            if (!loading && (totalItemCount - visibleItemCount)
                    <= (firstVisibleItem + visibleThreshold)) {
                offset++;
                showlist();
                // Do something

                loading = true;
                restarting = false;
            }
        }
    });

如果是米,则每次用户通过此滚动到该片段时,都会调用此功能:

Also if it's meter this funciton is called every time when user scroll to this fragment via this:

  @Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (isVisibleToUser && !areNewsLoaded) {
        listNews = new ArrayList<>();
        offset=0;
        showlist();
        restarting = true;



    }

}

推荐答案

我尝试了上面发布的解决方案,但没有任何效果.有帮助的我设法找到了一些解决方法.解决方案是在3条魔术线上:

I tried solutions posted above but none worked. Helpfully I manage to find some fix. Solution is in 3 magic lines :

 private Parcelable recyclerViewState; 
 recyclerViewState = newsList.getLayoutManager().onSaveInstanceState();
 newsList.getLayoutManager().onRestoreInstanceState(recyclerViewState);

所以基本上我在将新内容添加到列表之前添加了2.行,我猜它还记得当前位置,我在添加内容后添加了3.行,所以我假设这段代码记住了位置

So basically I added 2. line before adding new content to my list and I guess it remember current position and I added 3. line after adding content so I assume this piece of code remember position

这篇关于加载新数据时,RecyclerView滚动顶部的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆