无法保持Firestore RecyclerView状态返回导航

时间:2018-11-22 02:55:12

标签: java android firebase android-recyclerview

我有一个包含Recylcerview的片段。此RecyclerView使用Firebase FirestoreUI填充。

下面是我的RecyclerView的代码,我在.onStart()中调用它来侦听更改:

@Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        if (savedInstanceState != null) {
            mRecyclerViewState = savedInstanceState.getParcelable(RECYCLERVIEW_STATE);
        }
        mRecyclerview = (RecyclerView) view.findViewById(R.id.list);
        mPollHolderArray = new ArrayList<>();
        mRecyclerview.getItemAnimator().setChangeDuration(0);


        mLayoutManager = new LinearLayoutManager(getContext());
        mLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
        //TODO: Detertmine if necessary since ordering is now different in Firebase
        mLayoutManager.setReverseLayout(true);
        mLayoutManager.setStackFromEnd(true);

        mFloatingActionAdd = (FloatingActionButton) getActivity().findViewById(R.id.myFAB);
        mFloatingActionAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent I = new Intent(getActivity().getApplicationContext(), CreateActivity.class);
                startActivity(I);
            }
        });


        mRecyclerview.setLayoutManager(mLayoutManager);

        if (mRecyclerViewState != null){
            mLayoutManager.onRestoreInstanceState(mRecyclerViewState);
        }


        if (mFirestoreAdaper == null) {
            Query queryStore = FirebaseFirestore.getInstance()
                    .collection(POLLS_LABEL)
                    .orderBy("timestamp", Query.Direction.ASCENDING);
            //Cloud Firestore does not have any ordering; must implement a timestampe to order sequentially

            FirestoreRecyclerOptions<Poll> storeOptions = new FirestoreRecyclerOptions.Builder<Poll>()
                    .setQuery(queryStore, Poll.class)
                    .build();
            mFirestoreAdaper = new FirestoreRecyclerAdapter<Poll, PollHolder>(storeOptions) {
                @Override
                protected void onBindViewHolder(@NonNull final PollHolder holder, final int position, @NonNull Poll model) {
                    holder.mPollQuestion.setText(model.getQuestion());
                    String voteCount = String.valueOf(model.getVote_count());
                    //TODO: Investigate formatting of vote count for thousands
                    holder.mVoteCount.setText(voteCount);
                    Picasso.get()
                            .load(model.getImage_URL())
                            .fit()
                            .into(holder.mPollImage);
                    holder.mView.setOnClickListener(new View.OnClickListener() {
                        @Override
                        public void onClick(View view) {
                            Intent toClickedPoll = new Intent(getActivity(), PollHostActivity.class);
                            String recyclerPosition = getSnapshots().getSnapshot(position).getId();
                            Log.v("Firestore ID", recyclerPosition);
                            toClickedPoll.putExtra("POLL_ID", recyclerPosition);
                            startActivity(toClickedPoll);

                        }
                    });
                }


                @Override
                public PollHolder onCreateViewHolder(ViewGroup parent, int viewType) {
                    View v = LayoutInflater.from(parent.getContext())
                            .inflate(R.layout.latest_item, parent, false);
                    return new PollHolder(v);
                }


            };
            mRecyclerview.setAdapter(mFirestoreAdaper);
        }
    }

当我导航到另一个片段(on RecyclerView的onClick),然后返回到包含此RecyclerView的片段时,我希望能够保持被单击的位置。但是,这没有发生。下面是我尝试保存状态的代码,它只是恢复到RecyclerView的顶部项:

    @Override
    public void onSaveInstanceState(@NonNull Bundle outState) {
    super.onSaveInstanceState(outState);
    mRecyclerViewState = mLayoutManager.onSaveInstanceState();
    outState.putParcelable(RECYCLERVIEW_STATE, mRecyclerViewState);

}

编辑:原始片段是ViewPager的一部分(我现在正在NewFragment上对其进行测试):

    public class SectionPagerAdapter extends FragmentPagerAdapter {

    public SectionPagerAdapter(FragmentManager fm) {
        super(fm);
    }

    @Override
    public Fragment getItem(int position) {
        switch (position) {
            case 0:
                return new TrendingFragment();
            case 1:
                return new FollowingFragment();
            case 2:
                return new NewFragment();
            default:
                return new TrendingFragment();
        }
    }

1 个答案:

答案 0 :(得分:1)

那是因为您要在onStart中设置新适配器,并且只要您从先前的屏幕或背景恢复片段,就会发生这种情况。

您不需要所有这些逻辑来记住位置,只需初始化适配器并将其设置在生命周期内的正确位置即可。

在片段中,将适配器设置为onViewCreated而不是onStart

@Override public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mRecyclerview = view.findViewById(...);
    if (mAdapter == null) {
        mAdapter = new FirestoreRecyclerAdapter(...)
        mRecyclerView.setAdapter(mAdapter);
        mAdapter.startListening();
    }
}

@Override public void onDestroyView() {
    super.onDestroyView();
    mAdapter.stopListening();
}

并删除所有保存和恢复头寸的逻辑(onSaveInstanceStatescrollToPositiononRestoreInstanceState),您将不需要它们!