我正在开发一个简单的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);
- }
- }
- }
解决方法
@H_301_28@ 当旋转活动再次被破坏并再次创建时,意味着所有的对象都被破坏并重新创建,并且再次重新绘制布局.你想停止重新创建活动,你可以使用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"));
- }
- }
希望这些帮助你.