I need a search toolbar on Google Map.
I display the map with the use of MapActivity.
The way I did is via the create project wizard, when you a create a new project, you can choose from basic activity, empty activity, map activity.
I selected MapActivity.
In XML file I had only this:
<resources>
<string name="google_maps_key" templateMergeStrategy="preserve"
translatable="false">AIzaSyCx3iR5fkeWr2LUf6JBHwGLEEkeghL3snk
</string>
</resources>
So what is the way to insert that search toolbar on the map?
Then how to add that search tool bar. If I add a layout then an error it is shown.
The way I would do it is the following:
I would have an activity which has a fragment that contain the map inside.
Inside the activity I would have a method that display the fragment with the map:
public void showMap() {
MapLocationFragment locationFragment = MapLocationFragment.newInstance();
getSupportFragmentManager().beginTransaction()
.replace(R.id.fragment_container, locationFragment)
.addToBackStack(null)
.commit();
}
activity xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<include
android:id="#+id/app_bar_include"
layout="#layout/app_bar_layout_device" />
<FrameLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="?attr/actionBarSize" />
</RelativeLayout>
Now, inside the MapLocationFragment you need to have something like that:
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.maps_layout, container, false);
return view;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initializeMapIfNeeded();
}
private void initializeMapIfNeeded() {
if (googleMap == null) {
loadMapAsync();
}
}
private void loadMapAsync() {
((SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.location_map)).getMapAsync(getOnMapReadyCallback());
}
public OnMapReadyCallback getOnMapReadyCallback() {
return new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap map) {
googleMap = map;
if (googleMap == null) {
return;
}
googleMap.setIndoorEnabled(true);
googleMap.getUiSettings().setMyLocationButtonEnabled(true);
googleMap.setOnMyLocationButtonClickListener(getMapMpOnMyLocationClickListener());
googleMap.setLocationSource(getNewLocationSource());
googleMap.setOnCameraChangeListener(getCameraChangeListener());
//do other stuff too
}
};
}
xml:
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<fragment
android:id="#+id/location_map"
class="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
<android.support.design.widget.FloatingActionButton
android:id="#+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:clickable="true"
android:src="#android:drawable/ic_menu_set_as"
app:layout_anchorGravity="bottom|right|end"
android:layout_gravity="bottom|end"/>
</android.support.design.widget.CoordinatorLayout>
For more details look at this project:
Sunshine app
You can try it.
public class MapsActivity extends FragementActivity implements OnMapReadyCallback,LocationListener in here, Put the AppCompatActivity instead of the FragementActivity.
Related
One activity (MainActivity) calls a fragment(MainPage). The fragment is designed to open a local asset webview file, Map.html. It works as intended, with the exception that the map cannot be moved by fingertip. This function is available when the Map.html is opened a broswer. However, the zoom in zoom out tap button in the top left does work.
Is something overlaying the webview such that it can be seen but not swiped?
The initial AppCompatActivity (to support ActionBar) is given by MainActivity:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
//list of private declarations
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// a lot of other stuff relating to navigation drawer
// calls MainPage Fragment
android.support.v4.app.Fragment fragment = new MainPage();
FragmentManager fragmentManager = getSupportFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.content_frame, fragment)
.addToBackStack("tag")
.commit();
}
}
where the xml for this is given as:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_centerVertical="true"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<android.support.v4.widget.DrawerLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<WebView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/content_frame">
</WebView>
<ListView
android:id="#+id/left_drawer"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:choiceMode="singleChoice"
android:divider="#android:color/transparent"
android:dividerHeight="0dp"
android:background="#111">
</ListView>
</android.support.v4.widget.DrawerLayout>
</LinearLayout>
Eventually calls MainPage, given as:
public class MainPage extends android.support.v4.app.Fragment implements GeolocationPermissions.Callback {
public MainPage() {
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.activity_main, container, false);
WebView webview = (WebView) rootView.findViewById(R.id.content_frame);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
webview.getSettings().setGeolocationEnabled(true);
GeoClient geo = new GeoClient();
webview.setWebChromeClient(geo);
String origin = "";
geo.onGeolocationPermissionsShowPrompt(origin, this);
webview.loadUrl("file:///android_asset/Map.html");
return rootView;
}
You may need to set an onclicklistener. For Google Maps, this is how I did it. Its probably similar.
Add the implements, #override function, and set the onclick listener. I'm not sure if this will work since you are using HTML at some point.
public class MainActivity extends FragmentActivity implements View.OnClickListener,
GoogleMap.OnMapClickListener {
Then when you initiate it set the onmap click listener.
gMap.setOnMapClickListener(this);// add the listener for click on gmap object
Finally, add this #override:
#Override
public void onMapClick(LatLng point) {
//What code if any happens when user clicks on map
}
I am trying to setup a Google Map in a fragment and am running into some issues trying to get the buttons to listen properly. I have the following code:
public DefaultMap extends android,.support.v4.app.Fragment implements OnMapReadyCallback {
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.map_fragment, container, false);
MapsInitializer.initialize(getActivity());
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mMapFragment = new SupportMapFragment() {
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mMap = mMapFragment.getMap();
if (mMap != null) {
}
}
};
mMapFragment.getMapAsync(this);
// mAutocompleteView = (AutoCompleteTextView) findViewById(R.id.TFSearch);
// mAutocompleteView.setAdapter(new PlaceAutocompleteAdapter(this, android.R.layout.simple_dropdown_item_1line));
searchSetup(v);
zoomSetup(v);
setupMapType(v);
return v;
}
//an example of one of the setup functions
public void setupMapType(View view) {
typeMapButton = (Button) view.findViewById(R.id.TFtype);
typeMapButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mMap.getMapType() == GoogleMap.MAP_TYPE_NORMAL) {
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
} else {
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
}
}
});
}
}
relevant pieces of map_fragment.xml:
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<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/mapScreen"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
tools:context=".DefaultMap"
android:name="com.google.android.gms.maps.SupportMapFragment"
/>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/map_type"
android:id="#+id/TFtype"
android:onClick="onTypeMap"
tools:context=".DefaultMap"
android:layout_marginRight="5dp" />
</LinearLayout>
</LinearLayout>
</FrameLayout>
And I am receiving the following error when clicking the buttons (same for all 4 buttons):
11-15 22:57:22.481 32523-32523/oose2017.place2b E/AndroidRuntime: java.lang.NullPointerException: Attempt to invoke virtual method 'int com.google.android.gms.maps.GoogleMap.getMapType()' on a null object reference
11-15 22:57:22.481 32523-32523/myproject E/AndroidRuntime: at myproject.interfaces.map.DefaultMap$5.onClick(DefaultMap.java:153)
Does anybody have any idea how I can fix these issues?
Use SupportMapFragment.newInstance() for getting new instance of SupportMapFragment for adding it from Fragment and also remove android:name="com.google.android.gms.maps.SupportMapFragment" from xml of DefaultMap Fragment.
See following tutorial for more information :
SupportMapFragment problem when loding in Fragment class
I need to add a map dynamically into the app to my MainActivity, otherwise I somehow suffer on memory leaks. Adding the map basically works, but I can't add markers. They just don't appear. That's how I add the map:
activity_main.xml which is used by the MainActivity
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<!-- Placeholder for all fragments -->
<RelativeLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
</RelativeLayout>
<!-- Slider menu -->
<LinearLayout
android:id="#+id/list_container"
android:layout_width="240dp"
android:layout_height="match_parent"
android:layout_gravity="start"
android:background="#fff"
android:orientation="vertical" >
<!-- more code -->
</LinearLayout>
</android.support.v4.widget.DrawerLayout>
fragment_map.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center" >
<fragment
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/fragment_googlemap"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.androidmapsextensions.SupportMapFragment"
map:cameraTargetLat="48.21167860510698"
map:cameraTargetLng="16.365892895859423"
map:cameraZoom="11"
map:uiCompass="true"
map:uiRotateGestures="true"
map:uiScrollGestures="true"
map:uiTiltGestures="true"
map:uiZoomControls="true"
map:uiZoomGestures="true" />
</FrameLayout>
MapFragment.java
public class MapFragment extends com.androidmapsextensions.SupportMapFragment
{
private static final String TAG = MapFragment.class.getSimpleName();
private OnFragmentLoadedCompleteListener onFragmentLoadedCompleteListener;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle args)
{
super.onCreateView(inflater, container, args);
Logger.log(TAG, "onCreateView()", LogController.isLoggingEnabled(), Log.DEBUG);
return inflater.inflate(R.layout.fragment_map, container, false);
}
#Override
public void onActivityCreated(Bundle savedInstanceState)
{
super.onActivityCreated(savedInstanceState);
Logger.log(TAG, "onActivityCreated()", LogController.isLoggingEnabled(), Log.DEBUG);
onFragmentLoadedCompleteListener.onFragmentComplete();
}
#Override
public void onAttach(Activity activity)
{
super.onAttach(activity);
Logger.log(TAG, "onAttach()", LogController.isLoggingEnabled(), Log.DEBUG);
onFragmentLoadedCompleteListener = (OnFragmentLoadedCompleteListener)activity;
}
}
Important parts of MainActivity.java
#Override
public void onFragmentComplete()
{
googleMap = ((SupportMapFragment)getSupportFragmentManager().findFragmentByTag("mapFragment")).getExtendedMap();
}
private void initMapFragment()
{
if (googleMap != null)
{
googleMap.clear();
googleMap = null;
}
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, new MapFragment(), "mapFragment").commit();
}
OnFragmentLoadedCompleteListener.java
public interface OnFragmentLoadedCompleteListener
{
public void onFragmentComplete();
}
onFragmentComplete() is executed, googleMap is not null and shown. But I can't draw markers on it. They just don't appear.
But when I don't dynamically add the map and embed it into the activity_main.xml within the RelativeLayout like this
<RelativeLayout
android:id="#+id/fragment_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
<fragment
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/fragment_googlemap"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.androidmapsextensions.SupportMapFragment"
map:cameraTargetLat="48.21167860510698"
map:cameraTargetLng="16.365892895859423"
map:cameraZoom="11"
map:uiCompass="true"
map:uiRotateGestures="true"
map:uiScrollGestures="true"
map:uiTiltGestures="true"
map:uiZoomControls="true"
map:uiZoomGestures="true" />
</RelativeLayout>
and fetch the map like this without the listener, I can draw markers, that means they appear.
googleMap = ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.fragment_googlemap)).getExtendedMap();
That means drawing markers on the map only works when I directly embed the map into the xml of the MainActivity instead of added it dynamically as fragment. What's going on here. Where is the error?
As is often the case I found the solution on my own.
I have to keep a reference to my MapFragment I use to replace:
mapFragment = new MapFragment();
getSupportFragmentManager().beginTransaction().replace(R.id.fragment_container, mapFragment).commit();
In onFragmentComplete() I have to invoke getChildFragmentManager() on this reference to obtain the "correct" GoogleMap.
googleMap = ((SupportMapFragment)mapFragment.getChildFragmentManager().findFragmentById(R.id.fragment_googlemap)).getExtendedMap();
This time it can be found by id as well (didn't work before), and drawing markers on this map works now.
I have an activity that hosts two fragments. One fragment provides some info to the user in various fields. The other fragment should show a Map.
For the fragment hosting the map I need to be able to add custom logic for displaying markers and several other things that I would like to reuse in other places in the app. What is the best way to create a map without defining the fragment in xml like:
<fragment
class="com.google.android.gms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
Thanks,
Nathan
Edit:
I am now using nested fragments, not sure if that is the best way to handle this? My mapfragment is now:
<?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
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.MapFragment" />
</LinearLayout>
and the Fragments code is:
public class ViewCurrentMapFragment extends Fragment implements View.OnClickListener {
public static final String TAG = "MAP_FRAGMENT";
private GoogleMap map;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_view_current_map, container, false);
return rootView;
}
private void getCurrentMarkers() {
// Getting reference to the SupportMapFragment of activity_main.xml
SupportMapFragment smf = ((SupportMapFragment) getActivity().getSupportFragmentManager().findFragmentById(R.id.map));
map = smf.getMap();
}
#Override
public void onClick(View v) {
}
#Override
public void onResume() {
super.onResume();
getCurrentMarkers();
}
}
The problem I am having now is that smf.getMap() is returning null. Any ideas?
Edit2:
Got it to work by changing:
com.google.android.gms.maps.MapFragment
to
com.google.android.gms.maps.SupportMapFragment
Maybe:
<fragment
class="com.mycompany.MyCustomFragmentExtendingMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
or nest fragments like here: http://code.google.com/p/gmaps-api-issues/issues/detail?id=5064#c1
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>