I have an FragmentActivity which has a SupportMapFragment. I want to add buttons, menus (slide menu)...how could I do this?
here is my code:
public class MapsActivity extends FragmentActivity {
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private LocalizeDB db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
db = new LocalizeDB(this);
}
#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 (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMap();
}
}
}
FragmentActivity is a subclass of Activity. Most of all things you do with an Activity you can do with a FragmentActivity (some differences are stated here).
I think you will use your activity_maps layout to place additional buttons. The slide menu may be implemented as a Navigation Drawer. Let me know if I've missed something.
Hope it helps!
Related
I've got an app which is quite intensive in terms of memory and i'm trying to get all I can. I've noticed something which I can't work out, Google maps is keeping its allocation of memory even after (I think) i'm getting rid of it.
Before Google Maps is called:
After Google Maps is called:
Returned from Google Maps with back button:
Returned from Google Maps with on info window press button:
(the slightly higher number is just due to the fact I included a couple of methods more to include a marker to return)
As you can see, it's retaining a lot of the memory. So i'll show you how this is working:
Google Maps is not actually called, but a container for Google Maps is, and it's below:
public class GoogleMapsAndBookmarksContainer extends ActionBarActivity {
private FragmentTabHost mTabHost;
public ArrayList frameListContainer;
public HashMap<String, HashMap> bookmarkInfo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_google_maps_and_bookmarks_container);
frameListContainer = (ArrayList) getIntent().getSerializableExtra("arrayListWithFrameAttributes");
bookmarkInfo = (HashMap) getIntent().getSerializableExtra("hashmapWithBookmarks");
mTabHost = (FragmentTabHost) findViewById(android.R.id.tabhost);
mTabHost.setup(this, getSupportFragmentManager(), android.R.id.tabcontent);
// The first tab is the google maps fragment which i'll include below
mTabHost.addTab(
mTabHost.newTabSpec("tab1").setIndicator("Google Maps", null),
GoogleMapsFragment.class, null);
mTabHost.addTab(
mTabHost.newTabSpec("tab2").setIndicator("Bookmarks", null),
BookmarksFragment.class, null);
}
#Override
protected void onDestroy() {
super.onDestroy();
/// **** THIS WAS JUST ADDED A LOSS FOR WHAT IT COULD BE RETAINING ****
mTabHost = null;
frameListContainer = null;
bookmarkInfo = null;
}
// access for fragments
public HashMap getBookmarkInfo(){
return bookmarkInfo;
}
public ArrayList getFrameAttributesArrayList(){
return frameListContainer;
}
}
I managed to remove everything from my class but this and still the problem remain:
public class GoogleMapsFragment extends Fragment {
private GoogleMap map;
private SupportMapFragment mapFragment;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_google_maps, container, false);
FragmentManager fm = getChildFragmentManager();
mapFragment = (SupportMapFragment) fm.findFragmentById(R.id.map);
mapFragment.getMapAsync(new OnMapReadyCallback() {
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
initMap();
}
});
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
// frameListContainer = ((GoogleMapsAndBookmarksContainer) this.getActivity()).getFrameAttributesArrayList();
// bookmarkInfo = ((GoogleMapsAndBookmarksContainer) this.getActivity()).getBookmarkInfo();
// markerToFrameAndRoute = new HashMap<Marker, String[]>();
}
#Override
public void onDestroy() {
super.onDestroy();
mapFragment = null;
System.gc();
map = null; // I did add this in an edit, but it was mistakenly taken away when I was cutting it up, sorry
}
}
So, is this solvable? I can't work out what it is that it's retaining. I did notice if I keep going back on Google Maps and off it, it is garbage collecting it, so it's not a memory leak.
edit: have tried map.clear(); still keeps the memory
Just clear map
#Override
public void onDestroy() {
super.onDestroy();
map.clear();
}
One probable solution to this problem may be to use a retained fragment using setRetainInstance(boolean retain). In this process the map fragment wont destroy and recreate itself dumping a lot of memory, instead it will just retain the memory when it is needed, when you switch map fragment back and forth (by pressing back button).
public class RetainMapActivity extends FragmentActivity {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.basic_demo);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
if (savedInstanceState == null) {
// First incarnation of this activity.
mapFragment.setRetainInstance(true);
} else {
// Reincarnated activity. The obtained map is the same map instance in the previous
// activity life cycle. There is no need to reinitialize it.
mMap = mapFragment.getMap();
}
setUpMapIfNeeded();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
private void setUpMapIfNeeded() {
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
Another solution to this may be to use a Otto event bus which is designed to decouple different parts of your application while still allowing them to communicate efficiently.
Hope this Helps!!
I'm using Android Studio and using a map activity my map shows up fine, but the Mylocation button in the activity doesn't show. My google play services are installed. What am I doing wrong?
public class MapsActivity extends FragmentActivity {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
if (mMap != null) {
mMap.setMyLocationEnabled(true);
}
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
You have to add this line in your code, replace your old code for this one :
public class MapsActivity extends FragmentActivity {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
if (mMap != null) {
//edit this
}
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
if (mMap == null) {
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
mMap.setMyLocationEnabled(true);//here's the button
if (mMap != null) {
setUpMap();
}
}
}
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("Marker"));
}
}
Also you have to add this in your manifest
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
If my answer didn't help you, you can follow this tutorial and do what it says step by step :)
Check this for your setUpMapIfNeeded() method:
Android Google Maps setMyLocationEnabled(true)
To enable the location on your Google Maps if the Google Maps is visible on the activity/fragment.
Create an instance of the Google Map:
GoogleMap googleMap;
Inside your main activity that implements LocationListener
Add this line in your code to see the My Location Button:
googleMap.setMyLocationEnabled(true);
Don't forget to add the permissions in the manifest file:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
For more details please refer to this tutorial.
I'm trying to implement Google Map. But i'm getting Inflating error. Can anyone please provide a sample code to implement google map.
Thank you
Here is my code
public class GMap extends FragmentActivity implements LocationListener{
public static GoogleMap mMap;
LocationManager locationManager;
Criteria criteria;
String provider;
Location location;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_gmap);
setUpMapIfNeeded();
}
#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 (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
if (mMap != null) {
setUpMapIfNeeded();
}
}
}
I am trying to get google maps v2 working in my app. I have seen several examples showing how you can open up SupportMapFragment inside an activity. The idea being that your activity will call setContentView(R.layout.map_layout); where map_layout.xml links to the fragment with the lines:
android:name="com.google.android.gms.maps.SupportMapFragment"
xmlns:map="http://schemas.android.com/apk/res-auto"
The "name=" line effectively says that "this layout is to be controlled by a fragment of type 'SupportMapFragment'".
My complication is that I am attempting to get the map to appear in an activity with tabs (implemented with actionbarsherlock). This means that whatever fragment corresponds to a tab selection must implement a TabListener. But SupportMapFragment doesn't. So now presumably I need to create a new fragment like so:
public class MyMapFragmentWithTabListener extends SupportMapFragment implements TabListener
{
But now I have got all confused about how to write the contents of MapFragmentWithTabListener in particular onCreateView... should I be inflating some layout? Surely I can't be inflating exactly the same map_layout.xml from the examples because that already declares that it is controlled by SupportMapFragment, whereas in this implementation it should be controlled by MyMapFragmentWithTabListener - do I need a slightly different xml file to inflate (if so, what should it look like?) - or should I be creating my view programatically?
I've done this in quite a few applications now. Instead of extending SupportMapFragment, you just create your own MapFragment. You can have your own layout, with a MapView view inside of it. The key is to route the lifecycle events of the Fragment to the MapView, and bobs your uncle.
Heres some example code:
MapFragment
package com.example.testapplication;
import java.util.concurrent.TimeUnit;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.maps.MapsInitializer;
public class TestMapFragment extends Fragment {
private MapView mMapView;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.home_fragment, container, false);
mMapView = (MapView) view.findViewById(R.id.mapview);
// inflat and return the layout
mMapView.onCreate(savedInstanceState);
mMapView.onResume();// needed to get the map to display immediately
try {
MapsInitializer.initialize(getActivity());
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
GoogleMap googleMap = mMapView.getMap();
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
return view;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
}
/*
* Using a mapview in a fragment requires you to 'route'
* the lifecycle events of the fragment to the mapview
*/
#Override
public void onResume() {
super.onResume();
if (null != mMapView)
mMapView.onResume();
}
#Override
public void onPause() {
super.onPause();
if (null != mMapView)
mMapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
if (null != mMapView)
mMapView.onDestroy();
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
if (null != mMapView)
mMapView.onSaveInstanceState(outState);
}
#Override
public void onLowMemory() {
super.onLowMemory();
if (null != mMapView)
mMapView.onLowMemory();
}
}
And the layout:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<com.google.android.gms.maps.MapView
android:id="#+id/mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:uiZoomControls="false" />
</RelativeLayout>
You can used this way.
public class NewActivity extends FragmentActivity {
private GoogleMap mMap;
SupportMapFragment mapFragment;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activit);
mapFragment = (SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map);
if(isGooglePlayServicesIsInstalled(mContext)){
mMap = mapFragment.getMap();
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
mMap.getUiSettings().setCompassEnabled(true);
mMap.getUiSettings().setZoomControlsEnabled(true);
}else{
//display any toast message
//Global.Toast("Please First install Google Maps");
}
public static boolean isGooglePlayServicesIsInstalled(Context context){
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(context);
if (resultCode == ConnectionResult.SUCCESS)
return true;
else
return false;
}
Please check it out all the permission,api key and require all the thing.if you getting any error log then put as a comment.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I know the map is ready to get used when using the SupportMapFragment?
I am currently testing the new Maps API V2 but I'm really having trouble getting it to work correclty.
My problem is that getMap() always returns null.
I have tested the call in 3 different points:
onCreate()
onResume()
in a Handler that is called some seconds after the map is already visible on the screen
Here is the code:
public class MapActivity extends FragmentActivity {
private SupportMapFragment mMapFragment;
#Override
protected void onCreate(Bundle arg0) {
super.onCreate(arg0);
setupMap();
}
#Override
protected void onResume() {
super.onResume();
setupMap();
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
setupMap();
}
}, 5000);
}
private void setupMap() {
if (getSupportFragmentManager().findFragmentById(R.id.fragment) == null) {
mMapFragment = CustomMapFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.add(R.id.map_wrapper, mMapFragment).commit();
}
GoogleMap map = mMapFragment.getMap();
if (map != null) {
mMapFragment.getMap().getUiSettings().setZoomControlsEnabled(true);
mMapFragment.getMap().getUiSettings().setZoomGesturesEnabled(true);
mMapFragment.getMap().setMyLocationEnabled(true);
}
}
Anything that I'm doing wrong?
As CommonsWare stated in the linked question, the problem only occures when creating the SupportMapFragment programmatically and not a <fragment> XML tag.
If created programmatically, the map will be available in the onActivityCreated() call. So my workaround is the following:
mMapFragment = new SupportMapFragment() {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
GoogleMap map = mMapFragment.getMap();
if (map != null) {
//Your initialization code goes here
}
}
};