Using SupportMapFragment in Activity instead of FragmentActivity - android

I am using SupportMapFragment to show the google map in my activity. But the activity must be declared as FragmentActivity. Is there any way to use it in Activity instead of FragmentActivity? Here is my work:
In xml, I use:
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
In class file:
public class MapActivity extends FragmentActivity {
Context context;
GPSTracker gps;
Location location;
GoogleMap mMap;
#Override
protected void onResume() {
super.onResume();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_map);
gps = new GPSTracker(this);
location = gps.getLocation();
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map)).getMap();
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(
new LatLng((locLat + location.getLatitude()) / 2,
(locLng + location.getLongitude()) / 2), 12.0f));
}

The correct way to do it is:
Put your map inside a fragment and in your activity inflate this fragment.
your xml code:
<com.google.android.gms.maps.MapView
android:id="#+id/map_detail"
android:layout_width="match_parent"
android:layout_height="246dp" />
your java code to put in activity to inflate fragment:
FragmentManager fragmentManager = getFragmentManager();
fragmentManager.beginTransaction().replace(R.id.frame_container, new MapFragment()).commit();
With this way you can implements Activity in your activity class and Fragment in your fragment class.

Related

MapFragment is displaying but can't add markers, move camera, etc. with Google Map

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)

Google maps error inflating, Android

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" />

getMapAsync() in Fragment

I having trouble implementing Google Map in Fragment.
This is my the part of my fragment class:
public class FragmentStoreFinderMap extends Fragment implements OnMapReadyCallback {
// Google Map
private GoogleMap googleMap;
private int i;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
googleMap = ((SupportMapFragment)getActivity().getSupportFragmentManager().findFragmentById(
R.id.map)).getMapAsync(this);
I am getting an error in getMapAsync(this). I tells Incompatible type.
it says:
required: com.google.android.gms.map.GoogleMap
found: void
BTW here is my xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<fragment class="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
In your XML layout you should do like this
<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>
inside your fragment implement this
private MapView mapView;
private GoogleMap googleMap;
override onCreateView if there is no onCreateView just like the code below
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.your_layout, container, false);
}
override onViewCreated() inside that
onViewCreated() put this
mapView = (MapView) view.findViewById(R.id.map);
mapView.onCreate(savedInstanceState);
mapView.onResume();
mapView.getMapAsync(this);//when you already implement OnMapReadyCallback in your fragment
when you already implement OnMapReadyCallback in your fragment put this/code like this
#Override
public void onMapReady(GoogleMap map) {
googleMap = map;
}
hope this helps you.
After a few overheats in my head, thanks to this post and https://stackoverflow.com/a/34732804/3925554, I would say that currently there are two ways of adding a MapFragment to your app:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
class="com.google.android.gms.maps.SupportMapFragment"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
By this way, you have to use a standard fragment and implement this inside. Actually you are inserting a fragment into another:
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
SupportMapFragment supportMapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
supportMapFragment.getMapAsync(this);
}
The other way would be extending the real SupportMapFragment and implement it in this manner without the need of an xml:
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
getMapAsync(this);
}
And they work without having to set a layout in onCreateView neither call mapView.onCreate(savedInstanceState); and mapView.onResume(); manually inside onViewCreated(), what is not recommended anyway.
Hope it helps!
SupportMapFragment mMapFragment = SupportMapFragment.newInstance();
FragmentTransaction fragmentTransaction =
getChildFragmentManager().beginTransaction();
fragmentTransaction.add(R.id.flMap, mMapFragment);
fragmentTransaction.commit();
mMapFragment.getMapAsync(this);
Your code is returning this error because getMapAsync() does not return anything. If you look at the documentation for this function:
public void getMapAsync (OnMapReadyCallback callback)
Sets a callback object which will be triggered when the GoogleMap
instance is ready to be used.
Note that:
This method must be called from the main thread. The callback will be
executed in the main thread. In the case where Google Play services is
not installed on the user's device, the callback will not be triggered
until the user installs it. In the rare case where the GoogleMap is
destroyed immediately after creation, the callback is not triggered.
The GoogleMap object provided by the callback is non-null.
OnMapReadyCallback is an interface that needs implemented and passed to through this function. Nothing is currently assigned to your googleMap variable you should instead set its value in this block of code which implements OnMapReadyCallback
#Override
public void onMapReady(GoogleMap googleMap) {
this.googleMap = googleMap;
}
This code should be in your Fragment somewhere. Since your Fragment already implements this interface you do pass it in as this.

Inconvertible type error from fragment to SupportMapFragment

So I have a fragment class:
public class MyMapFragmentActivity extends Fragment implements LocationListener,
GoogleMap.OnMapClickListener, GoogleMap.OnMapLongClickListener {
Within it I have a SupportMapFragment defined:
private SupportMapFragment fragment;
I am trying to use the findFragmentById:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
FragmentManager fm = getChildFragmentManager();
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
if (fragment == null) {
fragment = SupportMapFragment.newInstance();
fm.beginTransaction().replace(R.id.content_frame, fragment).commit();
}
}
The line
fragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
Despite the 'fragment' being a SupportMapFragment, this is giving inconvertible type error:
cannot cast android.app.fragment to com.google.android.gms.maps.SupportMapFragment !
I'm using fragment layout:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.SupportMapFragment" />
If you use compatibility library - use getSupportFragmentManager().findFragmentById(R.id.fragment); otherwise extend from android.app.Fragment instead of android.support.v4.app.fragment.
You're mixing support fragments and the non-support fragment manager. Use the SupportFragmentManager instead.

Mapfragment findFragmentById always null

I have problems to access the fragment of the map.
getFragmentManager().findFragmentById(R.id.map)) returns always null.
I don't know why.
What's the problem?
Thank you!
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/tvNombreCentro"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="10dp"
android:text="Large Text"
android:textAppearance="?android:attr/textAppearanceLarge" />
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:tag="tag_fragment_map" />
</LinearLayout>
And in the activity after the setContentView I try to access to the map, but I receive an exception
public class Mapa extends Activity {
private GoogleMap mMap;
private ActionBar ab;
private TextView tvNombreCentro;
private TextView tvTelefonoValor;
private TextView tvEMailValor;
private TextView tvWebValor;
private TextView tvDireccionValor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mapa_centro);
GoogleMap mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
.getMap();
}
use this way:
SupportMapFragment mapFrag = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
map = mapFrag.getMap();
here is full code with sample:
In case your problem is not solved, try this :
As you are using SupportMapFragment, while retrieving map, use
GoogleMap mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
Also, change
public class Mapa extends Activity {
to
public class Mapa extends FragmentActivity {
I had a similar problem when trying to get MapFragment but getting null because the device didn't have Google Play Services updated.
Change in the layout
android:name = "com.google.android.gms.maps.SupportMapFragment"
by
android:name = "com.google.android.gms.maps.MapFragment".
Or, you can use getSupportFragmentManager() instead of getFragmentManager().

Categories

Resources