简体   繁体   English

在保持滚动位置的同时更新RecyclerView

[英]Update RecyclerView while keeping its scroll position

How can I keep the current scroll position in a RecyclerView after updating the contents? 更新内容后如何在RecyclerView保持当前滚动位置?

In the onCreate I set a task to repeat as follows: onCreate我设置了一个重复执行的任务,如下所示:

private void setRepeatingAsyncTask() {

    final Handler handler = new Handler();
    Timer timer = new Timer();

    TimerTask task = new TimerTask() {
        @Override
        public void run() {
            handler.post(new Runnable() {
                public void run() {
                    try {
                        new getArrivals().execute(station_id);
                    } catch (Exception e) {
                        // error, do something
                    }
                }
            });
        }
    };
    timer.schedule(task, 0, 30000);  // interval of 30 seconds
}

The AsyncTask will query the database for the latest list contents: AsyncTask将在数据库中查询最新列表内容:

private class getArrivals extends AsyncTask<Long, Void, Long>{

        @Override
        protected void onPreExecute(){
            //emptyMessage.setVisibility(VISIBLE);
            //recyclerView.setVisibility(GONE);
        }
        @Override
        protected Long doInBackground(Long... params) {
            long station_id = params[0];
            station = db.stationModel().getStationById(station_id);
            arrivals = db.arrivalModel().getNextArrivalsByStation(station_id, StaticClass.getDays());
            return station_id;
        }

        @Override
        protected void onPostExecute(Long result){
            if(getSupportActionBar() != null) {
                getSupportActionBar().setTitle(capitalize(station.name));
            }

            refreshList();
        }
}

Upon completion of the task I then call for the list to be refreshed: 完成任务后,我要求刷新列表:

private void refreshList(){

    arrivalListAdapter = new ArrivalListAdapter(getApplicationContext(), arrivals);
    staggeredGridLayoutManager = new StaggeredGridLayoutManager(1, StaggeredGridLayoutManager.VERTICAL);
    recyclerView.setLayoutManager(staggeredGridLayoutManager);
    recyclerView.setAdapter(arrivalListAdapter);
    Log.d("arrivals", arrivals.size()+"");
    arrivalListAdapter.notifyDataSetChanged();

    if(arrivals.size() == 0){
        emptyMessage.setVisibility(VISIBLE);
        recyclerView.setVisibility(GONE);

        new fetchArrivalsFromSource().execute(station.id);
    }else{
        emptyMessage.setVisibility(GONE);
        recyclerView.setVisibility(VISIBLE);
    }
}

I'm pretty sure that the reason for my issue is that I'm setting the adapter everytime. 我很确定问题的原因是我每次都要设置适配器。 I've tried setting that with the initial task but that leads to the list not being updated at all. 我尝试用初始任务设置它,但是导致列表根本没有更新。

You can get the current position, refresh the adapter and smooth scroll to the previous position like this: 您可以获取当前位置,刷新适配器并平滑滚动到上一个位置,如下所示:

RecyclerView.SmoothScroller smoothScroller = new LinearSmoothScroller(context) {
  @Override protected int getVerticalSnapPreference() {
    return LinearSmoothScroller.SNAP_TO_START;
  }
};

Then set the position to scroll to: 然后将位置设置为滚动到:

smoothScroller.setTargetPosition(position);
layoutManager.startSmoothScroll(smoothScroller);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM