【问题标题】:Retaining the scrolled position in RecyclerView with scrollToPosition is not working使用 scrollToPosition 在 RecyclerView 中保留滚动位置不起作用
【发布时间】:2017-12-26 22:36:18
【问题描述】:

我正在尝试使用 onPause 和 onResume 方法来保留 RecyclerView 的滚动位置,当意图用于启动另一个活动(在我的情况下是网络浏览器)时

当我调试 onResume 方法时,“lastFirstVisiblePosition”是一个有效的整数,但是屏幕仍然一直滚动到 RecyclerView 的第一个元素。

感谢您的帮助,提前感谢您。

编辑:我正在使用 viewpager,并且我有多个回收站视图/片段

这是我的片段:

public class CultureFragment extends Fragment implements LoaderManager.LoaderCallbacks<List<News>>, RecyclerViewAdapter.OnItemClicked {
    private String baseUrlString = "https://content.guardianapis.com/search?show-fields=headline,thumbnail,wordcount,trailText";
    private String LOG_TAG = CultureFragment.class.getName();
    public LoaderManager loaderManager;
    private RecyclerView recyclerView;
    private RecyclerViewAdapter recyclerViewAdapter;
    private TextView mEmptyStateTextView;
    private View LoadingIndicator;
    private RecyclerView.LayoutManager layoutManager;
    private int lastFirstVisiblePosition;

    View rootView;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        setRetainInstance(true);

        //initialise rootview
        rootView = inflater.inflate(R.layout.word_recycler_view, container, false);

        //set up empty text view
        mEmptyStateTextView = rootView.findViewById(R.id.empty_view);
        mEmptyStateTextView.setVisibility(View.GONE);

        //Set up loading indicator
        LoadingIndicator = rootView.findViewById(R.id.loading_indicator);


        // initialising the recycler view and setting the adapter for adding items.
        recyclerView = rootView.findViewById(R.id.recycler_view);
        recyclerView.setAdapter(recyclerViewAdapter);


        //set the layout manager for item positioning in the list
        layoutManager = new LinearLayoutManager(getContext());
        recyclerView.setLayoutManager(layoutManager);


        //Setting up loadermanager if there is connection
        if (NewsActivity.isConnected) {
            loaderManager = getLoaderManager();
            loaderManager.initLoader(1, null, this);
        } else {
            recyclerView.setVisibility(View.GONE);
            LoadingIndicator.setVisibility(View.GONE);
            mEmptyStateTextView.setVisibility(View.VISIBLE);
            mEmptyStateTextView.setText(R.string.no_connection);
        }


        return rootView;
    }


    @Override
    public Loader<List<News>> onCreateLoader(int id, Bundle args) {

        Uri baseUri = Uri.parse(baseUrlString);
        Uri.Builder uriBuilder = baseUri.buildUpon();

        //Create the URL
        uriBuilder.appendQueryParameter("section", "culture");
        uriBuilder.appendQueryParameter("page-size", "20");
        uriBuilder.appendQueryParameter("api-key", "test");
        uriBuilder.appendQueryParameter("format", "json");
        uriBuilder.appendQueryParameter("orderBy", "newest");

        Log.e(LOG_TAG, " the url  " + uriBuilder.toString());

        return new NewsLoader(getContext(), uriBuilder.toString());
    }

    @Override
    public void onLoadFinished(android.support.v4.content.Loader<List<News>> loader, List<News> data) {
        //populate the recyclerview
        //dismiss the loading indicator
        LoadingIndicator.setVisibility(View.GONE);

        if (data != null) {
            recyclerViewAdapter = new RecyclerViewAdapter(getContext(), data);
            recyclerView.setAdapter(recyclerViewAdapter);


            //set the on click listener if the adapter is not NULL (here)
            recyclerViewAdapter.setOnClick(this);

        } else {

            // Remove recycler view, and set the no text textview
            recyclerView.setVisibility(View.GONE);
            mEmptyStateTextView.setVisibility(View.VISIBLE);
            mEmptyStateTextView.setText(R.string.no_stories);

        }

    }

    @Override
    public void onLoaderReset(android.support.v4.content.Loader<List<News>> loader) {

    }

    /*Custom on item click method, implemented in the recycler view Adapter*/
    @Override
    public void onItemClick(int position) {
        News news = recyclerViewAdapter.getItem(position);

        Intent i = new Intent(Intent.ACTION_VIEW);
        i.setData(Uri.parse(news.getmWebUrl()));
        startActivity(i);

    }

    @Override
    public void onPause() {
        super.onPause();
        lastFirstVisiblePosition = ((LinearLayoutManager) recyclerView.getLayoutManager()).findFirstVisibleItemPosition();
    }

    @Override
    public void onResume() {
        super.onResume();
        if (lastFirstVisiblePosition > 0) {
            ((LinearLayoutManager) recyclerView.getLayoutManager()).scrollToPosition(lastFirstVisiblePosition);

        }
    }
}

【问题讨论】:

  • 实际上发生的情况是,recyclerview 出于某种原因一直向上滚动。

标签: android android-recyclerview onresume onpause


【解决方案1】:

使用 LinearLayoutManager 和 2 个方法:

 linearLayoutManagerInstance.onSaveInstanceState()
 linearLayoutManagerInstance.onRestoreInstanceState()

【讨论】:

  • 嗨 Jose,为什么 onpause 和 onrestore 在这种情况下不起作用?
  • 您需要使用正确的方式@tipi linearlayoutmanager 有一个使用 onsave 和 on restore 的实例。 onPause 和 onRestore 适用于所有应用,而不仅仅是 recyclerview
猜你喜欢
  • 2017-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-08
  • 1970-01-01
  • 2014-12-22
  • 1970-01-01
相关资源
最近更新 更多