我有一个MapView控件,我试图在ViewPager中加载。 ViewPager加载了布局视图,而不是片段,因为ViewPager本身位于片段中,我想避免片段场景中的片段。
这是ViewPager的适配器,它将地图加载为第4个屏幕:
public class AmbientPagerAdapter : PagerAdapter {
private ViewPagerWithMap pager;
private CurrentLocationStatistics ambientData;
private AmbientSearchBuilder searchBuilder;
private AmbientSearchIndicatorBuilder searchIndicatorBuilder;
private AmbientIndicatorBuilder indicatorBuilder;
private AmbientMapBuilder mapBuilder;
private Bundle savedInstanceState;
public AmbientPagerAdapter(View view, CurrentLocationStatistics ambientData, Bundle savedInstanceState) {
this.pager = view.FindViewById<ViewPagerWithMap> (Resource.Id.ambient_pager);
this.ambientData = ambientData;
this.savedInstanceState = savedInstanceState;
SetupEvents ();
}
private void SetupEvents () {
pager.Touch += (object sender, View.TouchEventArgs e) => {
pager.Parent.RequestDisallowInterceptTouchEvent(true);
e.Handled = false;
};
}
#region Setup Views
public override Java.Lang.Object InstantiateItem(View collection, int position) {
var layoutInflater = (LayoutInflater)ApplicationContext.Activity.GetSystemService (Context.LayoutInflaterService);
View view = null;
switch (position) {
case 0:
view = layoutInflater.Inflate (Resource.Layout.AmbientSearch, null);
searchBuilder = new AmbientSearchBuilder (view, ambientData);
break;
case 1:
view = layoutInflater.Inflate (Resource.Layout.AmbientSearchIndicators, null);
searchIndicatorBuilder = new AmbientSearchIndicatorBuilder (view, ambientData);
break;
case 2:
view = layoutInflater.Inflate (Resource.Layout.AmbientIndicators, null);
indicatorBuilder = new AmbientIndicatorBuilder (view, ambientData);
break;
case 3:
view = layoutInflater.Inflate (Resource.Layout.AmbientMap, null);
mapBuilder = new AmbientMapBuilder (view, ambientData, savedInstanceState);
break;
}
// Add view to pager
var viewPager = collection.JavaCast<ViewPager>();
viewPager.AddView(view);
return view;
}
public void Update (CurrentLocationStatistics ambientData) {
this.ambientData = ambientData;
if (searchBuilder != null) {
searchBuilder.Update (ambientData);
}
if (searchIndicatorBuilder != null) {
searchIndicatorBuilder.Update (ambientData);
}
if (indicatorBuilder != null) {
indicatorBuilder.Update (ambientData);
}
if (mapBuilder != null) {
mapBuilder.Update (ambientData);
}
}
#endregion
#region Infrastructure
public override void DestroyItem(View collection, int position, Java.Lang.Object view) {
var viewPager = collection.JavaCast<ViewPager>();
viewPager.RemoveView (view as View);
if (position == 3 && mapBuilder != null) {
mapBuilder.OnDestroy ();
}
}
public override bool IsViewFromObject(View view, Java.Lang.Object obj) {
return view == obj;
}
public override IParcelable SaveState() {
return null;
}
public override void StartUpdate(View arg0) {
}
public override void FinishUpdate(View arg0) {
}
public void UpdateVisibleItem (int index) {
pager.SetCurrentItem (index, false);
}
public override int Count {
get {
return 4;
}
}
#endregion
public AmbientSearchBuilder SearchBuilder { get { return searchBuilder; } }
public AmbientMapBuilder MapBuilder { get { return mapBuilder; } }
}
一旦用户滑动到第3个屏幕,它就会实例化地图,因为ViewPager需要加载下一个屏幕,以便在滑过时可以同时显示两者(默认的ViewPager行为)。这可能是问题的一部分,当它还没有在视野中时加载地图?
下面是设置MapView的类。生命周期事件由托管ViewPager的片段调用。
public class AmbientMapBuilder : AmbientBuilderBase {
private View view;
private TouchMapView mapView;
private PropertyMapAdapter adapter;
private Geolocation initialLocation;
private CameraPosition lastCamera;
private TinyMessageSubscriptionToken filterToken;
public AmbientMapBuilder(View view, CurrentLocationStatistics ambientData, Bundle savedInstanceState = null) : base(ambientData) {
this.view = view;
this.mapView = view.FindViewById<TouchMapView> (Resource.Id.map);
mapView.OnCreate (savedInstanceState);
//MapsInitializer.Initialize (ApplicationContext.Activity);
}
public void Update (CurrentLocationStatistics ambientData) {
this.ambientData = ambientData;
}
#region Lifecycle Events
public void OnResume () {
if (mapView != null)
mapView.OnResume ();
if (lastCamera != null) {
if (adapter != null)
adapter.MoveMapToPosition (lastCamera);
lastCamera = null;
}
}
public void OnPause () {
mapView.OnPause ();
lastCamera = mapView.Map.CameraPosition;
if (filterToken != null) {
filterToken.Dispose ();
filterToken = null;
}
}
public void OnSaveInstanceState (Bundle outState) {
var map = mapView;
if (map != null)
map.OnSaveInstanceState (outState);
}
public void OnLowMemory () {
if (mapView != null) {
mapView.OnLowMemory ();
}
}
public void OnDestroy () {
if (mapView != null) {
mapView.OnDestroy ();
}
}
#endregion
public bool MapIsLoaded { get; set; }
public PropertyMapAdapter MapAdapter {
get { return adapter; }
}
public View View {
get { return view; }
}
public TouchMapView MapView {
get { return mapView; }
}
}
最后,这是地图的布局xml:
<RPR.Mobile.Droid.Widget.TouchMapView xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/map"
map:cameraTargetLat="37.09024"
map:cameraTargetLng="-95.712891"
map:cameraZoom="3"
map:uiCompass="false"
map:uiRotateGestures="false"
map:uiScrollGestures="true"
map:uiTiltGestures="false"
map:uiZoomGestures="true"
map:uiZoomControls="false"
android:layout_width="match_parent"
android:layout_height="match_parent" />
下面是地图的样子,它只显示网格线和灰色背景但没有地图,地图无法与之互动。
任何想法是什么问题?
答案 0 :(得分:4)
此问题的产生是由于片段的生命周期与ViewPager中mapView的实例化不对齐,特别是在mapView设置之前调用了fragment.OnResume方法,因此从未调用过mapView.OnResume()。我需要在mapView.OnCreate()之后手动调用mapView.OnResume()然后一切都工作得很好。