I have a frame layout in my fragment layout and I can't access map fragment after I replace the frame layout with map fragment. I am having null pointer exception when I try to access the map after I put it into frame layout.
Here's my related layout:
<FrameLayout
android:id="#+id/map"
android:layout_width="fill_parent"
android:layout_height="0dp"
android:layout_weight="15" >
</FrameLayout>
Here's my code in fragment:
private GoogleMap map;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
fm.beginTransaction()
.replace(R.id.map, SupportMapFragment.newInstance()).commit();
map = ((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map))
.getMap();
map.moveCamera(CameraUpdateFactory.newLatLngZoom(KOCAELI, 15));
}
Related
I'm making an application using Android Studio and even though I've got the map and it's being displayed, I can't add markers or do anything else to it using the GoogleMap object obtained from OnMapReady.
Here's the code from my Main Activity:
public class MainActivity extends AppCompatActivity implements OnFragmentInteractionListener, OnMapReadyCallback {
MapFragment mapFragment;
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
switchFragments(GlobalConsts.FRAGMENT.MAP);
}
public void switchFragments(GlobalConsts.FRAGMENT fragment){
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
switch (fragment) {
case MAP:
if (mapFragment == null) {
mapFragment = new MapFragment();
}
mapFragment.getMapAsync(this);
transaction.replace(R.id.fragmentContainer, mapFragment);
transaction.addToBackStack(null);
break;
}
transaction.commit();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng sydney = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions()
.position(sydney)
.title("Sydney")
.snippet("Population: 4,627,300")
.icon(BitmapDescriptorFactory.fromResource(R.drawable.marker)));
CameraPosition cameraPosition = new CameraPosition.Builder().target(sydney).zoom(12).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
}
}
Here's the xml layout for my Main Activity
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
tools:context="jarett.familymap.MainActivity">
<FrameLayout
android:id="#+id/fragmentContainer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
My MapFragment class:
public class MapFragment extends SupportMapFragment {
public MapFragment() {}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
super.onCreateView(inflater, container, savedInstanceState);
return inflater.inflate(R.layout.fragment_map, container, false);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
}
}
and the xml layout for my MapFragment in fragment_map.xml:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/mapFragment"
android:orientation="vertical"
android:layout_width="match_parent" android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"
tools:context="jarett.familymap.MapFragment">
</fragment>
Like I said, everything seems to be working fine as far as displaying the map fragment but for the life of me I can't figure out why the code for zooming and adding markers isn't doing anything. I appreciate the help.
I can't figure out why the code for zooming and adding markers isn't doing anything
Well, you have two maps. Your MapFragment extends SupportMapFragment, so that will give you one map. Then, your MapFragment inflates a layout that, in turn, creates a SupportMapFragment. This gives you two maps.
Either:
Delete MapFragment entirely, along with its associated layout file, and just have your activity create a SupportMapFragment, or
Delete your onCreateView() method from MapFragment, and move your map-management code into MapFragment, triggered by a getMapAsync() call in onViewCreated() (as I worry that you are calling it too soon in your existing code)
I get the following error when I try to leave fragment which contains map (on back button press).
ERROR: mapInflater->Binary XML file line #7: Error inflating class fragment
Bellow is onCreate() method of fragment where the map is placed. And also there is a xml code of layout.
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
apiRequestManager = ApiRequestManager.getInstance();
fragmentHandler = FragmentHandlerActivityMain.getInstance(getActivity());
session = new SessionManager(App.getInstance().getApplicationContext());
((AppCompatActivity) getActivity()).getSupportActionBar().setTitle(getString(R.string.maps_fragment_toolbar_name));
Handler mainHandler = new Handler();
Runnable myRunnable = new Runnable() {
#Override
public void run() {
try {
SupportMapFragment maps = (SupportMapFragment) getChildFragmentManager()
.findFragmentById(R.id.mapView);
if (maps != null)
maps.getMapAsync(MapsFragment.this);
} catch (Exception ex) {
LogUtil.getInstance().add(LogUtil.ERROR,
TAG, "onCreateMaps", ex);
}
}
};
mainHandler.post(myRunnable);
}
Log is pointing on this layout on fragment (line 7).
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app1="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".salesman.fragments.MapsFragment">
<fragment
android:id="#+id/mapView"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"/>
</FrameLayout>
You are trying to getChildFragmentManager() instade of getSupportFragmentManager().
Need to change In Java File :
1). You need to implements OnMapReadyCallback in Your Fragment.
2). Get SupportMapFragment from View.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
3). Overrid onMapReady(GoogleMap googlMap) Method.
#Override
public void onMapReady(GoogleMap googleMap) {
// Add a marker in Sydney, Australia,
LatLng sydney = new LatLng(-33.852, 151.211);
googleMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
// and move the map's camera to the same location.
googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
In XML File :-
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app1="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".salesman.fragments.MapsFragment">
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
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"/>
</FrameLayout>
Please check the updated answer as per below comment:
Now try to set MapView insted of fragment because if you use fragment inside fragment it creates lot of issues.
Need to change in JAVA Code : // Initialize GoogleMap myMap; MapView mMapView;
// OnCreateView Method MapsInitializer.initialize(this.getActivity()); mMapView = (MapView) rootView.findViewById(R.id.map); mMapView.onCreate(savedInstanceState); mMapView.getMapAsync(this);
#Override public void onPause() { super.onPause(); mMapView.onPause(); }
#Override public void onPause() { super.onPause(); mMapView.onPause(); }
#Overridepublic void onResume() { super.onResume(); mMapView.onResume(); }
Need to change in XML File :
<com.google.android.gms.maps.MapView android:id="#+id/map" android:layout_width="match_parent" android:layout_height="match_parent" />
I`m developing an application that uses an activity with navigation drawer. I have two fragments in the drawer one of which is a google map.
In the map fragment class I want to initialize the GoogleMap object to do some things to the map, but in the onCreateView after I initialize the view through inflater, my app doesn't find the id in R class to initialize the google map.
I call the fragment from the activity through:
FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();
fragmentTransaction.add(R.id.mainContent, map, Map.class.getSimpleName());
fragmentTransaction.addToBackStack(Map.class.getSimpleName());
fragmentTransaction.commit();
the container xml:
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawerLayout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<FrameLayout
android:id="#+id/mainContent"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</FrameLayout>
<ListView
android:id="#+id/drawerList"
android:layout_width="200dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#color/background_color" >
</ListView>
</android.support.v4.widget.DrawerLayout>
layout_fragment_map.xml:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:name="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
The Map fragment class:
public class Map extends Fragment {
private View view;
private MapFragment mapFragment;
private GoogleMap googleMap;
#Override
public void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (view != null) {
ViewGroup parent = (ViewGroup) view.getParent();
if (parent != null)
parent.removeView(view);
}
try {
view = inflater.inflate(R.layout.layout_fragment_map, container, false);
} catch (InflateException e) {
/* map is already there, just return view as it is */
}
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
googleMap = mapFragment.getMap();
return view;
}
In the line:
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
the R.id.map is undefined Eclipse gives "could not resolve type".
Something is missing or my whole concept is faulty?
Thank you and happy coding!
I resolved the issue by modifying the line:
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.googleMap);
with
mapFragment = (MapFragment) getChildFragmentManager().findFragmentById(R.id.googleMap);
It is strange because the R.id.googleMap is still undefined but the object gets created correctly.
i have a mapfragment inside another fragment
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.MapFragment"
/>
</FrameLayout>
and im initializing map in oncreateview
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
view = inflater.inflate(R.layout.event_fragment, null);
try{
events = new ArrayList<EventsModel>();
try {
initilizeMap();
} catch (Exception e) {
e.printStackTrace();
}
double latitude = 24.875419;
double longitude = 66.993293;
CameraPosition cameraPosition = new CameraPosition.Builder().target(
new LatLng(latitude, longitude)).zoom(12).build();
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
loadEvents().execute();
}catch(Exception e){
}
return view;
}
its working fine but when i press back button and reopen this fragment it crashes
04-19 21:18:21.803: E/AndroidRuntime(31612): Caused by: java.lang.IllegalArgumentException: Binary XML file line #6: Duplicate id 0x7f050006, tag null, or parent id 0xffffffff with another fragment for com.google.android.gms.maps.MapFragment
then i googled it and put it in ondestroy
Fragment fragment = (getFragmentManager().findFragmentById(R.id.map));
FragmentTransaction ft = getActivity().getSupportFragmentManager().beginTransaction();
ft.remove(fragment);
ft.commit();
the above problem is resolved bu now it gives me nullpointer on reopening the fragment that had mapfragment in it may be because i removed it with above code but whats the solution now?
Please make sure that you have correctly checked the condition where map inflated is null or not while creating view for map fragment or while destroying.
put this one on onDestroy() method
SupportMapFragment mapFragment = ((SupportMapFragment)
getActivity().getSupportFragmentManager().findFragmentById(R.id.map_location_sharing));
if(mapFragment != null) {
FragmentManager fM = getFragmentManager();
fM.beginTransaction().remove(mapFragment).commit();
I'm using sliding menu for Android here is the link, when I slide on rendered map fragment, the sliding menu goes blank.
Here is my map fragment code.
public class BasicMapActivity extends SherlockFragment {
private MapView mMapView;
private GoogleMap mMap;
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.basic_demo, null);
// view.setBackgroundColor(0x00000000);
mMapView = (MapView) view.findViewById(R.id.map);
container.requestTransparentRegion(mMapView);
mMapView.onCreate(savedInstanceState);
return view;
}
}
Here is my home activity where in i render map.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_frame);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.home_screen, new BasicMapActivity())
.commit();
getSlidingMenu().setSecondaryMenu(
getLayoutInflater().inflate(R.layout.resq_events_frame, null));
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.resq_events_screen, new EventsFragment())
.commit();
// set the Behind View
setBehindContentView(R.layout.activity_settings_frame);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.settings_screen, new SettingsFragment())
.commit();
// customize the SlidingMenu
getSlidingMenu().setTouchModeAbove(SlidingMenu.TOUCHMODE_FULLSCREEN);
}
My XML file looks like this
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/home_screen"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
How to overcome by this issue?
Here how the image looks.
The issue is due to GoogleMap, you have to add this map:zOrderOnTop="true" to your XML map layout, like
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<fragment
android:name="com.google.android.gms.maps.SupportMapFragment"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:zOrderOnTop="true" />
</LinearLayout>