当我从另一个活动返回到相同的活动时,我正在尝试保持我的FirebaseRecyclerAdapter
的滚动位置。
下面是我的函数,它设置FirebaseRecyclerAdapter
public void setTheScreen(){
FirebaseRecyclerAdapter<Post,PostViewHolder> firebaseRecyclerAdapter = new FirebaseRecyclerAdapter<Post,PostViewHolder>(
Post.class,
R.layout.post_display_blueprint,
PostViewHolder.class,
postsNode
) {
@Override
public void onDataChanged() {
if(dialog != null && dialog.isShowing()){
dialog.dismiss();
}
}
@Override
protected void populateViewHolder(final PostViewHolder viewHolder, Post model, int position) {
final String key = getRef(position).getKey();
mRefPosts = FirebaseDatabase.getInstance().getReference().child("posts").child(key);
mLoveNode = mRef.child("loves");
mRefLoves = mRef.child("loves").child(key);
viewHolder.setTitle(model.getTitle());
viewHolder.setLoves(mRefLoves);
viewHolder.setLoveButton(Uid,key);
viewHolder.setImage(getApplicationContext(),model.getImageUrl());
mRefPosts.addValueEventListener(new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
String isAnonymous = dataSnapshot.child("anonymous").getValue(String.class);
if (isAnonymous != null && isAnonymous.equals("true")) {
viewHolder.anonymousButton.setVisibility(View.VISIBLE);
}
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
});
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this,PostDisplayPageActivity.class);
intent.putExtra("Key",key);
startActivity(intent);
}
});
}
};
mRecyclerView.setAdapter(firebaseRecyclerAdapter);
firebaseRecyclerAdapter.notifyDataSetChanged();
}
通过单击适配器创建的任何视图,我将从我的MainActivity转到一个名为PostDisplayPageActivity的新活动,然后按下back键,我将完成PostDisplayPageActivity并返回到MainActivity。
当我回到我的MainActivity时,列表从0位置开始
我在onPause和onResume方法中使用了以下代码,但它不起作用。
@Override
protected void onPause() {
super.onPause();
currentVisiblePosition = ((LinearLayoutManager)mRecyclerView.getLayoutManager()).findFirstCompletelyVisibleItemPosition();
Toast.makeText(MainActivity.this,String.valueOf(currentVisiblePosition),Toast.LENGTH_SHORT).show();
}
@Override
protected void onResume() {
super.onResume();
setTheScreen();
mRecyclerView.getLayoutManager().scrollToPosition(currentVisiblePosition);
Toast.makeText(MainActivity.this,String.valueOf(currentVisiblePosition),Toast.LENGTH_SHORT).show();
currentVisiblePosition = 0;
}
从这两个Toasts
中,我得到了正确的位置,但视图总是从位置0开始。
对于我的RecyclerView
,我使用LinearLayoutManager
作为mRecyclerView.setLayoutManager(mLinearLayoutManager);
请有人告诉我我做错了什么,或者给我一个不同的方法。
发布于 2018-10-23 03:32:48
我用一个更简单的解决方案解决了我的问题。我只是在onViewCreated()而不是onStart中调用了adapter.startListening();,并在onDestroyView()中调用了adapter.stopListening();而不是onStop(),这阻止了从下一个活动返回时重新生成整个列表,从而保留了以前的滚动位置。
发布于 2021-08-03 14:15:08
面对同样的问题,我发现许多建议对我都不起作用。因此,我想出了一个解决方法来解决这个问题,即恢复Firebase RecyclerView
状态/滚动位置。
在实现Firebase RecyclerView
的Activity/Fragment中保留RecyclerView instanceStateFirebaseRecycler
的实例状态字段:
private Parcelable instanceStateFirebaseRecycler;
首先,保存Firebase RecyclerView的实例状态instanceStateFirebaseRecycler
,它保留了滚动位置信息onPause()
@Override
public void onPause() {
saveScrollPosition();
super.onPause();
}
其中saveScrollPosition()
方法很简单:
private void saveScrollPosition(){
instanceStateFirebaseRecycler = firebaseRecyclerView.getLayoutManager().onSaveInstanceState();
}
接下来是棘手的部分,您需要向Firebase Adapter
添加一个侦听器,当适配器就绪时,即getItemCount()
不为零时,它会通知您。在监听器的回调中,您可以恢复回收器的状态/滚动位置:
firebaseAdapter = new FirebaseAdapter(options, new FirebaseAdapter.OnRestoreRecyclerStateListener() {
@Override
public void onRestoreRecyclerState() {
restoreScrollPosition();
}
});
firebaseRecyclerView.setAdapter(firebaseAdapter);
其中自定义interface
只是:
public interface OnRestoreRecyclerStateListener {
void onRestoreRecyclerState();
}
并且在Firebase Adapter
onBindViewHolder
(我没有找到更好的地方)中触发callback
,以确保适配器项准备就绪:
@Override
protected void onBindViewHolder(@NonNull ViewHolder holder, int position, @NonNull MyModel model) {
...
onRestoreRecyclerStateListener.onRestoreRecyclerState();
}
,以及restoreScrollPosition()
方法的位置:
private void restoreScrollPosition(){
if (instanceStateFirebaseRecycler == null) return;
firebaseRecyclerView.getRootView().setVisibility(View.GONE);
final Handler handler = new Handler(Looper.getMainLooper());
handler.postDelayed(new Runnable() {
@Override
public void run() {
if (instanceStateFirebaseRecycler == null) return;
firebaseRecyclerView.getLayoutManager().onRestoreInstanceState(instanceStateFirebaseRecycler);
instanceStateFirebaseRecycler = null;
firebaseRecyclerView.getRootView().setVisibility(View.VISIBLE);
}
}, 100);
}
在restoreScrollPosition()
方法中,我检查instanceStateFirebaseRecycler == null
以避免不必要的运行。此外,我通过Handler
延迟了实例状态恢复,因为items
还没有绘制,很快就会绘制。如果没有延迟地调用onRestoreInstanceState
,则状态将不会恢复到预期状态。此外,我通过setVisibility()
切换了RecyclerView
的可见性,以隐藏用户可能会认为是小故障的难看的项目重载和快速滚动。
顺便说一下,@Sanju建议的解决方案在流量和电池效率方面看起来有点危险,因为用户可以将正在运行的应用程序放在后台很长一段时间,而监听器在这段时间内一直处于活动状态。
https://stackoverflow.com/questions/45424383
复制相似问题