【发布时间】:2017-07-19 17:37:44
【问题描述】:
我正在开发一个简单的 APOD 应用程序,它实现了:
RecyclerViewCardViewFirebasePicasso
应用程序从Firebase 和Firebase Storage 中获取图像和文本,将它们显示在CardView 中,并为每个View 设置一个OnClickListener。当用户单击图像时,我通过Intent 打开一个新的Activity。第二个Activity 显示原始点击图像,以及有关它的更多信息。
我已经使用GridLayoutManager 实现了这一切,如果用户的手机是垂直的,则为 1 列,如果用户的手机是水平的,则为 3 列。
我遇到的问题是我似乎无法保存RecyclerView 在方向更改时的位置。我已经尝试了我能找到的每一个选项,但似乎没有一个有效。我能得出的唯一结论是,在轮换时,我正在销毁Firebase 的ChildEventListener 以避免内存泄漏,一旦定位完成,Firebase 将重新查询数据库,因为新的ChildEventListener 的实例。
有什么方法可以保存我的RecyclerView 在方向更改时的位置?我不想要android:configChanges,因为它不允许我更改布局,而且我已经尝试保存为Parcelable,但没有成功。我敢肯定我错过了一些简单的事情,但是嘿,我是开发新手。非常感谢对我的代码的任何帮助或建议。谢谢!
以下是我的课程,我已将其缩短为必要的代码。
MainActivity
public class MainActivity extends AppCompatActivity {
private RecyclerAdapter mRecyclerAdapter;
private DatabaseReference mDatabaseReference;
private RecyclerView mRecyclerView;
private Query query;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PreferenceManager.setDefaultValues(this, R.xml.preferences, false);
setContentView(R.layout.activity_main);
getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final int columns = getResources().getInteger(R.integer.gallery_columns);
mDatabaseReference = FirebaseDatabase.getInstance().getReference();
query = mDatabaseReference.child("apod").orderByChild("date");
mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(new GridLayoutManager(this, columns));
mRecyclerAdapter = new RecyclerAdapter(this, query);
mRecyclerView.setAdapter(mRecyclerAdapter);
}
@Override
public void onDestroy() {
mRecyclerAdapter.cleanupListener();
}
}
RecyclerAdapter
public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ApodViewHolder> {
private final Context mContext;
private final ChildEventListener mChildEventListener;
private final Query mDatabaseReference;
private final List<String> apodListIds = new ArrayList<>();
private final List<Apod> apodList = new ArrayList<>();
public RecyclerAdapter(final Context context, Query ref) {
mContext = context;
mDatabaseReference = ref;
ChildEventListener childEventListener = new ChildEventListener() {
@Override
public void onChildAdded(DataSnapshot dataSnapshot, String s) {
int oldListSize = getItemCount();
Apod apod = dataSnapshot.getValue(Apod.class);
//Add data and IDs to the list
apodListIds.add(dataSnapshot.getKey());
apodList.add(apod);
//Update the RecyclerView
notifyItemInserted(oldListSize - getItemCount() - 1);
}
@Override
public void onChildChanged(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onChildRemoved(DataSnapshot dataSnapshot) {
String apodKey = dataSnapshot.getKey();
int apodIndex = apodListIds.indexOf(apodKey);
if (apodIndex > -1) {
// Remove data and IDs from the list
apodListIds.remove(apodIndex);
apodList.remove(apodIndex);
// Update the RecyclerView
notifyDataSetChanged();
}
}
@Override
public void onChildMoved(DataSnapshot dataSnapshot, String s) {
}
@Override
public void onCancelled(DatabaseError databaseError) {
}
};
ref.addChildEventListener(childEventListener);
mChildEventListener = childEventListener;
}
@Override
public int getItemCount() {
return apodList.size();
}
public void cleanupListener() {
if (mChildEventListener != null) {
mDatabaseReference.removeEventListener(mChildEventListener);
}
}
}
【问题讨论】:
-
我认为问题在于配置更改后的新 RV 在 onCreate 结束时对其视图内容一无所知,因为该数据仅在所有子侦听器触发后才会出现。所以它不知道如何完全恢复自己,因为它认为它当时是空的。我不知道临时解决方案,但确实想提供该信息。如果有帮助,您可以查询 RV 的滚动偏移量。
-
@DougStevenson。非常感谢 Doug,我尝试保存和恢复该位置,但无法使其正常工作。我认为这篇文章会引起更多关注,因为我要么完全遗漏了某些东西,要么 Firebase 很难实现这种东西。我会继续尝试,如果我发现任何其他内容,我会更新我的帖子。
标签: android firebase firebase-realtime-database