android – 如何在使用Firebase&ChildEventListener之后保留RecyclerView的方向更改后的位置?

前端之家收集整理的这篇文章主要介绍了android – 如何在使用Firebase&ChildEventListener之后保留RecyclerView的方向更改后的位置?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在开发一个简单的APOD应用程序,它实现:

> RecyclerView
> CardView
> Firebase
毕加索

该应用程序从Firebase和Firebase Storage中抓取图像和文本,将它们显示在CardView中,并将OnClickListener设置为每个视图.当用户点击图像时,我通过意图打开一个新的活动.第二个活动显示原始点击的图像,以及更多关于它的信息.

如果用户的手机是VERTICAL,我已经实现了这一切,使用GridLayoutManager 1列,如果用户的手机是HORIZONTAL,则列3列.

我遇到的问题是,似乎无法保存RecyclerView对方向更改的立场.我已经尝试过我可以找到的每一个选项,但没有一个看起来不起作用.我唯一可以想出的结论是,在旋转时,我正在销毁Firebase的ChildEventListener以避免内存泄漏,一旦方向完成,Firebase将重新查询数据库,因为新的ChildEventListener实例.

有没有什么办法可以节省我的RecyclerView的方向改变的立场?我不想要android:configChanges,因为它不会让我改变我的布局,我已经尝试保存为一个包裹,这是不成功的.我确定这是一件容易的东西,我失踪了,但嘿,我很开心.对我的代码的任何帮助或建议非常感谢.谢谢!

以下是我的课程,我只缩写为必需的代码.

主要活动

  1. public class MainActivity extends AppCompatActivity {
  2.  
  3. private RecyclerAdapter mRecyclerAdapter;
  4. private DatabaseReference mDatabaseReference;
  5. private RecyclerView mRecyclerView;
  6. private Query query;
  7.  
  8.  
  9. @Override
  10. protected void onCreate(Bundle savedInstanceState) {
  11. super.onCreate(savedInstanceState);
  12.  
  13. PreferenceManager.setDefaultValues(this,R.xml.preferences,false);
  14. setContentView(R.layout.activity_main);
  15. getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
  16.  
  17. Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
  18. setSupportActionBar(toolbar);
  19.  
  20. final int columns = getResources().getInteger(R.integer.gallery_columns);
  21.  
  22. mDatabaseReference = FirebaseDatabase.getInstance().getReference();
  23. query = mDatabaseReference.child("apod").orderByChild("date");
  24.  
  25. mRecyclerView = (RecyclerView) findViewById(R.id.recycler_view);
  26. mRecyclerView.setHasFixedSize(true);
  27. mRecyclerView.setLayoutManager(new GridLayoutManager(this,columns));
  28.  
  29.  
  30. mRecyclerAdapter = new RecyclerAdapter(this,query);
  31. mRecyclerView.setAdapter(mRecyclerAdapter);
  32.  
  33.  
  34. }
  35.  
  36. @Override
  37. public void onDestroy() {
  38. mRecyclerAdapter.cleanupListener();
  39. }
  40.  
  41. }

RecyclerAdapter

  1. public class RecyclerAdapter extends RecyclerView.Adapter<RecyclerAdapter.ApodViewHolder> {
  2.  
  3. private final Context mContext;
  4. private final ChildEventListener mChildEventListener;
  5. private final Query mDatabaseReference;
  6. private final List<String> apodListIds = new ArrayList<>();
  7. private final List<Apod> apodList = new ArrayList<>();
  8.  
  9. public RecyclerAdapter(final Context context,Query ref) {
  10. mContext = context;
  11. mDatabaseReference = ref;
  12.  
  13.  
  14. ChildEventListener childEventListener = new ChildEventListener() {
  15.  
  16.  
  17. @Override
  18. public void onChildAdded(DataSnapshot dataSnapshot,String s) {
  19. int oldListSize = getItemCount();
  20. Apod apod = dataSnapshot.getValue(Apod.class);
  21.  
  22. //Add data and IDs to the list
  23. apodListIds.add(dataSnapshot.getKey());
  24. apodList.add(apod);
  25.  
  26. //Update the RecyclerView
  27. notifyItemInserted(oldListSize - getItemCount() - 1);
  28. }
  29.  
  30. @Override
  31. public void onChildChanged(DataSnapshot dataSnapshot,String s) {
  32.  
  33. }
  34.  
  35. @Override
  36. public void onChildRemoved(DataSnapshot dataSnapshot) {
  37. String apodKey = dataSnapshot.getKey();
  38. int apodIndex = apodListIds.indexOf(apodKey);
  39.  
  40. if (apodIndex > -1) {
  41.  
  42. // Remove data and IDs from the list
  43. apodListIds.remove(apodIndex);
  44. apodList.remove(apodIndex);
  45.  
  46. // Update the RecyclerView
  47. notifyDataSetChanged();
  48. }
  49. }
  50.  
  51. @Override
  52. public void onChildMoved(DataSnapshot dataSnapshot,String s) {
  53.  
  54. }
  55.  
  56. @Override
  57. public void onCancelled(DatabaseError databaseError) {
  58.  
  59. }
  60.  
  61. };
  62. ref.addChildEventListener(childEventListener);
  63. mChildEventListener = childEventListener;
  64.  
  65. }
  66.  
  67. @Override
  68. public int getItemCount() {
  69. return apodList.size();
  70. }
  71. public void cleanupListener() {
  72. if (mChildEventListener != null) {
  73. mDatabaseReference.removeEventListener(mChildEventListener);
  74. }
  75. }
  76.  
  77. }

解决方法

@H_301_28@ 当旋转活动再次被破坏并再次创建时,意味着所有的对象都被破坏并重新创建,并且再次重新绘制布局.

你想停止重新创建活动,你可以使用android:configChanges,但它是不好的做法,也不是正确的方式.

只有事情现在仍然存在,以在旋转之前保存回收者视图的位置,并在活动重新创建之后获取它.

//保存回收者的位置

  1. @Override
  2. public void onSaveInstanceState(Bundle savedInstanceState) {
  3. // Save UI state changes to the savedInstanceState.
  4. // This bundle will be passed to onCreate if the process is
  5. // killed and restarted.
  6. savedInstanceState.putInt("position",mRecyclerView.getAdapterPosition()); // get current recycle view position here.
  7. super.onSaveInstanceState(savedInstanceState);
  8. }

//恢复值

  1. @Override
  2. protected void onCreate(Bundle savedInstanceState) {
  3. super.onCreate(savedInstanceState);
  4.  
  5. PreferenceManager.setDefaultValues(this,query);
  6. mRecyclerView.setAdapter(mRecyclerAdapter);
  7. if(savedInstanceState != null){
  8. // scroll to existing position which exist before rotation.
  9. mRecyclerView.scrollToPosition(savedInstanceState.getInt("position"));
  10. }
  11.  
  12. }

希望这些帮助你.

猜你在找的Android相关文章