I'm trying to make an application that allows to open new activity from a marker on the map with the method GoogleMap.OnMarkerClickListener but do not know how to use it. Does anyone help me?
Just use this:
getMap().setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
public void onInfoWindowClick(Marker marker) {
Intent i = new Intent(getActivity(), NewActivity.class);
startActivity(i);
}
});
I used this code in my custom class that extends MapFragment
I've placed it in this method:
#Override
public void onActivityCreated(Bundle savedInstanceState) {
}
When touching Info window within a marker, if changing the current screen into another screen(class or Activity), Do this below;
private GoogleMap mMap:
.....
protected void onCreate(Bundle savedInstanceState) {
.....
private void setUpMap() {
.....
mMap.setOnInfoWindowClickListener(this);
#Override
public void onInfoWindowClick(Marker marker) {
// When touch InfoWindow on the market, display another screen.
Intent intent = new Intent(this, Another.class);
startActivity(intent);
}
Related
I want to call an activity from my mapfragment with a floating button and it doesn't work, the app keep crashing.
MapsActivity.java
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
String json_string; //ici seront stockées les information concernant les établissements
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
public void getBar(View view){
Log.v("myTag","button Clicked");
Intent intent = new Intent(this, DisplayFilter.class);
startActivity(intent);
}
}
DisplayFilter.java
public class DisplayFilter extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.filtreview);
Log.v("myTag","vue affichée");
}
}
The logcat show this
the log
It talks about the android manifest but I don't think I should edit it right ?
I'm guessing your problem comes from this code
public void getBar(View view){
Log.v("myTag","button Clicked");
Intent intent = new Intent(this, DisplayFilter.class);
//Intent intent = new Intent(getActivity(), DisplayFilter.class);
startActivity(intent);
}
The thing is that you are in a Fragment so you can not pass this, you have to use getActivity() instead.
You need a context somehow, so you can also call view.getContext()
Whenever you want to create an Activity do these steps :
Picture is taken from : this answer
And your Manifest should look like :
<application
....
<activity1></activity1>
<activity
android:name=". DisplayFilter" />
...
</application>
As of this morning I've tried to put together enough knowledge to produce a very basic app to demonstrate a concept. The idea is to display google maps, the user presses on where they want to add a marker, then a screen pops up where they can fill out more information that is then displayed when someone taps that marker.
This is what I got from the Android Studio base.
public class MapsActivity extends FragmentActivity implements
OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
private void setMapLongClick(final GoogleMap map) {
map.setOnMapLongClickListener(new GoogleMap.OnMapLongClickListener() {
#Override
public void onMapLongClick(LatLng latLng) {
}
});
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.z
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Move the camera to Delft
LatLng delft = new LatLng(52.003569, 4.372987);
Float zoom = 15f;
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(delft, zoom));
setMapLongClick(mMap);
}
}
I tried adding this
private void setMarkerClick(final GoogleMap map) {
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
Intent intent = new Intent(this, MainActivity.class);
this.startActivity(intent);
});
}
But I get and "illegal start of type" error. Am I doing this completely wrong?
Is there an easier way to add information to a marker?
This is how you should use it.
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
Intent intent = new Intent(MainActivity.this, MainActivity.class);
startActivity(intent);
return true;
}
});
Providing this as first argument when creating the Intent might not work since it refers to the OnMarkerClickListener anonymous class and not to the packageContext. Here's my suggestion, give MapsActivity.this as reference:
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(Marker marker) {
Intent intent = new Intent(MapsActivity.this, MainActivity.class);
startActivity(intent);
return true;
}
});
You cannot call
this.startActivity(intent);
inside an anonymous class as startActivity is not a method of the anonymous class but of the enclosing activity. Therefore you should use
startActivity(intent);
Also use the proper anonymous implementation.
So I have a list of locations (inside a ListFragment) and their corresponding coordinates and I want to start a new map activity when one of them is pressed.
public void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(getActivity(), "Item: " + locations[position], Toast.LENGTH_SHORT).show();
Intent eventActivity = new Intent(getContext(), MapsActivity.class);
startActivity(eventActivity);
}
Currently I have it so that when one of the items is clicked, it displays the name of the location, then opens a map to (0,0) within the app. How can I open the map to the coordinates that corresponds to the location (which I have)?
Thanks to Ajeet Choudhary. Solved. Solution below.
MapFragment.java
public class MapFragment extends ListFragment{
...
LatLng[] coordinates = new LatLng[] {
new LatLng(..., ...),
new LatLng(..., ...),
new LatLng(..., ...),
...
};
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
ArrayAdapter<String> adapter = new MapAdapter(getActivity(), locations);
setListAdapter(adapter);
}
#Override
public void onListItemClick(ListView l, View v, int position, long id) {
Toast.makeText(getActivity(), "Item: " + locations[position], Toast.LENGTH_SHORT).show();
Intent eventActivity = new Intent(getContext(), MapsActivity.class);
eventActivity.putExtra("latlng", coordinates[position]);
startActivity(eventActivity);
}
}
MapsActivity.java
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker and move the camera.
LatLng location = getIntent().getExtras().getParcelable("latlng");
mMap.addMarker(new MarkerOptions().position(location).title("Marker"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(location));
}
}
As Latlng already have implemnted Parcable class, so put that into intent and send to your Map activity,get That Latlng from getIntent().getParcableExtra("your_key"), then there will be methods onMapReady(GoogleMap googleMap)(if you have implemented map there already) add your latlng to the Map ,see this answer for help.
I am using retrofit to fetch data online.However I cannot find any solution to my problem. I want to call another fragment and display more of the details about the marker I clicked and pass those values to another fragment. Can someone please help me on this. Any help and solutions are well appreciated.
MapFragment.jav
RestAdapter adapter = new RestAdapter.Builder()
.setEndpoint(getString(R.string.fine_dinings))
.build();
RestaurantPlacesApiInterface restaurantPlacesApiInterface =
adapter.create(RestaurantPlacesApiInterface.class);
restaurantPlacesApiInterface.getStreams(new Callback<List<RestaurantPlaces>>() {
#Override
public void success(List<RestaurantPlaces> restaurantPlaces, Response response) {
for (RestaurantPlaces restaurantPlace : restaurantPlaces){
MarkerOptions options = new MarkerOptions().position(new LatLng(restaurantPlace.getLatitude(),
restaurantPlace.getLongitude()));
options.title(restaurantPlace.getName());
options.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_GREEN));
getMap().addMarker(options);
}
}
#Override
public void failure(RetrofitError error) {
}
});
}
You need to use this:
#Override
public boolean onMarkerClick(Marker marker) {
// call fragment and pass data.
return false;
}
If you return false the click is not consumed.
If you need help implementing this let me know, it's fairly simple.
Here is a quick sample, please change the names to match your own code:
public class MapActivity implements OnMapReadyCallback, GoogleMap.OnMarkerClickListener {
private GoogleMap mGoogleMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
initMap();
}
public void initMap() {
MapFragment map = (MapFragment) getFragmentManager().findFragmentById(R.id.mapFragment);
map.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
try {
if (googleMap != null) {
mGoogleMap = googleMap;
mGoogleMap.setOnMarkerClickListener(this);
mGoogleMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
// Now make your retrofit call
}
} catch (Exception e) {
e.printStackTrace();
Log.e("ERROR", "GOOGLE MAPS NOT LOADED");
}
}
#Override
public boolean onMarkerClick(Marker marker) {
Bundle bundle = new Bundle();
bundle.putString("myString", "value");
// set Fragment class Arguments
MyFragment myFragment= new MyFragment();
myFragment.setArguments(bundle);
// launch fragment
return false;
}
}
better to use interface in fragment and implement that interface in (activity where RestAdapter used)
I have a GridMarkerClusterer with some Marker in it representing shared bike stations. I want those markers have a custom MarkerInfoWindow (bubble) with a click listener so that when the user clicks on the bubble, a new intent is launched.
Thus far, I'm OK.
Now I want to put extra data (station information corresponding to the marker) to that intent.
What I actually did is to add a constructor in my StationMarkerInfoWindow which takes a Station in parameter. I then add this parameter to the intent with putExtra() in my OnClickListener.
That's working but what is wrong is that I need to create a new StationMarkerInfoWindow for each marker instead of using the same object, and if I have more than 1000 markers to display, the activity takes up to 10 seconds to be created on my device (~1 second if I use the same StationMarkerInfoWindow object for each marker).
The question is: how should I add those data to the intent?
Here are the relevant parts of the code:
public class MapActivity extends Activity {
private BikeNetwork bikeNetwork;
private ArrayList<Station> stations;
private MapView map;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_map);
// ...
stations = bikeNetwork.getStations();
map = (MapView) findViewById(R.id.mapView);
GridMarkerClusterer stationsMarkers = new GridMarkerClusterer(this);
Drawable clusterIconD = getResources().getDrawable(R.drawable.marker_cluster);
Bitmap clusterIcon = ((BitmapDrawable) clusterIconD).getBitmap();
map.getOverlays().add(stationsMarkers);
stationsMarkers.setIcon(clusterIcon);
stationsMarkers.setGridSize(100);
for (final Station station : stations) {
stationsMarkers.add(createStationMarker(station));
}
// ...
}
private Marker createStationMarker(Station station) {
Marker marker = new Marker(map);
marker.setInfoWindow(new StationMarkerInfoWindow(
R.layout.bonuspack_bubble, map, station)); // this seems wrong
marker.setInfoWindow(stationMarkerInfoWindow);
marker.setPosition(stationLocation);
marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER);
marker.setIcon(getResources().getDrawable(R.drawable.ic_bike));
marker.setTitle(station.getName());
marker.setSnippet(String.valueOf(station.getFreeBikes())); // free bikes
marker.setSubDescription(String.valueOf(station.getEmptySlots())); // empty slots
return marker;
}
private class StationMarkerInfoWindow extends MarkerInfoWindow {
Station station;
public StationMarkerInfoWindow(int layoutResId, final MapView mapView, final Station station) {
super(layoutResId, mapView);
this.station = station;
}
#Override
public void onOpen(Object item) {
super.onOpen(item);
closeAllInfoWindowsOn(map);
LinearLayout layout = (LinearLayout) getView().findViewById(R.id.map_bubble_layout);
layout.setClickable(true);
layout.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(MapActivity.this, StationActivity.class);
intent.putExtra("station", station);
startActivity(intent);
}
});
}
}
}
I would suggest to set the Station as the "related object" of its Marker:
marker.setRelatedObject(station);
You can then retrieve this related object in StationMarkerInfoWindow#onOpen:
Marker marker = (Marker)item;
selectedStation = (Station)marker.getRelatedObject();
Similar implementation can be found here.
Then you can share the same StationMarkerInfoWindow.