可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have a Android.Support.V4.Fragment
that contains both a MapView
and a RecyclerView
. These are separate views in the Fragment
.
The app crashes when the device is rotated:
Android.OS.BadParcelableException: ClassNotFoundException when unmarshalling: android.support.v7.widget.RecyclerView$SavedState
I am passing the lifecycle methods to the MapView as required by the docs:
private MapView mapView; private RecyclerView myRecyclerView; private RecyclerView.LayoutManager myLayoutManager; public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { base.OnCreateView(inflater, container, savedInstanceState); myRecyclerView = myRootView.FindViewById<RecyclerView>(Resource.Id.myRecyclerView); myLayoutManager = new LinearLayoutManager(activity, LinearLayoutManager.Horizontal, false); myRecyclerView.SetLayoutManager(myLayoutManager); myRecyclerAdapter = ... myRecyclerView.SetAdapter(myRecyclerAdapter); mapView.OnCreate(savedInstanceState); } public override void OnSaveInstanceState(Bundle outState) { ... if (mapView != null) mapView.OnSaveInstanceState(outState); base.OnSaveInstanceState(outState); }
If I remove the RecyclerView
form the AXML it rotates correctly, if I include it the app crashes at mapView.OnCreate(savedInstanceState)
why is this?
回答1:
For anyone that searches and has the same problem. This is the solution, It would appear to be a 2yr old bug.
I was able to get around it by saving the MapView's saved state on a separate Bundle and then adding it to the outgoing saved state bundle. Then in onCreate()
, I would just grab the MapView's saved state from the incoming one and pass it into its onCreate()
method, thus stopping the crashes.
In my case I implemented as so:
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { base.OnCreateView(inflater, container, savedInstanceState); myRecyclerView = myRootView.FindViewById<RecyclerView>(Resource.Id.myRecyclerView); myLayoutManager = new LinearLayoutManager(activity, LinearLayoutManager.Horizontal, false); myRecyclerView.SetLayoutManager(myLayoutManager); myRecyclerAdapter = ... myRecyclerView.SetAdapter(myRecyclerAdapter); Bundle mapViewSavedInstanceState = savedInstanceState != null ? savedInstanceState.GetBundle("mapViewSaveState") : null; mapView.OnCreate(mapViewSavedInstanceState); } public override void OnSaveInstanceState(Bundle outState) { if (mapView != null) { Bundle mapViewSaveState = new Bundle(outState); outState.PutBundle("mapViewSaveState", mapViewSaveState); mapView.OnSaveInstanceState(outState); } base.OnSaveInstanceState(outState); }
回答2:
Tallpaul's answer didn't work for me. The solution that he linked was working good though.
public class FragmentMain extends Fragment { private Bundle savedInstanceState; @Override public void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); ... this.savedInstanceState = savedInstanceState; } @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { containerView = inflater.inflate(R.layout.fragment_main, container, false); //mapView bug https://code.google.com/p/gmaps-api-issues/issues/detail?id=6237#c9 final Bundle mapViewSavedInstanceState = savedInstanceState != null ? savedInstanceState.getBundle("mapViewSaveState") : null; vmGoogleMap.create( mapViewSavedInstanceState ; return containerView; } @Override public void onSaveInstanceState(Bundle outState) { //mapView bug https://code.google.com/p/gmaps-api-issues/issues/detail?id=6237#c9 final Bundle mapViewSaveState = new Bundle(outState); vmGoogleMap.onSaveInstanceState(mapViewSaveState); outState.putBundle("mapViewSaveState", mapViewSaveState); super.onSaveInstanceState(outState); } }