Как использовать карту google V2 внутри фрагмента?
У меня есть фрагмент, который является частью Viewpager, и я хочу использовать Google Map V2 внутри этого фрагмента. Это то, что я пробовал до сих пор,
В моем фрагменте
private SupportMapFragment map;
private GoogleMap mMapView;
@Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
map = (SupportMapFragment) fm.findFragmentById(R.id.map);
if (map == null) {
map = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map, map).commit();
}
}
@Override
public void onResume() {
super.onResume();
if (mMapView == null) {
mMapView = map.getMap();
Marker hamburg = mMapView.addMarker(new MarkerOptions().position(HAMBURG)
.title("Hamburg"));
Marker kiel = mMapView.addMarker(new MarkerOptions()
.position(KIEL)
.title("Kiel")
.snippet("Kiel is cool")
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.ic_launcher)));
mMapView.moveCamera(CameraUpdateFactory.newLatLngZoom(HAMBURG, 15));
// Zoom in, animating the camera.
mMapView.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
}
}
и в моем макете subfragment_info.xml, у меня есть
<fragment
android:id="@+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="300dp"
android:layout_alignParentLeft="true"
android:layout_below="@+id/tableLayout1" />
Теперь я вижу карту. Но маркеры не показываются. Я думаю, что моя карта mMapView Google имеет значение NULL. Пожалуйста, помогите мне решить эту проблему. Спасибо заранее.
Ответы
Ответ 1
Создайте фрейм для карты, в которую он будет добавлен в ваш макет xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map_container">
<!-- The map fragments will go here -->
</RelativeLayout>
Не включайте class= "com.google.android.gms.maps.SupportMapFragment" в xml
либо в вашем классе фрагмента, получите его вручную внутри onActivityCreated
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (fragment == null) {
fragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, fragment).commit();
}
/***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();
if (map == null) {
map = fragment.getMap();
map.addMarker(new MarkerOptions().position(new LatLng(0, 0)));
}
}
если вы, ребята, сталкиваетесь с какой-либо проблемой. Незаконное исключение штата. Просто напишите ниже код.
/* * Эта проблема отслеживается в (Ошибки Google) * http://code.google.com/p/gmaps-api-issues/issues/detail?id=5064 Добавлен * Код из-за незаконного исключения государства. При повторном нажатии на вкладке * * Кратковременное обходное решение, которое фиксировало это для меня, заключается в следующем: * onDetach() каждого фрагмента, который вы называете */
@Override
public void onDetach() {
super.onDetach();
try {
Field childFragmentManager = Fragment.class
.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
//Если вы хотите отобразить карту в действии, просто увеличивайте свою активность на //FragmentActivity, напишите код ниже
В onCreate
FragmentManager fm = getSupportFragmentManager();
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map_container);
if (fragment == null) {
fragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.map_container, fragment)
.commit();
}
В onResume
@Override
protected void onResume() {
super.onResume();
if (googleMap == null) {
initilizeMap();
}
}
private void initilizeMap() {
if (googleMap != null) {
googleMap = fragment.getMap();
googleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.getUiSettings().setCompassEnabled(true);
googleMap.getUiSettings().setRotateGesturesEnabled(true);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(latitude, longitude)).zoom(10).build();
googleMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
// create marker
MarkerOptions marker = new MarkerOptions().position(new LatLng(
latitude, longitude));
// ROSE color icon
marker.icon(BitmapDescriptorFactory
.defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
// adding marker
googleMap.addMarker(marker);
// check if map is created successfully or not
if (googleMap == null) {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
}
Дополнительная помощь может быть получена из этих ссылок
https://code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1
https://developers.google.com/maps/documentation/android/map
Ответ 2
Вы должны решить, создаете ли вы свой фрагмент в коде new SupportMapFragment()
или надуваете из xml class="com.google.android.gms.maps.SupportMapFragment"
.
На самом деле вы не можете иметь Fragment
в xml для другого Fragment
. Читайте о вложенных Fragment
s.
Вы можете следовать этому комментарию о том, как добавить вложенный SupportMapFragment
.
Ответ 3
У меня была более или менее та же проблема. У меня был навигационный ящик, и я хотел поместить карту в фрагмент.
Я следил за этой нитью (но это на испанском):
https://groups.google.com/forum/#!msg/desarrolladores-android/1cvqPm0EZZU/Q801Yvb2ntYJ
Ключ был (на мой взгляд) изменить файл layout.xml:
Вместо "фрагмента" внутри вашего "макета subfragment_info.xml" вам нужно будет изменить это:
<com.google.android.gms.maps.MapView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent" />`
Вот код внутри потока (вы можете его использовать и адаптировать):
https://groups.google.com/d/msg/desarrolladores-android/1cvqPm0EZZU/9srw_9feamUJ
Ответ 4
мой подход:
Bundle bundle = new Bundle();
bundle.putInt(MY_ID, id);
FragmentManager fm = getFragmentManager();
Fragment fragment = fm.findFragmentById(R.id.customer_details_fragment);
fragment = new SalesFragment();
fm.beginTransaction()
.add(R.id.customer_details_fragment, fragment)
.commit();
fragment.setArguments(bundle);
Ответ 5
Для MapFragment
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
В вашем классе фрагментов
map = ((MapFragment) getActivity().getFragmentManager()
.findFragmentById(R.id.map)).getMap();
map.addMarker(new MarkerOptions().position(
new LatLng(13.031902, 80.278823)).title("Marker Title"));
Для SupportMapFragment
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
В вашем классе фрагментов
map = ((SupportMapFragment) getActivity().getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
map.addMarker(new MarkerOptions().position(
new LatLng(13.031902, 80.278823)).title("Marker Title"));
Примечание. Отображение карты SupportMapFragment после того, как пользователь коснется карты.
Ответ 6
В ссылке ответьте:
"Проблема в том, что то, что вы пытаетесь сделать, не должно быть сделано. Вы не должны раздувать фрагменты внутри других фрагментов. Из документации для Android:
Примечание. Вы не можете надуть макет во фрагмент, если в этом макете есть a. Вложенные фрагменты поддерживаются только при динамическом добавлении фрагмента.
Пока вы можете выполнить задачу с представленными здесь хаками, я настоятельно рекомендую вам не делать этого. Невозможно убедиться, что эти хаки будут обрабатывать то, что делает каждая новая ОС Android, когда вы пытаетесь раздуть макет для фрагмента, содержащего другой фрагмент.
Единственный поддерживаемый Android способ добавления фрагмента к другому фрагменту - это транзакция из диспетчера дочерних фрагментов.
Для этой проблемы:
Дублировать идентификатор, тег null или родительский идентификатор с другим фрагментом для com.google.android.gms.maps.MapFragment
Для меня лучшим решением является @DeepakPanwar
Ответ 7
Для загрузки карты в фрагмент:
<fragment
android:id="@+id/fragmentMap1"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"/>
Для .java:
public class PathFragment extends Fragment {
View view;
GoogleMap mMap;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
view=inflater.inflate(R.layout.fragment_path,null);
setupMap();
return view;
}
private void setupMap()
{
if (mMap == null)
{
mMap = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.fragment_map1)).getMap();
mMap.getUiSettings().setZoomControlsEnabled(true);
}
mMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
getlocation();
}
});
}
public void getlocation()
{
try
{
/*Collect Source and destination latitude and longitude
* To draw Polyline
* */
LatLng src = new LatLng(Double.parseDouble(AppGlobal.WorkerHistory.getOrder_lat()),Double.parseDouble(AppGlobal.WorkerHistory.getOrder_lng()));
LatLng dest =new LatLng(Double.parseDouble(AppGlobal.WorkerHistory.getWorker_lat()),Double.parseDouble(AppGlobal.WorkerHistory.getWorker_lng()));
//Add Marker
mMap.addMarker(new MarkerOptions()
.position(src)
.title("Source")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.srcicon)));
mMap.addMarker(new MarkerOptions()
.position(dest)
.title("Destination")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.desticon)));
Polyline line = mMap.addPolyline(
new PolylineOptions().add(
new LatLng(src.latitude, src.longitude),
new LatLng(dest.latitude, dest.longitude)
).width(5).color(Color.RED).geodesic(true)
);
//set zoom level
LatLngBounds.Builder builder = new LatLngBounds.Builder();
builder.include(src);
builder.include(dest);
LatLngBounds bounds = builder.build();
int padding = 0; // offset from edges of the map in pixels
CameraUpdate cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
mMap.animateCamera(cu);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
Ответ 8
Вот как я это сделал
в макете:
<fragment
android:id="@+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight=".90"
class="com.google.android.gms.maps.SupportMapFragment"
/>
в коде:
public class GPS extends FragmentActivity {
@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (supportMap == null) {
// Try to obtain the map from the SupportMapFragment.
supportMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (supportMap != null) {
MarkerOptions mo = new MarkerOptions().position( new LatLng( latitude, longitude ) );
supportMap.addMarker( mo );
}
}
}
}
Мне очень понравилось, вам нужно только правильное сочетание вещей, убедитесь, что ваш класс расширяет FragmentActivity
Ответ 9
Если я заменил фрагмент, в котором находится фрагмент карты (в этом примере кода MyFragment) с другим фрагментом, а затем возвращается, я получаю исключение IllegalStateException
public class Home_Map extends Fragment {
GoogleMap googleMap;
FragmentManager myFragmentManager;
SupportMapFragment mySupportMapFragment;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// TODO Auto-generated method stub
View rootView = inflater.inflate(R.layout.fragment_home__map, container, false);
//googleMap.setMyLocationEnabled(true);
try {
// Loading map
initilizeMap();
googleMap.setMyLocationEnabled(true);
} catch (Exception e) {
e.printStackTrace();
}
return rootView;
}
private void initilizeMap() {
try
{
if (googleMap == null) {
myFragmentManager = getFragmentManager();
mySupportMapFragment = (SupportMapFragment)myFragmentManager.findFragmentById(R.id.map2);
googleMap = mySupportMapFragment.getMap();
if (googleMap == null) {
Toast.makeText(getActivity().getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
} catch (Exception e) { Toast.makeText(getActivity().getApplicationContext(), ""+e, 1).show();
// TODO: handle exception
}
}
@Override
public void onResume() {
super.onResume();
initilizeMap();
}
@Override
public void onDetach() {
// TODO Auto-generated method stub
super.onDetach();
try {
Field childFragmentManager = Fragment.class
.getDeclaredField("mChildFragmentManager");
childFragmentManager.setAccessible(true);
childFragmentManager.set(this, null);
} catch (NoSuchFieldException e) {
throw new RuntimeException(e);
} catch (IllegalAccessException e) {
throw new RuntimeException(e);
}
}
}