我正在开发一个使用v2的应用程序,MapFragment
我遇到了非常奇怪的行为.我已经创建了一个子类MapFragment
来处理一些自定义行为(处理Marker
s,调整菜单选项等),并在第一次加载它时所有工作都很漂亮.然后我将一个新片段嵌入到我的活动中,将自定义推MapFragment
到了后台上.然而,当我从后台堆栈返回地图时,事情变得奇怪; 平移地图变得极其迟钝(我们正在谈论~1 FPS),无论是手动拖动/缩放还是通过点击引脚引起的动画.而再如果我与溢出菜单的任何部分进行交互,即使只是打开它并再次解除它,滞后会立即清除.似乎没有别的东西可以解决它(没有关闭/重新打开应用程序); 与非溢出菜单项进行交互,导航抽屉没有任何帮助.我从来没有见过这样的东西,也找不到之前描述过类似问题的人.任何想法,建议和/或修复都将受到欢迎.
在被问到之前回答几个问题:
是的,我正在调用super
我覆盖的所有生命周期方法的版本(onCreate()
,onCreateView()
[我还返回超级返回的那个],以及onDestroyView()
).
据我所知,我正在清理地图.每次刷新引脚时,我都会调用remove()
它们,然后clean()
在地图上调用,我也会这样做onDestroyView()
.
最后,作为参考,这是添加新片段的代码:
getFragmentManager().beginTransaction().replace(R.id.main_content_container, new JoinGroupFragment()).addToBackStack(null).commit();
当我完成它时,我只是打电话给:
getFragmentManager().popBackStack();
编辑:我不确定它会有多大帮助,但这是习惯MapFragment
:
public class CustomMapFragment extends MapFragment { private static final String DIALOG_TAG = "CUSTOM_MAP_FRAGMENT_DIALOG"; private static final int DEFAULT_ZOOM = 14; private static final int MARKER_ZOOM = 15; private static final int DEFAULT_PADDING = 80; private static final int ORANGE_THRESHOLD_MINUTES = 7; private static final int BLUE_THRESHOLD_MINUTES = 20; public static final String KEY_GROUP_NAME = "GROUP_NAME"; public static final String KEY_GROUP_ID = "GROUP_ID"; private TextView mGroupNameOverlay; private GoogleMap mMap; private ArrayListmMarkers; private Marker mSelectedMarker; private ArrayList mAllGroups; private Group mCurrentGroup; private ArrayList mAllLocations; private boolean mMapReady; private String mUsername; private boolean mCenterOnUser; public CustomMapFragment() { } @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setHasOptionsMenu(true); mMarkers = new ArrayList<>(); mAllLocatiOns= new ArrayList<>(); SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity()); mUsername = prefs.getString(PreferenceUtils.KEY_USERNAME, null); mCenterOnUser= prefs.getBoolean(PreferenceUtils.KEY_CENTER_ON_ME, false); mSelectedMarker = null; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { ViewGroup view = (ViewGroup)super.onCreateView(inflater, container, savedInstanceState); if (view != null) { // View should never be null; MapFragments have a FrameLayout as their top level parent mGroupNameOverlay = (TextView)inflater.inflate(R.layout.group_name_overlay, view, false); view.addView(mGroupNameOverlay); } Bundle results = ((MainActivity)getActivity()).getFragmentResults(); if (results != null) { String name = results.getString(KEY_GROUP_NAME); String id = results.getString(KEY_GROUP_ID); if (!StringUtils.isNullOrEmpty(name) && !StringUtils.isNullOrEmpty(id)) { mCurrentGroup = new Group(name, id); mAllGroups.add(mCurrentGroup); } } if (mCurrentGroup != null) { updateGroupNameOverlay(mCurrentGroup.getGroupName()); } getMapAsync(new OnMapReadyCallback() { @Override public void onMapReady(GoogleMap googleMap) { mMap = googleMap; mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() { @Override public boolean onMarkerClick(Marker marker) { mSelectedMarker = marker; getActivity().invalidateOptionsMenu(); return false; } }); mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() { @Override public void onMapClick(LatLng latLng) { mSelectedMarker = null; getActivity().invalidateOptionsMenu(); } }); populateMap(true, false); } }); GetGroupsRequest request = new GetGroupsRequest(); request.setListener(new GetGroupsRequestListener()); RequestProcessor.getInstance(getActivity()).queueRequest(request); return view; } @Override public void onDestroyView() { mSelectedMarker = null; for (Marker marker : mMarkers) { marker.remove(); } mMarkers.clear(); mMap.clear(); mMap = null; mMapReady = false; super.onDestroyView(); } @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { if (mSelectedMarker == null) { inflater.inflate(R.menu.menu_map, menu); } else { inflater.inflate(R.menu.menu_marker, menu); } super.onCreateOptionsMenu(menu, inflater); } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.map_menu_refresh_pins: performLocationsRequest(false); return true; case R.id.map_menu_recenter_zoom: populateMap(true, true); return true; case R.id.map_menu_select_group: DialogFragment selectDialog = new DialogFragment() { @Override public Dialog onCreateDialog(Bundle savedInstanceState) { String[] groups = new String[mAllGroups.size()]; for (int i = 0; i 1) { LatLngBounds.Builder builder = new LatLngBounds.Builder(); for (Location location : mAllLocations) { mMarkers.add(addMarker(location)); if (mCenterOnUser) { if (location.getUsername().equals(mUsername)) { update = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), DEFAULT_ZOOM); } } else { builder.include(new LatLng(location.getLatitude(), location.getLongitude())); } } if (!mCenterOnUser) { update = CameraUpdateFactory.newLatLngBounds(builder.build(), DEFAULT_PADDING); } } if (update != null && zoom) { if (animate) { mMap.animateCamera(update); } else { mMap.moveCamera(update); } } } } private Marker addMarker(Location location) { String timestamp; long minutesOld = (new Date().getTime() - location.getLastReported()) / 60000; float hue = BitmapDescriptorFactory.HUE_RED; if (minutesOld <1) { timestamp = getString(R.string.map_timestamp_just_now); } else if (minutesOld <2) { timestamp = getString(R.string.map_timestamp_one_minute); } else { timestamp = getString(R.string.map_timestamp_n_minutes, minutesOld); if (minutesOld >= ORANGE_THRESHOLD_MINUTES) { hue = BitmapDescriptorFactory.HUE_ORANGE; } if (minutesOld >= BLUE_THRESHOLD_MINUTES) { hue = BitmapDescriptorFactory.HUE_BLUE; } } LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); return mMap.addMarker(new MarkerOptions() .position(latLng) .icon(BitmapDescriptorFactory.defaultMarker(hue)) .title(location.getUsername()) .snippet(timestamp)); } private class GetGroupsRequestListener extends RequestListener { public GetGroupsRequestListener() { super(getActivity()); } @Override protected void onRequestComplete(GetGroupsResponse response) { mAllGroups = response.getGroups(); if (mAllGroups.size() > 0) { if (mCurrentGroup == null) { mCurrentGroup = mAllGroups.get(0); updateGroupNameOverlay(mCurrentGroup.getGroupName()); } performLocationsRequest(true); } } } private class GetLocationsRequestListener extends RequestListener { private boolean mmAutoZoom; public GetLocationsRequestListener(boolean autoZoom) { super(getActivity()); mmAutoZoom = autoZoom; } @Override protected void onRequestComplete(GetLocationsResponse response) { mAllLocatiOns= response.getLocations(); getActivity().runOnUiThread(new Runnable() { @Override public void run() { populateMap(mmAutoZoom, false); } }); } } }
PS我意识到这可能不是最好的做法来劫持视图创建并以这种方式注入我自己的叠加层,但是为了它的价值,我尝试将该部分评论出去并且它没有解决问题,所以我是怀疑它是否相关.