Java 返回地图时带有MapFragment黑屏的Android抽屉布局
我一直在试验android.support.v4.widget.DrawerLayout,其中有4个片段可供选择。地图最初加载时没有问题,但是当我打开抽屉并更改片段时,我无法返回地图。我刚得到一个黑屏。Logcat显示碎片被重新创建,但我什么也没得到。只是一个空白的黑屏。我可以毫无问题地在其他片段之间切换。我做错了什么?我的项目的最小API为14 我从Java 返回地图时带有MapFragment黑屏的Android抽屉布局,java,android,android-fragments,drawerlayout,mapfragment,Java,Android,Android Fragments,Drawerlayout,Mapfragment,我一直在试验android.support.v4.widget.DrawerLayout,其中有4个片段可供选择。地图最初加载时没有问题,但是当我打开抽屉并更改片段时,我无法返回地图。我刚得到一个黑屏。Logcat显示碎片被重新创建,但我什么也没得到。只是一个空白的黑屏。我可以毫无问题地在其他片段之间切换。我做错了什么?我的项目的最小API为14 我从MainActivity.java这里加载ExploreMap(一个片段): if (position == 0){
MainActivity.java
这里加载ExploreMap
(一个片段):
if (position == 0){
ExploreMap exMap = new ExploreMap();
exMap.setRetainInstance(true);
getFragmentManager().beginTransaction().replace(R.id.content_frame, exMap).commit();
}
在ExploreMap.java
中,我执行以下操作
public class ExploreMap extends Fragment implements OnInfoWindowClickListener, android.location.LocationListener, OnMapLongClickListener{
private LocationManager mLocManager;
private GoogleMap mMap;
private MapFragment mMapFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
FragmentManager fm = getActivity().getFragmentManager();
mMapFragment = (MapFragment) fm.findFragmentById(R.id.map);
if (mMapFragment == null) {
mMapFragment = MapFragment.newInstance();
fm.beginTransaction().replace(R.id.map, mMapFragment).commit();
}
if (savedInstanceState == null) {
// First incarnation of this activity.
mMapFragment.setRetainInstance(true);
}else {
// Reincarnated activity. The obtained map is the same map instance in the previous
// activity life cycle. There is no need to reinitialize it.
mMap = mMapFragment.getMap();
}
createMapIfNeeded();
return inflater.inflate(R.layout.explore_map_layout, container, false);
}
@Override
public void onResume() {
super.onResume();
//create the map
createMapIfNeeded();
}
private void createMapIfNeeded(){
if(mLocManager == null){
mLocManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
mLocManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES,
this);
}
//locmanager can return null if no last known locaiton is available.
location = mLocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if a map has not already been instantiated it'll return null
if(mMap == null){
//instantiate map
mMap = mMapFragment.getMap();
//check it has been instantiated
if(mMap != null){
mMap.setOnMapLongClickListener(this);
mMap.setOnInfoWindowClickListener(this);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.setMyLocationEnabled(true);
//Manipulate map here (add coordinates/polylines from trip etc etc.)
UiSettings setting = mMap.getUiSettings();
setting.setTiltGesturesEnabled(true);
setting.setRotateGesturesEnabled(true);
setting.setZoomControlsEnabled(true);
setting.setMyLocationButtonEnabled(true);
if(location != null){
CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15);
mMap.animateCamera(cu);
}
}
}
}
XML的特性如下
mainactivity_layout.xml
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<!-- As the main content view, the view below consumes the entire
space available using match_parent in both dimensions. -->
<FrameLayout
android:id="@+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<!-- android:layout_gravity="start" tells DrawerLayout to treat
this as a sliding drawer on the left side for left-to-right
languages and on the right side for right-to-left languages.
The drawer is given a fixed width in dp and extends the full height of
the container. A solid background is used for contrast
with the content view. -->
<ListView
android:id="@+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="@android:color/transparent"
android:dividerHeight="0dp"
android:background="#111"/>
</android.support.v4.widget.DrawerLayout>
我希望这对你有用:
在我的头撞了几天墙之后,我发现了问题,或者应该说是问题。tsp建议使用上面的库,这些库也可以使用,但是我想让它与Google提供的android.support.v4.widget.DrawerLayout一起使用 这个问题有两个方面
setRetainInstance(true)
,原始MapFragment实例保留在内存中。由于某些原因,我仍然不完全理解MapFragment的原始实例在返回到ExploreMap片段后不会重新出现。为了解决这个问题,我在最初创建MapFragment时为它分配了一个名为“mapfrag”的字符串标记,并将变量设置为public static
。接下来在活动中,抽屉代码将切换片段,我执行一个findFragmentByTag()
并测试其null
,如果它不为null,则删除MapFragmentGoogleMap
不断向我返回null,我根本无法配置地图
2) 我找到了这个帖子。它建议扩展您自己的MapFragment并实现一个接口,以便在创建MapFragment时发出通知,这在很大程度上保证了非空GoogleMap
真倒霉!!你有一个谷歌地图在谷歌抽屉布局。这是我的完整工作代码
MainActivity.java
if (position == 0){
exMap = new ExploreMap();
exMap.setRetainInstance(true);
getFragmentManager().beginTransaction().replace(R.id.content_frame, exMap).commit();
}
if(position == 1){
//remove map frag here instead of in explore map
Fragment f = getFragmentManager().findFragmentByTag("mapfrag");
if(f != null){
getFragmentManager().beginTransaction().remove(f).commit();
}
Ms fragment = new Ms();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit();
}
if(position == 2){
Fragment f = getFragmentManager().findFragmentByTag("mapfrag");
if(f != null){
getFragmentManager().beginTransaction().remove(f).commit();
}
Settings fragment = new Settings();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit();
}
if(position == 3){
Fragment f = getFragmentManager().findFragmentByTag("mapfrag");
if(f != null){
getFragmentManager().beginTransaction().remove(f).commit();
}
About fragment = new About();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment).commit();
}
在ExploreMap.java中
public class ExploreMap extends Fragment implements MyMapFragment.MapCallback, OnInfoWindowClickListener, android.location.LocationListener, OnMapLongClickListener{
private LocationManager mLocManager;
private GoogleMap mMap;
public static MyMapFragment mMapFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.explore_map_layout, container, false);
FragmentManager fm = getActivity().getFragmentManager();
mMapFragment = (MyMapFragment) fm.findFragmentById(R.id.map_framelayout);
if (mMapFragment == null) {
mMapFragment = new MyMapFragment();
mMapFragment.setRetainInstance(true);
mMapFragment.setMapCallback(this);
fm.beginTransaction().replace(R.id.map_framelayout, mMapFragment,"mapfrag").commit();
}
createMapIfNeeded();
return v;
}
@Override
public void onMapReady(GoogleMap map) {
createMapIfNeeded();
}
private void createMapIfNeeded(){
if(mLocManager == null){
mLocManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
mLocManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES,
this);
}
//locmanager can return null if no last known locaiton is available.
location = mLocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if a map has not already been instantiated it'll return null
if(mMap == null){
//instantiate map
mMap = mMapFragment.getMap();
//check it has been instantiated
if(mMap != null){
mMap.setOnMapLongClickListener(this);
mMap.setOnInfoWindowClickListener(this);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.setMyLocationEnabled(true);
//Manipulate map here (add coordinates/polylines from trip etc etc.)
UiSettings setting = mMap.getUiSettings();
setting.setTiltGesturesEnabled(true);
setting.setRotateGesturesEnabled(true);
setting.setZoomControlsEnabled(true);
setting.setMyLocationButtonEnabled(true);
if(location != null){
CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15);
mMap.animateCamera(cu);
}
}
}
}
public class MyMapFragment extends MapFragment{
private MapCallback callback;
public static interface MapCallback
{
public void onMapReady(GoogleMap map);
}
public void setMapCallback(MapCallback callback)
{
this.callback = callback;
}
@Override public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
if(callback != null) callback.onMapReady(getMap());
}
}
现在MyMapFragment.java
public class ExploreMap extends Fragment implements MyMapFragment.MapCallback, OnInfoWindowClickListener, android.location.LocationListener, OnMapLongClickListener{
private LocationManager mLocManager;
private GoogleMap mMap;
public static MyMapFragment mMapFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.explore_map_layout, container, false);
FragmentManager fm = getActivity().getFragmentManager();
mMapFragment = (MyMapFragment) fm.findFragmentById(R.id.map_framelayout);
if (mMapFragment == null) {
mMapFragment = new MyMapFragment();
mMapFragment.setRetainInstance(true);
mMapFragment.setMapCallback(this);
fm.beginTransaction().replace(R.id.map_framelayout, mMapFragment,"mapfrag").commit();
}
createMapIfNeeded();
return v;
}
@Override
public void onMapReady(GoogleMap map) {
createMapIfNeeded();
}
private void createMapIfNeeded(){
if(mLocManager == null){
mLocManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
mLocManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES,
this);
}
//locmanager can return null if no last known locaiton is available.
location = mLocManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if a map has not already been instantiated it'll return null
if(mMap == null){
//instantiate map
mMap = mMapFragment.getMap();
//check it has been instantiated
if(mMap != null){
mMap.setOnMapLongClickListener(this);
mMap.setOnInfoWindowClickListener(this);
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
mMap.setMyLocationEnabled(true);
//Manipulate map here (add coordinates/polylines from trip etc etc.)
UiSettings setting = mMap.getUiSettings();
setting.setTiltGesturesEnabled(true);
setting.setRotateGesturesEnabled(true);
setting.setZoomControlsEnabled(true);
setting.setMyLocationButtonEnabled(true);
if(location != null){
CameraUpdate cu = CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 15);
mMap.animateCamera(cu);
}
}
}
}
public class MyMapFragment extends MapFragment{
private MapCallback callback;
public static interface MapCallback
{
public void onMapReady(GoogleMap map);
}
public void setMapCallback(MapCallback callback)
{
this.callback = callback;
}
@Override public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
if(callback != null) callback.onMapReady(getMap());
}
}
干杯 在邮件线程上找到此问题的简易解决方法。这解决了我的问题。
使用相对布局并将此透明视图直接放置在上方
你的地图碎片。例如:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/transparent" />
</RelativeLayout>
感谢您的推荐,但是我不认为使用上述工具与使用谷歌提供的android.support.v4.widget.DrawerLayout有什么不同。功能是一样的,我想我会得到同样的结果。您是否成功地使用此库在抽屉中获取mapfragment?我正在努力编译示例应用程序。我已经导入了示例和依赖库,但是示例项目无法解析“R”。做了通常清洁的项目,但没有。我注意到有一个“./ABS”无法解析,但我不知道它位于何处,也不知道它是什么。有什么想法吗?