我正在开发一个简单的APOD应用程序,它可以实现:
RecyclerView
CardView
Firebase
Picasso
该应用程序从中抓取图像和文本,Firebase
并将其Firebase Storage
显示在a中CardView
,并OnClickListener
为每个设置View
.当用户点击图片时,我打开一个新Activity
的Intent
.第二个Activity
显示原始单击的图像,以及有关它的更多信息.
GridLayoutManager
如果用户的手机是VERTICAL,我已经使用1列实现了这一切,如果用户的手机是HORIZONTAL则使用3列.
我遇到的问题是我似乎无法挽救RecyclerView
方向改变的立场.我已经尝试了我能找到的每一个选项,但似乎都没有.唯一的结论,我可以想出,是在旋转,我毁坏Firebase
的ChildEventListener
,以避免内存泄漏,一旦定位完成后,Firebase
再查询,因为新实例的数据库ChildEventListener
.
有什么方法可以挽救我RecyclerView
对方向改变的立场吗?我不想要,android:configChanges
因为它不会让我改变我的布局,我已经尝试过保存为一个Parcelable
,这是不成功的.我确信这很容易让我失踪,但是,嘿,我是新手.我非常感谢您对我的代码的任何帮助或建议.谢谢!
下面是我的课程,我只简化了必要的代码.
主要活动
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{ private final Context mContext; private final ChildEventListener mChildEventListener; private final Query mDatabaseReference; private final List apodListIds = new ArrayList<>(); private final List 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); } } }
jitsm555.. 7
旋转活动被破坏并再次重新创建,这意味着所有对象都被销毁并重新创建,并且布局也会重新绘制.
你想停止重新创建你可以使用android:configChanges的活动,但这是不好的做法,也不是正确的方法.
现在唯一剩下的就是在轮换之前保存recyclerview的位置,并在重新创建活动之后获取它.
//保存recyclerview的位置
@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, 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); if(savedInstanceState != null){ // scroll to existing position which exist before rotation. mRecyclerView.scrollToPosition(savedInstanceState.getInt("position")); } }
希望这些能帮到你.
旋转活动被破坏并再次重新创建,这意味着所有对象都被销毁并重新创建,并且布局也会重新绘制.
你想停止重新创建你可以使用android:configChanges的活动,但这是不好的做法,也不是正确的方法.
现在唯一剩下的就是在轮换之前保存recyclerview的位置,并在重新创建活动之后获取它.
//保存recyclerview的位置
@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, 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); if(savedInstanceState != null){ // scroll to existing position which exist before rotation. mRecyclerView.scrollToPosition(savedInstanceState.getInt("position")); } }
希望这些能帮到你.