加载由ViewPager管理的Android Google地图片段

时间:2015-04-30 20:09:52

标签: android google-maps android-fragments fragmentpageradapter

我可以将Google地图加载到活动中的Android片段中。这一直很好。

但现在我想使用ViewPager在视图之间导航(类 android.support.v4.app.Fragment )。似乎无法将 com.google.android.gms.maps.MapFragment 加载到此类片段中。

例如,在:

SoleMap.java

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.LatLng;

public class SoleMap extends Fragment implements OnMapReadyCallback {

    MapFragment gMapFragment;
    GoogleMap gMap = null;

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.sole_map, container, false);

        gMapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.soleViewMap);
        gMapFragment.getMapAsync(this);

        return view;
    }

    @Override
    public void onMapReady(GoogleMap map) {
        gMap = map;
        gMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
        gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new
                LatLng(49.39,-124.83), 20));
    }

}

声明

getFragmentManager().findFragmentById(R.id.holeViewMap);

导致编译器错误(不兼容的类型)。

我尝试使用SupportMapFragment,这消除了编译器错误,但是当我运行应用程序时,它立即退出并显示消息“I / O错误:连接被拒绝”。 Google文档似乎表明您需要一个特殊的“For Work”帐户才能使用支持库。那是对的吗?如果是这样,我想我运气不好。

我能看到的另一种方法是使用活动而不是片段来托管我的观点,即摆脱 ViewPager

有什么建议吗?

5 个答案:

答案 0 :(得分:14)

在你的sole_map.xml中你必须添加一个MapView,让我们这样说:

<?xml version="1.0" encoding="utf-8"?>
<com.google.android.gms.maps.MapView
    android:id="@+id/soleViewMap"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

然后从ID为view.findViewById(R.id.soleViewMap);的SoleMap片段中获取它。这将返回一个MapView,然后你可以做你现在正在做的事情。看起来应该是这样的:

public class SoleMap extends Fragment implements OnMapReadyCallback {

  MapView gMapView;
  GoogleMap gMap = null;

  @Override
  public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.sole_map, container, false);

    gMapView = (MapView) view.findViewById(R.id.soleViewMap);
    gMapView.getMapAsync(this);

    return view;
  }

  @Override
  public void onMapReady(GoogleMap map) {
    gMap = map;
    gMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
    gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new
            LatLng(49.39,-124.83), 20));
  }
}

不要忘记将mapview与调用事件onCreateonLowMemoryonPauseonResumeonDestroy的片段生命周期相关联(不希望如此)错过任何一个),并呼叫MapsInitializer.initialize(getContext());

答案 1 :(得分:8)

接受的答案是一个很好的起点但是如果我们尝试使用它会失败,它不会描述完整的解决方案。包含地图的完整工作片段,可在ViewPagerTabs中使用(通知在片段生命周期中使用地图):

public class AttractionMapTabFragment extends AttractionTab implements OnMapReadyCallback {

private ScrollMapView gMapView;
private GoogleMap gMap;


@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    View view = inflater.inflate(R.layout.fragment_map, null);

    gMapView = (ScrollMapView) view.findViewById(R.id.map);
    gMapView.getMapAsync(this);

    //most important use onCreate;
    gMapView.onCreate(getArguments());
    return view;

}

@Override
public void onMapReady(GoogleMap googleMap) {
    gMap = googleMap;
    gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new
            LatLng(51.3623329,21.7719342), 8));
}

@Override
public void onResume() {
    super.onResume();

    if (gMapView != null)
        gMapView.onResume();
}


@Override
public void onDestroy() {
    super.onDestroy();

    if (gMapView != null)
        gMapView.onDestroy();
}

@Override
public void onStart() {
    super.onStart();

    if (gMapView != null)
        gMapView.onStart();
}

@Override
public void onStop() {
    super.onStop();

    if (gMapView != null)
        gMapView.onStop();

}

@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);

    if (gMapView != null)
        gMapView.onSaveInstanceState(outState);
}
}

自定义MapView类 - 如果我们使用ScrollView作为父级,则需要它。它可以移动地图。如果您未在此屏幕中使用ScrollView,则标准{{1可以使用。

MapView

最后一件事是布局 - public class ScrollMapView extends MapView { public ScrollMapView(Context context, AttributeSet attributeSet) { super(context, attributeSet); } @Override public boolean dispatchTouchEvent(MotionEvent ev) { /** * Request all parents to relinquish the touch events */ getParent().requestDisallowInterceptTouchEvent(true); return super.dispatchTouchEvent(ev); } }

R.layout.fragment_map

答案 2 :(得分:2)

public class MapViewFragment extends Fragment implements OnMapReadyCallback{

private GoogleMap mMap;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    // Inflate the layout for this fragment
    return inflater.inflate(R.layout.activity_maps, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    //FragmentManager fragment = getActivity().getSupportFragmentManager();
   // Fragment fragment=(Fragment) getChildFragmentManager().findFragmentById(R.id.mapView);
    final SupportMapFragment myMAPF = (SupportMapFragment)getChildFragmentManager().findFragmentById(R.id.map);
    myMAPF.getMapAsync(this);

}

@Override
public void onMapReady(GoogleMap googleMap) {
   mMap = googleMap;

    // Add a marker in Sydney and move the camera
    LatLng sydney = new LatLng(25.412383, 55.508085);
    mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}

答案 3 :(得分:0)

将此代码写入activity_maps.xml

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />

答案 4 :(得分:0)

我被这个问题困扰了好几天。最后,我使它像这样工作:

sole_map.xml

<fragment xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".SoleMap"
    android:id="@+id/soleViewMap"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    map:mapType="terrain" />

SoleMap.java

不是在“ onCreateView”中执行操作,而是在“ onViewCreated”中执行操作,而不是使用MapFragment,而是使用SupportMapFragment并使用getChildFragmentManager而不是getFragmentManager,如下所示:

public class MapaFragment extends Fragment implements OnMapReadyCallback {

GoogleMap mapa_sole;

public View onCreateView(@NonNull LayoutInflater inflater,
                         ViewGroup container, Bundle savedInstanceState) {
    return inflater.inflate(R.layout.sole_map, container, false);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    final SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.soleViewMap);
    mapFragment.getMapAsync(this);

}

@Override
public void onMapReady(GoogleMap googleMap) {
    mapa_sole = googleMap;


    // TODO....

}

}(这应该在上面的代码中,不知道为什么不把它放在那里)

希望这项帮助!