我有一个使用actionbarsherlock和谷歌地图的应用程序。我在应用程序中有3个主要选项卡,当您导航两个选项卡时,第一个选项卡将被销毁。我将setOffscreenPageLimit()设置为2,但我想正确解决此问题,有时当用户返回到地图视图时,地图为空且无响应。我将片段保存在我的操作栏活动中的一个数组中,以防止它们被破坏,这曾经与之前版本的google play一起使用,但是在迁移到7.0.0时我不得不重构我的代码。我对片段缺乏经验,所以问题可能就在那里,尽管地图的缩放和位置都是保持不变的(选项,标记等等)。
我的代码如下:
修改
当我回来时,地图会保存我的缩放和我正在寻找的位置,但是听众和标记都消失了。任何使用地图的任务都不再连接
// ActionBarActivity.java
public class ActionBarActivity extends SherlockFragmentActivity implements TabListener, OnPageChangeListener {
ViewPager mViewPager;
String pageString = "map_view";
// Holder for the fragments used
List<SherlockFragment> frags;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_action_bar);
mViewPager = (ViewPager) findViewById(R.id.pager);
// *** I would like for the code to work WITHOUT the following line ***
mViewPager.setOffscreenPageLimit(2);
mViewPager.setAdapter(new MyPagerAdapter(this, getSupportFragmentManager()));
// Get Actionbar
ActionBar bar = getSupportActionBar();
// Get tabs
ActionBar.Tab mapTab = bar.newTab()
.setIcon(R.drawable.ic_action_map)
.setTabListener(this)
.setTag("map");
ActionBar.Tab listTab = bar.newTab()
.setIcon(R.drawable.ic_action_view_as_list)
.setTabListener(this)
.setTag("list");
// Get tabs
ActionBar.Tab photoFeedTab = bar.newTab()
.setIcon(R.drawable.ic_action_camera)
.setTabListener(this)
.setTag("photo");
bar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS);
bar.addTab(mapTab);
bar.addTab(listTab);
bar.addTab(photoFeedTab);
frags = Arrays.asList(null, null, null);
}
@Override
protected void onResume() {
super.onResume();
mViewPager.setOnPageChangeListener(this);
}
@Override
protected void onPause() {
super.onPause();
mViewPager.setOnPageChangeListener(null);
}
private class MyPagerAdapter extends FragmentStatePagerAdapter {
private final String[] mPageTitles;
public MyPagerAdapter(Context context, FragmentManager fm) {
super(fm);
mPageTitles = context.getResources().getStringArray(R.array.pageTitle);
}
@Override
public CharSequence getPageTitle(int position) {
return mPageTitles[position];
}
@Override
public int getCount() {
return mPageTitles.length;
}
@Override
public Fragment getItem(int position) {
Fragment f = null;
switch (position) {
case 0:
pageString = "map_view";
if(frags.get(0) == null) {
ViewMap vm = new ViewMap();
vm.setRetainInstance(true);
frags.set(0, vm);
}
f = frags.get(0);
// pass through the bundle holding lat/long
// to move the camera (if present)
Bundle showData = getIntent().getExtras();
if (showData != null) {
f.setArguments(showData);
}
break;
case 1:
pageString = "list_view";
if(frags.get(1) == null) {
frags.set(1, new ListViewHubba());
}
f = frags.get(1);
break;
case 2:
pageString = "Photo_feed";
if(frags.get(2) == null) {
frags.set(2, new PhotoFeedList());
}
f = frags.get(2);
break;
}
return f;
}
}
public void onPageScrollStateChanged(int arg0) {
}
public void onPageScrolled(int arg0, float arg1, int arg2) {
}
public void onPageSelected(int position) {
position = position % getSupportActionBar().getNavigationItemCount();
getSupportActionBar().setSelectedNavigationItem(position);
}
public void onTabSelected(Tab tab, FragmentTransaction ft) {
mViewPager.setCurrentItem(tab.getPosition());
}
public void onTabUnselected(Tab tab, FragmentTransaction ft) {
}
public void onTabReselected(Tab tab, FragmentTransaction ft) {
}
}
// ViewMap.java
public class ViewMap extends SherlockFragment {
public GoogleMap mMap;
private View rootView = null;
Context context;
private View v;
ProgressDialog progressDialog;
boolean fetched = false;
SupportMapFragment fragment;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
fragment = getMapFragment();
if (fragment == null) {
Log.i("DEBUG", "Fragment was null.");
fragment = SupportMapFragment.newInstance();
fragment.setRetainInstance(true);
fm.beginTransaction().replace(R.id.map_container, fragment).commit();
} else {
Log.i("DEBUG", "Fragment was Not null.");
}
/**
* at this time google play services are not initialize so get map
* and add what ever you want to it in onResume() or onStart()
*/
}
@Override
public void onResume() {
super.onResume();
setupMapIfNeeded();
}
public View onCreateView(final LayoutInflater inflater,
final ViewGroup container, Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
context = getActivity().getApplicationContext();
if(rootView == null) {
rootView = inflater.inflate(R.layout.view_map_activity, container,
false);
} else {
Log.i("DEBUG", "Non null root view.");
}
return rootView;
}
public void setupMapIfNeeded() {
if (mMap == null) {
mMap = fragment.getMap();
fetched = false;
}
// Check if we were successful in obtaining the map.
// and only reload it if we haven't already fetched
if (mMap != null && !fetched) {
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
isHybrid = false;
mMap.setMyLocationEnabled(true);
// Check if current location is available, otherwise default to riley
LocationManager lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
Location location = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
LatLng Center;
if (location != null) {
// Get current location info
Center = new LatLng(location.getLatitude(), location.getLongitude());
} else {
// default to riley
Center = new LatLng(42.4409010, -83.3978000);
}
// set camera position
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(Center)
.zoom(CAMERA_ZOOM)
.bearing(0)
.tilt(30)
.build();
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
/**
* Show loading message if first time fetching.
*/
progressDialog = ProgressDialog.show(getActivity(), "",
"Fetching spots...", true);
Spot.getAllSpots(mMap, getActivity().getApplicationContext(), progressDialog);
fetched = true;
//... custom map options here ...
}
}
private SupportMapFragment getMapFragment() {
FragmentManager fm = null;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Log.i("DEBUG", "using getFragmentManager");
fm = getFragmentManager();
} else {
Log.i("DEBUG", "using getChildFragmentManager");
fm = getChildFragmentManager();
}
return (SupportMapFragment) fm.findFragmentById(R.id.map_container);
}
}
// view_map_activity.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map_view_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#000">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map_container">
<!-- The map fragment will go here -->
</RelativeLayout>
</RelativeLayout>
我没有收到任何错误/崩溃但是当我从最右边的选项卡返回到地图视图时,我的缩放和位置仍然存在,但所有标记都消失了。当片段被导航回来时,我有一个解决方法可以将它们添加回来 - 但由于我有很多标记,所以它太慢了。
有没有人知道如何保持嵌套的子supportmapfragment?我已经在这方面工作了很长时间,并且可以真正使用一些帮助......
答案 0 :(得分:1)
你可以使用:
setRetainInstance(true);
在onCreate()方法中,要求supportmapfragment在回收地图时保留点等。无论如何,这可能需要时间来保存和恢复数千个标记,而你没有其他选择,大数据是大数据:D
编辑:无论如何,你似乎已经保留了实例......这有用吗?
<强> EDIT2:强> 查看地图演示,有一个“MapRetain”在我的设备上运行。也许您对片段的所有触摸和“SupportMapFragment.newInstance()”会破坏所有内容......
/**
* This shows how to retain a map across activity restarts (e.g., from screen rotations), which can
* be faster than relying on state serialization.
*/
public class RetainMapDemoActivity extends FragmentActivity implements OnMapReadyCallback {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.basic_demo);
SupportMapFragment mapFragment =
(SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
if (savedInstanceState == null) {
// First incarnation of this activity.
mapFragment.setRetainInstance(true);
}
mapFragment.getMapAsync(this);
}
@Override
public void onMapReady(GoogleMap map) {
map.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}