MapFragment, GoogleMap .getMap() - java

I am having a lot of trouble getting .getMap() to work when trying to create a GoogleMap object (it is returning null), I have looked around and seen people had similar issues but wasn't able to find any help from any of them. In it's current implementation how can I find the MapFragment & create a GoogleMap from it?
protected void setFragment(){
FragmentManager fm = getFragmentManager();
MapFragment mapFragment = MapFragment.newInstance();
fm.beginTransaction().replace(R.id.fragment_container, mapFragment).commit();
try{
GoogleMap gMap = ((MapFragment)fm.findFragmentById(R.id.fragment_container)).getMap();
gMap.setBuildingsEnabled(true);
}catch(Exception e){ }
}
The portion of XML containing fragment_container
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:id="#+id/selectionLayout">
<RelativeLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="85dp">
</RelativeLayout>
</RelativeLayout>

Allow the Map to load before you start using otherwise you'll get null. You have the onReady callback when the map is ready for use.
protected void setFragment(){
FragmentManager fm = getFragmentManager();
MapFragment mapFragment = MapFragment.newInstance();
fm.beginTransaction().replace(R.id.fragment_container, mapFragment).commit();
try{
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap map) {
//your map related actions.
}
});
}
catch(Exception e) {
e.printStackTrace();
}
}

You actually need to include a fragment (NOT the Relative Layout) to your layout like so:
<fragment
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />

Related

Android Google Maps Fragment

I have created a new Android project with a Google Map activity defined as
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
The Layout is this
<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"
tools:context="com.example.alewe.myapplication.MapsActivity" />
The problem is :
i have created another activity and im trying to add the google map fragment inside it.
Using the
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction().replace(R.id.firstLayout,this,this.getTag());
doesnt work because i cant cast FragmentActivity to Fragment.
How can i add the google maps fragment just created inside another activity ?
Thanks
Change your layout (activity_maps) like this:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.alewe.myapplication.MapsActivity"
android:id="#+id/main_view_map">
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/button"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:elevation="10dp"
app:fabSize="mini"
app:srcCompat="#drawable/ic_refresh_black_24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="16dp" />
<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" />
</androidx.constraintlayout.widget.ConstraintLayout>
And don't use
FragmentManager manager = getSupportFragmentManager();
manager.beginTransaction().replace(R.id.firstLayout,this,this.getTag());
this code.

Switching from fragment with map fragment leaves a black screen

I have added a full-screen map fragment to one of my three tabbed fragments. Everything works great apart from an issue I'm experiencing with switching between the tabs.
Each time I switch from the fragment with the map, to one of the other fragments, I get a black screen for like 0.2 seconds. It seems to be a similar issue to the problems with scrolling in an activity with a map fragment.
I've tried adding a transparent view other the top of the map as others have suggested, but it didn't help.
This is my xml:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ParkMapFragment">
<fragment
android:id="#+id/fullParkMap"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
And this is my code:
public class ParkMapFragment extends Fragment {
public ParkMapFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_map, container, false);
}
#Override
public void onStart(){
super.onStart();
getActivity().setTitle("Map");
}
#Override
public void onDestroyView() {
super.onDestroyView();
SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
if (mapFragment != null) {
getFragmentManager().beginTransaction().remove(mapFragment).commit();
}
}
}
Anyone have any suggestions?
Check if the view is null, and if not, remove it from its parent view. That way, you won't see the black screen.
Try the code below.
Fragment:
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerClickListener;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.view.InflateException;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public class ExhibhitionMap2 extends Fragment implements OnMapClickListener,OnMarkerClickListener{
View v;
private GoogleMap mMap;
FragmentManager fragmentManager;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// android = inflater.inflate(R.layout.activity_exhibhition_map, container, false);
if (v != null) {
ViewGroup parent = (ViewGroup) v.getParent();
if (parent != null)
parent.removeView(v);
}
try {
v = inflater.inflate(R.layout.activity_exhibhition_map, container, false);
} catch (InflateException e) {
/* map is already there, just return view as it is */
}
setUpMapIfNeeded();
return v;
}
/***** Sets up the map if it is possible to do so *****/
public void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
mMap = ((SupportMapFragment) this.getChildFragmentManager().findFragmentById(R.id.map2)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null)
{
mMap.setOnMapClickListener(this);
mMap.setOnMarkerClickListener((OnMarkerClickListener) this);
MarkerOptions marker = new MarkerOptions().position(new LatLng(36.011513,-115.174853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.title("P-1");
MarkerOptions marker01 = new MarkerOptions().position(new LatLng(36.111513,-115.204853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.title("P-2");
MarkerOptions marker02 = new MarkerOptions().position(new LatLng(36.051513,-115.154853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.title("P-3");
MarkerOptions marker03 = new MarkerOptions().position(new LatLng(36.057513,-115.344853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE))
.title("P-4");
MarkerOptions marker1 = new MarkerOptions().position(new LatLng(36.081513,-115.224853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
.title("F-1");
MarkerOptions marker2 = new MarkerOptions().position(new LatLng(36.051513,-115.334853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
.title("F-2");
MarkerOptions marker3 = new MarkerOptions().position(new LatLng(36.101513,-115.124853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
.title("F-1");
MarkerOptions marker4 = new MarkerOptions().position(new LatLng(36.031513,-115.154853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
.title("F-2");
MarkerOptions marker5 = new MarkerOptions().position(new LatLng(36.081513,-115.194853))
.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_CYAN))
.title("F-2");
mMap.addMarker(marker);
mMap.addMarker(marker01);
mMap.addMarker(marker02);
mMap.addMarker(marker03);
mMap.addMarker(marker1);
mMap.addMarker(marker2);
mMap.addMarker(marker3);
mMap.addMarker(marker4);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(36.051513,-115.174853), 10.0f));
}
}
}
#Override
public boolean onMarkerClick(Marker marker) {
/*Toast.makeText(getActivity(),
"" + marker.getTitle(), Toast.LENGTH_LONG)
.show();*/
marker.showInfoWindow();
return false;
}
#Override
public void onMapClick(LatLng arg0) {
// TODO Auto-generated method stub
}
public void onDestroy() {
super.onDestroy();
}
}
XML:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.istride.mmps.ContactActivity" >
<RelativeLayout
android:id="#+id/relativeLayout1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="#+id/tableLayout1"
android:visibility="gone"
android:layout_margin="10dp" >
<TextView
android:id="#+id/tv_Title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="Bharati Vidyapeeth University's"
android:textColor="#color/black_text_color"
android:textSize="#dimen/Large_Size" />
<TextView
android:id="#+id/tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_below="#+id/tv_Title"
android:text="Department of Information Technology and Management "
android:textColor="#color/black_text_color"
android:textSize="#dimen/small_size" />
<View
android:id="#+id/view2"
android:layout_width="fill_parent"
android:layout_height="2dp"
android:layout_below="#+id/tv"
android:layout_marginTop="10dp"
android:background="#color/blue_background" />
<RelativeLayout
android:id="#+id/relative"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/view2"
android:layout_marginTop="10dp"
android:background="#color/gray_home">
<TextView
android:id="#+id/textVi1"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/tv_add"
android:layout_alignParentTop="true"
android:background="#color/blue_background"
android:paddingBottom="2dp"
android:paddingLeft="8dp"
android:paddingRight="13dp"
android:paddingTop="2dp"
android:gravity="center_vertical"
android:text="ADDRESS "
android:textColor="#color/white_text_color"
android:textSize="#dimen/Medium_size"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:layout_toRightOf="#+id/textVi1"
android:paddingBottom="2dp"
android:paddingTop="2dp"
android:text="2nd Floor, Architecture Building, Bharati Vidyapeeth Campus, Dhankawadi, Pune-411043"
android:textColor="#color/black_text_color"
android:textSize="#dimen/Medium_size" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/relativeLayout_call"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/relative"
android:layout_marginTop="10dp"
android:background="#color/gray_home">
<TextView
android:id="#+id/textView1"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/tv_school_office_num"
android:layout_alignParentTop="true"
android:background="#color/blue_background"
android:paddingBottom="2dp"
android:paddingLeft="8dp"
android:paddingRight="13dp"
android:paddingTop="2dp"
android:text="PHONE "
android:gravity="center_vertical"
android:textColor="#color/white_text_color"
android:textSize="#dimen/Medium_size"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_school_office_num"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:layout_marginRight="5dp"
android:layout_toRightOf="#+id/textView1"
android:layout_toLeftOf="#+id/imageView2"
android:textColor="#color/black_text_color"
android:paddingTop="2dp"
android:textSize="#dimen/Medium_size"
android:paddingBottom="2dp"
android:text="+91 989898989 asasa asas asasas ass sdsd asas asas ass assas asas ass " />
<ImageView
android:id="#+id/imageView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="3dp"
android:src="#drawable/ic_call" />
</RelativeLayout>
<RelativeLayout
android:id="#+id/relativeLayout_Email"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_below="#+id/relativeLayout_call"
android:layout_marginTop="10dp"
android:background="#color/gray_home">
<TextView
android:id="#+id/tex1"
android:layout_width="90dp"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView1"
android:layout_alignParentTop="true"
android:background="#color/blue_background"
android:gravity="center_vertical"
android:paddingBottom="2dp"
android:paddingLeft="8dp"
android:paddingRight="13dp"
android:paddingTop="2dp"
android:text="EMAIL "
android:textColor="#color/white_text_color"
android:textSize="#dimen/Medium_size"
android:textStyle="bold" />
<TextView
android:id="#+id/tv_school_office_email"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="#+id/imageView1"
android:layout_alignParentTop="true"
android:layout_marginLeft="10dp"
android:gravity="center_vertical"
android:layout_toRightOf="#+id/tex1"
android:textColor="#color/black_text_color"
android:paddingTop="2dp"
android:paddingBottom="2dp"
android:textSize="#dimen/Medium_size"
android:text="principal.mmei#eternalmewar.in" />
<ImageView
android:id="#+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:layout_marginRight="3dp"
android:src="#drawable/ic_email" />
</RelativeLayout>
</RelativeLayout>
<fragment
android:id="#+id/map2"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentRight="true"
android:layout_marginTop="10dp"
class="com.google.android.gms.maps.SupportMapFragment"
android:background="#color/gray_color"
android:paddingBottom="5dp"
android:layout_above="#+id/footer"
android:textSize="#dimen/small_size" />
<RelativeLayout
android:id="#+id/footer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="10dp"
android:layout_alignParentLeft="true"
android:layout_alignParentRight="true" >
<TextView
android:id="#+id/blue"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#0000FF"
android:gravity="center"
android:layout_margin="10dp"
android:textColor="#color/black_text_color"
android:textSize="#dimen/small_size"
android:textStyle="bold" />
<TextView
android:id="#+id/parking"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/blue"
android:layout_alignTop="#+id/blue"
android:layout_alignBottom="#+id/blue"
android:gravity="center_vertical"
android:text="Parking"
android:textColor="#color/black_text_color"
android:textSize="#dimen/Medium_size"
android:textStyle="bold" />
<TextView
android:id="#+id/cyc"
android:layout_width="20dp"
android:layout_height="20dp"
android:background="#00FFFF"
android:gravity="center"
android:layout_margin="10dp"
android:layout_toRightOf="#+id/parking"
android:textColor="#color/black_text_color"
android:textSize="#dimen/small_size"
android:textStyle="bold" />
<TextView
android:id="#+id/footer2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toRightOf="#+id/cyc"
android:layout_alignTop="#+id/cyc"
android:layout_alignBottom="#+id/cyc"
android:gravity="center_vertical"
android:text="Food"
android:textColor="#color/black_text_color"
android:textSize="#dimen/Medium_size"
android:textStyle="bold" />
</RelativeLayout>
</RelativeLayout>
#Override
public void onDestroyView() {
super.onDestroyView();
SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
if (mapFragment != null) {
getFragmentManager().beginTransaction().remove(mapFragment).commit();
}
}
right here you are removing the fragment without replacing it. I would use .replace instead with a new fragment.
Something like this:
getFragmentManager().beginTransaction().replace(R.id.your_placeholder, new CustomFragment(), "cstmFragID").commit();
i would recommend you to use MapView instead of SupportFragment to avoid nested fragment For details answer look at the following post
Should I use MapView or MapFragment
Now your ParkFragment be look like
MapFragment.java
public class MapFragment extends Fragment implements OnMapReadyCallback {
private MapView mMapView;
private GoogleMap mGoogleMap;
public MapFragment() {
// Required empty public constructor
}
public static MapFragment newInstance() {
MapFragment fragment = new MapFragment();
return fragment;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container, false);
mMapView = (MapView) rootView.findViewById(R.id.map);
mMapView.onCreate(savedInstanceState);
mMapView.getMapAsync(this);
return rootView;
}
#Override
public void onResume() {
super.onResume();
mMapView.onResume();
}
#Override
public void onPause() {
mMapView.onPause();
super.onPause();
}
#Override
public void onDestroy() {
mMapView.onDestroy();
super.onDestroy();
}
#Override
public void onMapReady(GoogleMap googleMap) {
googleMap.getUiSettings().setZoomControlsEnabled(true);
}
}
fragment_map.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.google.android.gms.maps.MapView
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</FrameLayout>
The problem is possibly because it is recreating Fragment which causes the Black screen. If you are using ViewPager then you can use
// Note that you must set adapter before this line otherwise it can cause NullPointerException
// Or add null check on getAdapter if required
mViewPager.setOffscreenPageLimit(mViewPager.getAdapter().getCount());
It will force ViewPager not to create Fragments second time. For sure, it takes more memory but I believe it is more efficient when using less tabs so I normally do this to avoid recreation of fragments.
Secondly I would suggest to remove these lines from onDestroy:
SupportMapFragment mapFragment = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.fullParkMap);
if (mapFragment != null) {
getFragmentManager().beginTransaction().remove(mapFragment).commit();
}
And overcome this issue by updating onCreateView as this:
private View mView;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (mView == null) {
mView = inflater.inflate(R.layout.fragment_map, container, false);
}
return mView;
}
It will not inflate layout every time so you will not face Duplicate ID, tag null, or parent id with another fragment for com.google.android.gms.maps.MapFragment issue.
But make sure you pass false in attachToRoot (last argument of inflater.inflate) otherwise you may get exceptions like The specified child already has a parent
Last thing, when using MapFragment inside Fragment, or in other words, when using Nested Fragments, I would recommend use getChildFragmentManager() instead of getFragmentManager() to avoid unexpected issues.
Because as the documentation says:
getFragmentManager: Return the FragmentManager for interacting with fragments associated with this fragment's activity. Note that this will be non-null slightly before getActivity(), during the time from when the fragment is placed in a FragmentTransaction until it is committed and attached to its activity. If this Fragment is a child of another Fragment, the FragmentManager returned here will be the parent's getChildFragmentManager().
getChildFragmentManager: Return a private FragmentManager for placing and managing Fragments inside of this Fragment.
This is a known issue. For the meantime, you may use work around by placing another view on top of the map that uses a background color that is the same as its container is. This makes the map smoothly come in once its ready.
SupportMapFragment mapFragment = SupportMapFragment.newInstance(new GoogleMapOptions().zOrderOnTop(true));
As you always replace fragment then map gets always created then workaround for this would be load your map fragment only once, rest of the time just show/hide your fragment (as if you are showing tabbed fragments).
Have you tried to hide and show fragment (instead of remove/adding it) ?
private FragmentA fragmentA;
private FragmentB fragmentB;
private FragmentC fragmentC;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
fragmentA = FragmentA.newInstance("foo");
fragmentB = FragmentB.newInstance("bar");
fragmentC = FragmentC.newInstance("baz");
}
}
In your case you might change it to ParkMapFragment etc.
protected void displayFragmentA() {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (fragmentA.isAdded()) { // if the fragment is already in container
ft.show(fragmentA);
} else { // fragment needs to be added to frame container
ft.add(R.id.flContainer, fragmentA, "A");
}
// Hide fragment B
if (fragmentB.isAdded()) { ft.hide(fragmentB); }
// Hide fragment C
if (fragmentC.isAdded()) { ft.hide(fragmentC); }
// Commit changes
ft.commit();
}
source: https://github.com/codepath/android_guides/wiki/Creating-and-Using-Fragments
Try this inside createView:
if (v != null) {
ViewGroup parent = (ViewGroup) v.getParent();
if (parent != null)
parent.removeView(v);
}
You should make the transition of fragments by this way:
Fragment fragment = new YourFragmentToShow();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, TAG).setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE).commit();
With TRANSIT_FRAGMENT_FADE Fragment should simply fade in or out; that is, no strong navigation associated with it except that it is appearing or disappearing for some reason.
Use it when you replace the fragment with map by another fragment, in other case I recomend the common use, without (.setTransition...):
Fragment fragment = new YourFragmentToShow();
getFragmentManager().beginTransaction().replace(R.id.content_frame, fragment, TAG).commit();

Cannot fix Map Fragment in Fragment NullPointerException

I am trying to show a Map in a Fragment but I always get this NullPointerException:
java.lang.NullPointerException: Attempt to invoke virtual method
'com.google.android.gms.maps.GoogleMap
com.google.android.gms.maps.SupportMapFragment.getMap()' on a null
object reference
I knew there are many questions with this exception in this case but i can't find my mistake. I read any answer I have found.
Here is my Code:
public class DetailKarteFragment extends Fragment {
GoogleMap map;
static final LatLng brend = new LatLng(48.079, 8.157);
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.fragment_detail_karte, null, false);
FragmentTransaction ft = getFragmentManager().beginTransaction();
map = ((SupportMapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
SupportMapFragment fmap = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
if (fmap == null) {
fmap = SupportMapFragment.newInstance();
ft.add(R.id.map, fmap);
}
ft.commit();
Marker brendMarker = map.addMarker(new MarkerOptions().position(brend).title("Brend"));
// Move the camera instantly to hamburg with a zoom of 15.
map.moveCamera(CameraUpdateFactory.newLatLngZoom(brend, 15));
// Zoom in, animating the camera.
map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
return v;
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
}
and the xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:background="#color/background"
android:layout_height="match_parent">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="bottom">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Route anzeigen"
android:id="#+id/button_route_planen"
android:layout_gravity="center_horizontal"
android:height="48dp"
android:background="#color/secondary_100"
android:layout_marginBottom="-48dp"/>
</LinearLayout>
</LinearLayout>
Just move the map = (...).getMap() line after ft.commit(). You are getting that exception because FragmentManager can't find a fragment which has not already been added or replaced into the container.
A better solution in my opinion would be:
SupportMapFragment fmap;
fmap = (SupportMapFragment) getFragmentManager().findFragmentById(R.id.map);
if (fmap == null) {
fmap = SupportMapFragment.newInstance();
ft.add(R.id.map, fmap);
ft.commit();
}
map = fmap.getMap();
You are retrieving the GoogleMap object map before checking if the SupportMapFragment even exists. I assume that this fragment hasn't been added yet, and you're invoking the getMap() method on a null reference.
I know this question is very old... But I just had this problem and I would like to share what was happening to me and the solution.
I was trying to put a MapFragment inside a fragment just like you. But I forgot to put the key in my manifest:
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="#string/google_maps_key" />
So, when this happens in a Activity, it throw an exception. That's great, because your app crashes and you can read the log and understand what you have to do! You get this message:
Caused by: java.lang.RuntimeException: API key not found.
Check that <meta-data android:name="com.google.android.geo.API_KEY" android:value="your API key"/>
is in the <application> element of AndroidManifest.xml
It's very easy to find what needs to be done this way, right?
But it doesn't happen when the MapFragment is inside another fragment!
It only return a null fragment... just like the problem you have right now.
So just put the key in the Manifest and you will be fine! I hope Google fix this, because it took me some hours to find out what was wrong.

How to add map fragment programmatically

I would like add this xml fragment programmatically to other fragments.
Is it possible?
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment" />
In XML you can add a placeholder container:
<FrameLayout
android:id="#+id/mapContainer"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
And then in code you can do:
FragmentManager fm = getChildFragmentManager();
SupportMapFragment supportMapFragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.mapContainer, supportMapFragment).commit();
Make a layout like:
<FrameLayout
android:id="#+id/layout_mapContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_weight="0"
android:background="#android:color/transparent"
android:orientation="vertical" >
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/transparent" />
</FrameLayout>
In Activity declare :
FrameLayout mapLayout = (FrameLayout)findViewById(R.id.layout_mapContainer);
initialise map like this:
private void initialiseMap() {
FragmentTransaction mTransaction = getSupportFragmentManager().beginTransaction();
SupportMapFragment mFRaFragment = new MapFragmentActivity();
mTransaction.add(mapLayout.getId(), mFRaFragment);
mTransaction.commit();
try {
MapsInitializer.initialize(context);
} catch (Exception e) {
e.printStackTrace();
}
}
Here MapFragmentActivity is class extends SupportMapFragment

calling getMap() inside nested mapfragment gives nullpointerexception

I have a mapfragment inside a custom fragment, by calling it like in the answer provided here
Unfortunatly there's a NullPointerException, if I call the getMap()-Method (see attached code). Has anybody an idea why? Thanks for your help!
private void initializeMap() {
initializeMapFragment();
try {
// show current location
map.setMyLocationEnabled(true);
map.getUiSettings().setRotateGesturesEnabled(true);
map.getUiSettings().setZoomGesturesEnabled(true);
// adding marker
addDestinationMarker();
// zoom to current location
Location myLocation = map.getMyLocation();
if (myLocation != null) {
LatLng currentPosition = new LatLng(myLocation.getLatitude(), myLocation.getLongitude());
CameraPosition cameraPosition = new CameraPosition.Builder().target(currentPosition).zoom(12).build();
map.moveCamera(CameraUpdateFactory.newLatLng(currentPosition));
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
} catch (Exception e) {
e.printStackTrace();
}
}
private void initializeMapFragment() {
MapFragment mapFragment = MapFragment.newInstance();
FragmentManager fm = getFragmentManager();
if (fm.findFragmentByTag("my_map_fragment") == null) {
FragmentTransaction ft = fm.beginTransaction();
ft.replace(R.id.map_container, mapFragment, "my_map_fragment").commit();
}
map = mapFragment.getMap();
}
EDIT //
The xml of the HomeFragment looks like this:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" android:weightSum="1">
<FrameLayout
android:id="#+id/map_container"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="1">
</FrameLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_gravity="top|bottom|left|right|center"
android:background="#drawable/bg_lines"
android:orientation="horizontal">
<Button
android:id="#+id/alarmButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
style="#style/BlueButtonStyle"
android:text="#string/btn_alarm"/>
</LinearLayout>

Categories