Android 当从其他活动返回到同一片段时,如何保存和恢复片段中RecyclerView的滚动位置?

Android 当从其他活动返回到同一片段时,如何保存和恢复片段中RecyclerView的滚动位置?,android,android-fragments,android-recyclerview,Android,Android Fragments,Android Recyclerview,请版主回答:这不是一个重复的问题,请阅读以下信息 在问这个问题之前,我尝试了几乎所有可用的解决方案,但没有一个对我有效,有些导致崩溃,有些根本不起作用(我是一个初学者,可能是我在代码中做错了什么,我不怪任何人的答案不适用于我的情况)。下面是我的代码,请看一下: fragment_tab1.xml(包含recyclerview): Fragmenttab1.java public class tab1 extends Fragment { RecyclerView mRecycler

请版主回答:这不是一个重复的问题,请阅读以下信息

在问这个问题之前,我尝试了几乎所有可用的解决方案,但没有一个对我有效,有些导致崩溃,有些根本不起作用(我是一个初学者,可能是我在代码中做错了什么,我不怪任何人的答案不适用于我的情况)。下面是我的代码,请看一下:

fragment_tab1.xml(包含recyclerview):


Fragmenttab1.java

public class tab1  extends Fragment {
    RecyclerView mRecyclerView;
    FirebaseDatabase mFirebaseDatabase;
    DatabaseReference mRef;
    LinearLayoutManager manager;
    private static final String TAG = "tab1";
    ProgressDialog progressDialog;
    View rootView;
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

        //Returning the layout file after inflating
        //Change R.layout.tab1 in you classes
         rootView = inflater.inflate(R.layout.fragment_tab1, container, false);


return rootView;

    }


    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);



        manager = new LinearLayoutManager(getActivity());
        mRecyclerView.setLayoutManager(manager);
        mRecyclerView.setItemViewCacheSize(20);
        mRecyclerView.setDrawingCacheEnabled(true);
        mFirebaseDatabase = FirebaseDatabase.getInstance();
        mRef = mFirebaseDatabase.getReference("memes");

        mFirebaseDatabase.getInstance().getReference().keepSynced(true);

        progressDialog = new ProgressDialog(getActivity());
        progressDialog.setMessage("Please Wait");
        progressDialog.show();

    }

    public void onStart() {

        super.onStart();


        FirebaseRecyclerAdapter<Model, ViewHolder> firebaseRecyclerAdapter =
                new FirebaseRecyclerAdapter<Model, ViewHolder>(
                        Model.class,
                        R.layout.row2,
                        ViewHolder.class,
                        mRef

                ) {



                    @Override
                    protected void populateViewHolder(ViewHolder viewHolder, Model model, int position) {
                        viewHolder.setDetails(getActivity(), model.getTitle(), model.getDesc(), model.getImage());
                        progressDialog.cancel();
                    }



                    @Override
                    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

                        ViewHolder viewHolder = super.onCreateViewHolder(parent, viewType);

                        viewHolder.setOnClickListener(new ViewHolder.ClickListener(){




                            @Override
                            public void onItemClick(View view, int position){



                                //get data from firebase here
                                String mTitle = getItem(position).getTitle();
                                String mDesc= getItem(position).getDesc();
                                String mImage = getItem(position).getImage();

                                //pass this data to new activity
                                Intent intent = new Intent(view.getContext(), ArticleDetail.class);
                                intent.putExtra("title", mTitle);// put title
                                intent.putExtra("desc", mDesc);// put description
                                intent.putExtra("image", mImage); //put image urls

                                startActivity(intent);
                            }




                            @Override
                            public void onItemLongClick(View view, int position){

                                //TODO your own implementation on long item click


                            }

                        });

                        return viewHolder;
                    }
                };


        mRecyclerView.setAdapter(firebaseRecyclerAdapter);

    }

    @Override
    public void  onPause() {
        super.onPause();
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());

        View firstChild = mRecyclerView.getChildAt(0);
        int firstVisiblePosition = mRecyclerView.getChildAdapterPosition(firstChild);
        int offset = firstChild.getTop();

        Log.d(TAG, "Postition: " + firstVisiblePosition);
        Log.d(TAG, "Offset: " + offset);

        preferences.edit()
                .putInt("position", firstVisiblePosition)
                .putInt("offset", offset)
                .apply();
    }


    @Override
    public void onResume(){
        super.onResume();

    }
    @Override
    public void onSaveInstanceState(Bundle outState) {


        super.onSaveInstanceState(outState);
    }

    @Override
    public void onViewStateRestored(@Nullable Bundle savedInstanceState) {


        super.onViewStateRestored(savedInstanceState);
    }

}
public类tab1扩展了片段{
回收视图mRecyclerView;
FirebaseDatabase mFirebaseDatabase;
数据库参考mRef;
直线布局经理;
私有静态最终字符串TAG=“tab1”;
进行对话进行对话;
视图根视图;
@凌驾
CreateView上的公共视图(布局、充气机、视图组容器、捆绑包保存状态){
//充气后返回布局文件
//更改类中的R.layout.tab1
rootView=充气机。充气(R.layout.fragment_tab1,容器,假);
返回rootView;
}
@凌驾
ActivityCreated上的公共无效(@Nullable Bundle savedinStateCState){
super.onActivityCreated(savedInstanceState);
mRecyclerView=(RecyclerView)rootView.findviewbyd(R.id.recycler\u视图);
manager=新的LinearLayoutManager(getActivity());
mRecyclerView.setLayoutManager(manager);
mRecyclerView.setItemViewCacheSize(20);
mRecyclerView.setDrawingCacheEnabled(true);
mFirebaseDatabase=FirebaseDatabase.getInstance();
mRef=mFirebaseDatabase.getReference(“memes”);
mFirebaseDatabase.getInstance().getReference().KeepSync(true);
progressDialog=新建progressDialog(getActivity());
progressDialog.setMessage(“请稍候”);
progressDialog.show();
}
public void onStart(){
super.onStart();
FirebaseRecyclerAdapter FirebaseRecyclerAdapter=
新型FirebaseRecyclerAdapter(
模型类,
R.layout.row2,
ViewHolder.class,
mRef
) {
@凌驾
受保护的void populateViewHolder(ViewHolder ViewHolder、模型、int位置){
viewHolder.setDetails(getActivity()、model.getTitle()、model.getDesc()、model.getImage());
progressDialog.cancel();
}
@凌驾
public ViewHolder onCreateViewHolder(视图组父级,int-viewType){
ViewHolder ViewHolder=super.onCreateViewHolder(父级,viewType);
viewHolder.setOnClickListener(新建viewHolder.ClickListener(){
@凌驾
公共虚线单击(视图,int位置){
//从firebase获取数据
字符串mTitle=getItem(position).getTitle();
字符串mDesc=getItem(position).getDesc();
字符串mImage=getItem(position).getImage();
//将此数据传递给新活动
Intent Intent=新的Intent(view.getContext(),articledeail.class);
intent.putExtra(“title”,mTitle);//放置title
intent.putExtra(“desc”,mDesc);//放置说明
intent.putExtra(“image”,mImage);//放置图像URL
星触觉(意向);
}
@凌驾
长单击(视图,int位置)时的公共无效{
//在长项目单击上执行自己的实现
}
});
返回视图持有者;
}
};
mRecyclerView.setAdapter(firebaseRecyclerAdapter);
}
@凌驾
公共无效暂停(){
super.onPause();
SharedReferences preferences=PreferenceManager.GetDefaultSharedReferences(getActivity());
View firstChild=mRecyclerView.getChildAt(0);
int firstVisiblePosition=mRecyclerView.getChildAdapterPosition(firstChild);
int offset=firstChild.getTop();
日志d(标签“位置:”+firstVisiblePosition);
Log.d(标记“偏移量:”+偏移量);
preferences.edit()
.putInt(“位置”,第一可见位置)
.putInt(“偏移量”,偏移量)
.apply();
}
@凌驾
恢复时公开作废(){
super.onResume();
}
@凌驾
SaveInstanceState上的公共无效(束超出状态){
super.onSaveInstanceState(超出状态);
}
@凌驾
ViewStateRestored上的公共无效(@Nullable Bundle savedinStateCState){
super.onViewStateRestored(savedInstanceState);
}
}

您应该使用此方法返回第一个可见项:

int findFirstVisibleItemPosition()

然后,您必须将此索引保存在onPause()上,当用户返回retrieve并将其设置为onResume()时:


在支付了这么多天的费用后,在尝试了许多解决方案后,终于找到了解决我问题的有效方法,这要感谢

我已经将工作解决方案移动到另一个方法,以使其在片段中工作

也许这可以拯救某人的一天,下面是它的工作原理:

  • OnConfiguration已更改(如原始解决方案中所建议的),onSaveInstanceState或onViewRestoredState方法不起作用,因此您需要
    public class tab1  extends Fragment {
        RecyclerView mRecyclerView;
        FirebaseDatabase mFirebaseDatabase;
        DatabaseReference mRef;
        LinearLayoutManager manager;
        private static final String TAG = "tab1";
        ProgressDialog progressDialog;
        View rootView;
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    
            //Returning the layout file after inflating
            //Change R.layout.tab1 in you classes
             rootView = inflater.inflate(R.layout.fragment_tab1, container, false);
    
    
    return rootView;
    
        }
    
    
        @Override
        public void onActivityCreated(@Nullable Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recycler_view);
    
    
    
            manager = new LinearLayoutManager(getActivity());
            mRecyclerView.setLayoutManager(manager);
            mRecyclerView.setItemViewCacheSize(20);
            mRecyclerView.setDrawingCacheEnabled(true);
            mFirebaseDatabase = FirebaseDatabase.getInstance();
            mRef = mFirebaseDatabase.getReference("memes");
    
            mFirebaseDatabase.getInstance().getReference().keepSynced(true);
    
            progressDialog = new ProgressDialog(getActivity());
            progressDialog.setMessage("Please Wait");
            progressDialog.show();
    
        }
    
        public void onStart() {
    
            super.onStart();
    
    
            FirebaseRecyclerAdapter<Model, ViewHolder> firebaseRecyclerAdapter =
                    new FirebaseRecyclerAdapter<Model, ViewHolder>(
                            Model.class,
                            R.layout.row2,
                            ViewHolder.class,
                            mRef
    
                    ) {
    
    
    
                        @Override
                        protected void populateViewHolder(ViewHolder viewHolder, Model model, int position) {
                            viewHolder.setDetails(getActivity(), model.getTitle(), model.getDesc(), model.getImage());
                            progressDialog.cancel();
                        }
    
    
    
                        @Override
                        public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    
                            ViewHolder viewHolder = super.onCreateViewHolder(parent, viewType);
    
                            viewHolder.setOnClickListener(new ViewHolder.ClickListener(){
    
    
    
    
                                @Override
                                public void onItemClick(View view, int position){
    
    
    
                                    //get data from firebase here
                                    String mTitle = getItem(position).getTitle();
                                    String mDesc= getItem(position).getDesc();
                                    String mImage = getItem(position).getImage();
    
                                    //pass this data to new activity
                                    Intent intent = new Intent(view.getContext(), ArticleDetail.class);
                                    intent.putExtra("title", mTitle);// put title
                                    intent.putExtra("desc", mDesc);// put description
                                    intent.putExtra("image", mImage); //put image urls
    
                                    startActivity(intent);
                                }
    
    
    
    
                                @Override
                                public void onItemLongClick(View view, int position){
    
                                    //TODO your own implementation on long item click
    
    
                                }
    
                            });
    
                            return viewHolder;
                        }
                    };
    
    
            mRecyclerView.setAdapter(firebaseRecyclerAdapter);
    
        }
    
        @Override
        public void  onPause() {
            super.onPause();
            SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getActivity());
    
            View firstChild = mRecyclerView.getChildAt(0);
            int firstVisiblePosition = mRecyclerView.getChildAdapterPosition(firstChild);
            int offset = firstChild.getTop();
    
            Log.d(TAG, "Postition: " + firstVisiblePosition);
            Log.d(TAG, "Offset: " + offset);
    
            preferences.edit()
                    .putInt("position", firstVisiblePosition)
                    .putInt("offset", offset)
                    .apply();
        }
    
    
        @Override
        public void onResume(){
            super.onResume();
    
        }
        @Override
        public void onSaveInstanceState(Bundle outState) {
    
    
            super.onSaveInstanceState(outState);
        }
    
        @Override
        public void onViewStateRestored(@Nullable Bundle savedInstanceState) {
    
    
            super.onViewStateRestored(savedInstanceState);
        }
    
    }
    
    void scrollToPosition (int position)
    
    mBundleRecyclerViewState = new Bundle();    
    
    mListState = mRecyclerView.getLayoutManager().onSaveInstanceState();
    
    mBundleRecyclerViewState.putParcelable(KEY_RECYCLER_STATE, mListState);
    
       if (mBundleRecyclerViewState != null) {
            new Handler().postDelayed(new Runnable() {
    
                @Override
                public void run() {
                    mListState = mBundleRecyclerViewState.getParcelable(KEY_RECYCLER_STATE);
                    mRecyclerView.getLayoutManager().onRestoreInstanceState(mListState);
    
                }
            }, 50);
        }
    
    
        mRecyclerView.setLayoutManager(staggeredGridLayoutManager);
    
    implementation "androidx.recyclerview:recyclerview:1.2.0"
    
     listAdapter = ListAdapter()
    
     // Set scroll restore policy
     listdapter.stateRestorationPolicy =
          RecyclerView.Adapter.StateRestorationPolicy.PREVENT_WHEN_EMPTY