I am using MapView inside a RecycleView in android.
here is my xml code:
<com.google.android.gms.maps.MapView
android:id="#+id/map_view"
android:layout_width="match_parent"
android:layout_height="match_parent">
and:
private fun initializeMap() {
val mapView : MapView = binding.root.findViewById(R.id.map_view)
mapView?.let {
mapView.onCreate(null)
mapView.getMapAsync(this)
}
}
override fun onMapReady(map: GoogleMap?) {
MapsInitializer.initialize(fragment.context)
googleMap = map
googleMap?.let {
it.setOnMapLoadedCallback { this }
it.setOnMapClickListener { this }
it.uiSettings.setAllGesturesEnabled(false)
it.uiSettings.isZoomControlsEnabled = false
}
}
override fun onMapLoaded() {
}
override fun onMapClick(p0: LatLng?) {
}
the map that appear is like following
and it takes a lot of time tp appear and also does not appear direct, I scroll a lot
also the methods onMapLoaded() and onMapClick() does not call
As you set it.uiSettings.setAllGesturesEnabled(false) and it.uiSettings.isZoomControlsEnabled = false use MapView in Lite Mode:
<com.google.android.gms.maps.MapView
android:id="#+id/map_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraZoom="<ZOOM>"
map:mapType="normal"
map:liteMode="true">
Here you can find Official example of using MapView inside RecyclerView and here MapView layout settings:
<!-- MapView in lite mode. Note that it needs to be initialised
programmatically before it can be used. -->
<com.google.android.gms.maps.MapView
android:id="#+id/lite_listrow_map"
android:layout_width="match_parent"
android:layout_height="150dp"
map:liteMode="true" map:mapType="none" />
this my map.xml file
<com.google.android.gms.maps.MapView android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:android="http://schemas.android.com/apk/res/android" />
And this is java class
public class map extends Fragment implements OnMapReadyCallback {
GoogleMap mMap;
private MapView mapView;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
return inflater.inflate(R.layout.map,null);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng ahmedabad = new LatLng(23.022505, 72.571365);
BitmapDescriptor icon = BitmapDescriptorFactory.fromResource(R.drawable.icons8fiat50060);
MarkerOptions markerOptions = new MarkerOptions().position(ahmedabad)
.title("Current Location")
.snippet("Thinking of finding some thing...")
.icon(icon);
googleMap.addMarker(markerOptions);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(ahmedabad,30f));
}
}
this is quite easy i think this will helpful for you.
Related
I'm trying to add a googlemap into my app, but I couldn't get it to work.
I'm working with ViewPager on xamarin btw.
Layout:
...
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.google.android.gms.maps.MapFragment" />
...
My fragment:
public class InfoFragment : FragmentV4, IOnMapReadyCallback
{
private GoogleMap mMap;
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
var view = inflater.Inflate(Resource.Layout.InfoFragment, container, false);
//Set up google maps coords in infos section
SetUpMap();
return view;
}
private void SetUpMap()
{
if (mMap == null) {
//((MapFragment)FragmentManager.FindFragmentById (Resource.Id.map)).GetMapAsync (this);
var mapFragment = (SupportMapFragment)Activity.SupportFragmentManager.FindFragmentById(Resource.Id.map);
mapFragment.GetMapAsync(this);
}
}
//Launching of the actual map
public void OnMapReady (GoogleMap googleMap)
{
//Setup cords and stuff...
}
}
During the setup of my map. When i do
var mapFragment = (SupportMapFragment)Activity.SupportFragmentManager.FindFragmentById(Resource.Id.map);
it always returns null. can someone help?
found the problem
android:name="com.google.android.gms.maps.MapFragment" />
should be:
android:name="com.google.android.gms.maps.SupportMapFragment" />
and in my fragment instead of:
var mapFragment = (SupportMapFragment)Activity.SupportFragmentManager.FindFragmentById(Resource.Id.map);
mapFragment.GetMapAsync(this);
it should be:
((SupportMapFragment)ChildFragmentManager.FindFragmentById(Resource.Id.map)).GetMapAsync(this);
When starting a new map activity the map loads really slow and doesn't start the loading until clicking the screen.
The Layout is the following:
<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" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.android.momintuition.DirectionsActivity">
<com.google.android.gms.maps.MapView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/mapView"
android:paddingTop="62px"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:clickable="true"
map:uiCompass="true"
map:zOrderOnTop="true"
map:uiZoomControls="true"
android:background="#00000000" />
</RelativeLayout>
The new activity looks like this:
public class DirectionsActivity extends AppCompatActivity implements OnMapReadyCallback {
GoogleMap mMap; // Might be null if Google Play services APK is not available.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_directions);
MapView mv = (MapView) findViewById(R.id.mapView);
mv.onCreate(savedInstanceState);
mMap = mv.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
this.map = googleMap;
CameraUpdate cameraUpdate =
CameraUpdateFactory.newLatLngZoom(new LatLng(43.1, -87.9), 10);
map.animateCamera(cameraUpdate);
}
}
I am new to Android. Am I missing something? Thank you!
The problem in this case was that I didn't implement the following methods(even if it was specified in the documentation):
#Override
public void onResume() {
mapView.onResume();
super.onResume();
}
#Override
public void onPause() {
super.onPause();
mapView.onPause();
}
#Override
public void onDestroy() {
super.onDestroy();
mapView.onDestroy();
}
#Override
public void onLowMemory() {
super.onLowMemory();
mapView.onLowMemory();
}
It is counterintuitive to me why this methods might affect showing the map but it does fix the problem.
TL;DR These lines made my map load.
itemMap.onResume();
mapView.onEnterAmbient(null);
For people having the same problem:
I'm using maps inside a RecyclerView, and I was having the same problem, so I implemented racula's answer by having an ArrayList of type MapView, and I would add the mapView to the list when it was initialized.
And in the Activity Lifecycle methods I would get the mapViewList from the adapter, and call the appropriate method. And now the map was loading when I resumed the application.
//In the Activity
#Override
protected void onResume() {
super.onResume();
for(MapView mapView : adapter.getMapViewList()){
if (mapView != null){
mapView.onResume();
}
}
}
So finally I tested a few things, and added the "itemMap.onResume();" and the "mapView.onEnterAmbient(null);" methods, and the map started loading and working just fine.
Here's a simple version of my Adapter class
//RecyclerView Adapter and inside it the ViewHolder
class ReminderAdapter extends RecyclerView.Adapter<ReminderAdapter.MyViewHolder> {
private ArrayList<MapView> mapViewList;
#Override
public RecyclerViewAdapter.MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_layout, parent, false);
return new MyViewHolder(itemView);
}
#Override
public void onBindViewHolder(final ReminderAdapter.MyViewHolder holder, int position) {
(...)
holder.initializeMapView(new LatLng(getLat(), getLng()));
}
ArrayList<MapView> getMapViewList(){
return mapViewList;
}
(...)
class MyViewHolder extends RecyclerView.ViewHolder implements OnMapReadyCallback{
#Override
public void onMapReady(GoogleMap googleMap) {
MapsInitializer.initialize(context);
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15f));
googleMap.addMarker(new MarkerOptions().position(latLng));
this.googleMap = googleMap;
itemMap.onResume(); //The methods
itemMap.onEnterAmbient(null); // that made my map work
}
void initializeMapView(LatLng latLng){
if(itemMap != null){
this.latLng = latLng;
itemMap.onCreate(bundle);
itemMap.getMapAsync(this);
mapViewList.add(itemMap); // adds the MapView to the list
}
}
}
}
Started working with Android Studio, trying to display a Google Map in a fragment. The maps displays fine and I'm able to zoom/move the map around, but my markers will not display.
Here is my MapsActivity (HomePageMapsActivity.java):
public class HomePageMapsActivity extends FragmentActivity {
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page_maps);
setUpMapIfNeeded();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
}
/**
* Sets up the map if it is possible to do so, and the map has not already been instantiated.
* If not installed {#link SupportMapFragment} (and
* {#link com.google.android.gms.maps.MapView MapView}) will prompt user to
* install/update the Google Play services APK on their device.
*/
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();
}
}
}
/**
* This is where we can add markers, lines, listeners, or move the camera.
* Only call once and when sure {#link #mMap} is not null.
*/
private void setUpMap() {
mMap.addMarker(new MarkerOptions().position(new LatLng(33, -84)).title("Atlanta"));
}
}
The xml (activity_home_page_maps.xml):
<?xml version="1.0" encoding="utf-8"?>
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
tools:context="net.datanetics.campusresponseapp.HomePageMapsActivity" />
The home page xml (activity_home_page):
<LinearLayout
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"
android:orientation="vertical"
android:gravity="center">
<fragment
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/HomePageMap"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="9"
tools:context=".HomePageMapsActivity"
class="com.google.android.gms.maps.SupportMapFragment" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:orientation="horizontal"
android:weightSum="1" >
<Button
android:id="#+id/MenuButton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:background="#3498DB"
android:text="Menu"
android:textColor="#FFFFFF" />
<Button
android:id="#+id/EmergencyButton"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.5"
android:background="#C1392B"
android:text="Emergency"
android:textColor="#FFFFFF" />
</LinearLayout>
Are you sure, your GoogleMap is not null? Try to get map asynchronously:
public class YourActivity extends AppCompatActivity implements OnMapReadyCallback {
private GoogleMap mMap;
SupportMapFragment fragMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_page_maps);
fragMap = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
fragMap.getMapAsync(this);
}
#Override
public void onMapReady(final GoogleMap map) {
if (map != null) {
mMap = map;
setUpMap();
}
}
}
Two things:
1) You are trying to use the map too early. You need to have the view
first, so your code should be in onCreateView() not onCreate().
Correction: onCreateView() applies to fragments, not activities.
The app I used to test this used a Fragment to hold the map, not a
FragmentActivity.
2) I found I needed to prod the initialization of the map layers by
calling mMapView.onCreate() and mMapView.onResume() explicitly. See
also JoelLipman.com.
public class HomePageMaps extends SupportMapFragment {
private View mView;
private View mMapView;
private GoogleMap mMap;
#Override public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle state) {
super.onCreateView(inflater, group, state);
mView = inflater.inflate(R.layout.activity_home_page_maps, group, false);
mMapView= (MapView)mView.findViewById(R.id.map);
mMapView.onCreate(state);
mMapView.onResume();
mMap= mMapView.getMap();
mapUpdate();
return (mView);
}
private void mapUpdate() {
LatLng myLoc= new LatLng(33,-84);
MarkerOptions opt = new MarkerOptions();
mMap.clear();
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(myLoc, 15));
mMap.addMarker(opt.position(myLoc).title("Me"));
}
}
I got your issue change this line
mMap.addMarker(new MarkerOptions().position(new LatLng(33, -84)).title("Atlanta"));
to
mMap.addMarker(new MarkerOptions().position(new LatLng(33.7550,84.3900)).title("Atlanta"));
you have to pass the double value in lat and lng.
I found my "FirstMap" project, hope it helps. You will want to
move your map into a fragment sooner rather than later.
MapsActivity.java
public class MapsActivity extends FragmentActivity {
private PageMap mPageMap;
public interface IAction {
boolean onClick(int BtnID);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mPageMap= new PageMap();
setContentView(R.layout.activity_main);
}
public void onClick(View Ctrl) {
int BtnID= Ctrl.getId();
switch(BtnID) {
case R.id.MainBtn_Map: ShowMap(); break;
default: mPageMap.onClick(BtnID);
}
}
private void ShowMap() {
LoadPage(mPageMap);
}
public void LoadPage(Fragment NewPage) {
FragmentManager Mgr= getSupportFragmentManager();
FragmentTransaction Action= Mgr.beginTransaction();
Action.replace(R.id.Main_FragmentContainer,NewPage);
Action.show(NewPage);
Action.commit();
}
}
res/layout/activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<Button
android:id="#+id/MainBtn_Map"
android:onClick="onClick"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_margin="20dp"
android:text="Load Map"
/>
<LinearLayout
android:id="#+id/Main_FragmentContainer"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
android:background="#color/material_blue_grey_800"
>
</LinearLayout>
</LinearLayout>
PageMap.java
public class PageMap extends SupportMapFragment implements MapsActivity.IAction {
private FragmentActivity mActivity;
private MapView mMapView;
private GoogleMap mMap;
#Override public void onAttach(Activity parent) {
mActivity= (FragmentActivity)parent;
super.onAttach(parent);
}
#Override public View onCreateView(LayoutInflater inflater, ViewGroup group, Bundle instance) {
super.onCreateView(inflater,group,instance);
View view= inflater.inflate(R.layout.page_map,group,false);
mMapView= (MapView)view.findViewById(R.id.map);
mMapView.onCreate(instance);
mMapView.onResume();
mMap= mMapView.getMap();
return(view);
}
public boolean onClick(int BtnID) {
switch(BtnID) {
case R.id.PageMap_BtnUpdate: return (Update());
}
return (false);
}
private boolean Update() {
setUpMap();
return(true);
}
private void setUpMap() {
if(mMap!=null) {
LatLng loc = new LatLng(-34, 151);
mMap.addMarker(new MarkerOptions().position(loc).title("Marker"));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(loc, 15));
}
}
}
//EOF: PAGEMAP.JAVA
res/layout/page_map.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
>
<Button
android:id="#+id/PageMap_BtnUpdate"
android:onClick="onClick"
android:text="Update"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<com.google.android.gms.maps.MapView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
/>
</LinearLayout>
I have a Google Maps mapView in a ScrollView. it works fine, except when Scrolling I get some ugly black backgrounds along the bottom and top.
Here's a video of the issue:
https://www.youtube.com/watch?v=wLla7nS6Ehc&feature=youtu.be
To fix this, I wrapped the Map in a FrameLayout and made it bigger than the actual container, this fixes the issue, except now I can't see the Google watermark anymore. I tried using a bottom padding, but with the padding the black pattern shows up again, but this time only at the bottom.
Is it okay to put a TextView in the FrameLayout with the font and style of the Google Maps watermark as a work around? Am I violating the TOS if I do this?
This is the xml for my fix:
<FrameLayout
android:id="#+id/map_view_container"
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_below="#+id/location"
android:layout_centerHorizontal="true"
android:layout_marginTop="#dimen/full_margin"
android:background="#color/transparent">
<com.google.android.gms.maps.MapView
android:id="#+id/map_view"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_gravity="center"
android:background="#color/off_white"
map:mapType="normal" />
<View
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/transparent" />
</FrameLayout>
EDIT: Fragment code:
public class MapFragment extends Fragment
implements View.OnClickListener,
com.google.android.gms.maps.OnMapReadyCallback {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_business_home, container, false);
final Bundle mapViewSavedInstanceState = savedInstanceState != null ? savedInstanceState.getBundle("mapViewSaveState") : null;
initializeViewComponents(rootView, mapViewSavedInstanceState);
return rootView;
}
private void initializeViewComponents(View rootView, Bundle savedInstanceState) {
scrollView = (ScrollView) rootView.findViewById(R.id.scroll_view);
mapView = (MapView) rootView.findViewById(R.id.map_view);
mapView.onCreate(savedInstanceState);
mapView.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
MapsInitializer.initialize(this.getActivity());
this.map = googleMap;
// Gets to GoogleMap from the MapView and does initialization stuff
map.getUiSettings().setMyLocationButtonEnabled(true);
map.getUiSettings().setAllGesturesEnabled(false);
map.setMyLocationEnabled(true);
onAsyncLoad();
}
#Override
public void onResume() {
if (mapView != null) {
mapView.onResume();
}
super.onResume();
}
#Override
public void onLowMemory() {
if (mapView != null) {
mapView.onLowMemory();
}
super.onLowMemory();
}
public void onSaveInstanceState(Bundle outState) {
Log.i(TAG, "SAVING TO INSTANCE STATE");
//This MUST be done before saving any base class variables
final Bundle mapViewSaveState = new Bundle(outState);
if (mapView != null) { // May be null after onDestroView
mapView.onSaveInstanceState(mapViewSaveState);
outState.putBundle("mapViewSaveState", mapViewSaveState);
}
}
I allready read a lot topics about this problem but nothing helped.
So I want to operate on a GoogleMap in a SupportMapFragment. In the FragmentActivity I initialized the map in the onCreate Method
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_frame);
// Initialize Google Maps Android API
try {
MapsInitializer.initialize(this);
} catch (GooglePlayServicesNotAvailableException e) {
e.printStackTrace();
}
...
the Code of my MapFragment looks exactly like this
public class MapFragment extends SupportMapFragment {
private final String TAG = getClass().getSimpleName();
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
return inflater.inflate(R.layout.map, null);
}
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
#Override
public void onViewCreated(View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
GoogleMap gMap = this.getMap();
Log.d(TAG,
"getMap() " + ((gMap == null) ? "null" : gMap.toString()));
// Setting Location and Zoom
gMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(
40.76793169992044f, -73.98180484771729f), 14.0f));
}
}
Every time I am getting null with the getMap Method... any ideas?
€dit:
<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
class="com.google.android.gms.maps.SupportMapFragment"
map:cameraBearing="112.5"
map:cameraTargetLat="-33.796923"
map:cameraTargetLng="150.922433"
map:cameraTilt="30"
map:cameraZoom="50"
map:mapType="normal"
map:uiCompass="false"
map:uiRotateGestures="true"
map:uiScrollGestures="false"
map:uiTiltGestures="true"
map:uiZoomControls="false"
map:uiZoomGestures="true" />
faced with similiar issue, after updating google play services to the latest version.
my problem was resolved by adding metadata in manifest
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
https://developers.google.com/maps/documentation/android/start#add_a_map