我正在开发一个简单的APOD应用程序,它实现:
> RecyclerView
> CardView
> Firebase
毕加索
该应用程序从Firebase和Firebase Storage中抓取图像和文本,将它们显示在CardView中,并将OnClickListener设置为每个视图.当用户点击图像时,我通过意图打开一个新的活动.第二个活动显示原始点击的图像,以及更多关于它的信息.
如果用户的手机是VERTICAL,我已经实现了这一切,使用GridLayoutManager 1列,如果用户的手机是HORIZONTAL,则列3列.
我遇到的问题是,似乎无法保存RecyclerView对方向更改的立场.我已经尝试过我可以找到的每一个选项,但没有一个看起来不起作用.我唯一可以想出的结论是,在旋转时,我正在销毁Firebase的ChildEventListener以避免内存泄漏,一旦方向完成,Firebase将重新查询数据库,因为新的ChildEventListener实例.
有没有什么办法可以节省我的RecyclerView的方向改变的立场?我不想要android:configChanges,因为它不会让我改变我的布局,我已经尝试保存为一个包裹,这是不成功的.我确定这是一件容易的东西,我失踪了,但嘿,我很开心.对我的代码的任何帮助或建议非常感谢.谢谢!
以下是我的课程,我只缩写为必需的代码.
主要活动
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); } } }
解决方法
当旋转活动再次被破坏并再次创建时,意味着所有的对象都被破坏并重新创建,并且再次重新绘制布局.
你想停止重新创建活动,你可以使用android:configChanges,但它是不好的做法,也不是正确的方式.
只有事情现在仍然存在,以在旋转之前保存回收者视图的位置,并在活动重新创建之后获取它.
//保存回收者的位置
@Override public void onSaveInstanceState(Bundle savedInstanceState) { // Save UI state changes to the savedInstanceState. // This bundle will be passed to onCreate if the process is // killed and restarted. savedInstanceState.putInt("position",mRecyclerView.getAdapterPosition()); // get current recycle view position here. super.onSaveInstanceState(savedInstanceState); }
//恢复值
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); PreferenceManager.setDefaultValues(this,query); mRecyclerView.setAdapter(mRecyclerAdapter); if(savedInstanceState != null){ // scroll to existing position which exist before rotation. mRecyclerView.scrollToPosition(savedInstanceState.getInt("position")); } }
希望这些帮助你.