Please I need help in creating a similar interface like field trip app, I have a list of cards in a horizontal RecyclerView. I want to connect each marker on the map with its card, and when a marker is clicked the card connected to it moves upper than others with a bottom margin 20. How can I achieve this?
Override
public boolean onMarkerClick(Marker marker) {
// TODO Auto-generated method stub
marker=selected_marker;
selected_marker_title=marker.getTitle();
lm.smoothScrollToPosition(mRecyclerView, null, 3);
return false;
}
Little late but try this:
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(final Marker marker){
final LatLng markerPosition = marker.getPosition();
int selected_marker = -1;
for (int i = 0; i < YOURLIST.size(); i++) {
if (markerPosition.latitude == YOURLIST.get(i).getMap().getLatitude() && markerPosition.longitude == YOURLIST.get(i).getMap().getLongitude()) {
selected_marker = i;
}
}
CameraPosition cameraPosition = new CameraPosition.Builder().target(markerPosition).zoom(12).build();
map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
YOURADAPTER.notifyDataSetChanged();
YOURRECYCLERVIEW.smoothScrollToPosition(selected_marker);
marker.showInfoWindow();
return false;
}
});
Related
I am a new Android Developer. I am creating google map and custom marker with lat long map and markers work and show proper in S4 mobile but not shown in s8 or higher version mobile I grant all permission for that.I also put click listener on Custom Marker. These all work fine in s4 or low version mobile but not work in high version api mobile. Thanks in Advance..
where i am wrong ? please help me
Here is my code
public void mSetUpMap() {
googleMap.clear();
/**Create dummy Markers List*/
List<Marker> markersList = new ArrayList<Marker>();
for (City item : cityList)
{
if (googleMap !=null) {
Marker m1 = googleMap.addMarker(new MarkerOptions().position(new
LatLng(item.getLatitude(),
item.getLongitude())).title(item.getName()).anchor(0.5f,
0.5f).icon(BitmapDescriptorFactory.fromBitmap(getCustomMarker(
item.getDrawableId(), item.getName()))));
markersList.add(m1);
}
}
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
{
#Override
public boolean onMarkerClick(final Marker marker) {
ValueAnimator ani = ValueAnimator.ofFloat(0,1); //change for
(0,1) if you want a fade in
ani.setDuration(2000);
ani.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
#Override
public void onAnimationUpdate(ValueAnimator animation) {
marker.setAlpha((float) animation.getAnimatedValue());
}
});
ani.start();
if(marker.getTitle().equals(cityList.get(0).getName()))
{
AppUtil.city=cityList.get(0);
}
else if(marker.getTitle().equals(cityList.get(1).getName()))
{
AppUtil.city=cityList.get(1);
}
else if(marker.getTitle().equals(cityList.get(2).getName()))
{
AppUtil.city=cityList.get(2);
}
else if(marker.getTitle().equals(cityList.get(3).getName()))
{
AppUtil.city=cityList.get(3);
}
else if(marker.getTitle().equals(cityList.get(4).getName()))
{
AppUtil.city=cityList.get(4);
}
FragmentTransaction transaction =
getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, new
CityDetailFragment());
transaction.commit();
/*((CityDetailFragment) adapter.getItem(1)).setupData();
viewPager.setCurrentItem(1,false);*/
return true;
}
});
/**create for loop for get the latLngbuilder from the marker list*/
builder = new LatLngBounds.Builder();
for (Marker m : markersList) {
builder.include(m.getPosition());
}
/**initialize the padding for map boundary*/
final int padding = 150;
/**create the bounds from latlngBuilder to set into map camera*/
final LatLngBounds bounds = builder.build();
/**create the camera with bounds and padding to set into map*/
cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
/**call the map call back to know map is loaded or not*/
enter code here
googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback(){
#Override
public void onMapLoaded() {
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds,
padding));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(12));
}
});
}
private Bitmap createStoreMarker() {
ViewGroup continer = null;
View markerLayout = view.inflate(null,
R.layout.store_marker_layout,continer);
markerLayout.measure(View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED));
markerLayout.layout(0, 0, markerLayout.getMeasuredWidth(),
markerLayout.getMeasuredHeight());
final Bitmap bitmap =
Bitmap.createBitmap(markerLayout.getMeasuredWidth(),
markerLayout.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
markerLayout.draw(canvas);
return bitmap;
}
I am a new Android Developer. I am creating google map and custom marker with lat long map and markers work and show proper in S4 mobile but not shown in s8 or higher version mobile I grant all permission for that.I also put click listener on Custom Marker. These all work fine in s4 or low version mobile but not work in high version api mobile. Thanks in Advance..
where i am wrong ? please help me
Here is my code
public void mSetUpMap() {
googleMap.clear();
/**Create dummy Markers List*/
List<Marker> markersList = new ArrayList<Marker>();
for (City item : cityList)
{
if (googleMap !=null) {
Marker m1 = googleMap.addMarker(new MarkerOptions().position(new
LatLng(item.getLatitude(),
item.getLongitude())).title(item.getName()).anchor(0.5f,
0.5f).icon(BitmapDescriptorFactory.fromBitmap(getCustomMarker(
item.getDrawableId(), item.getName()))));
markersList.add(m1);
}
}
googleMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener()
{
#Override
public boolean onMarkerClick(final Marker marker) {
ValueAnimator ani = ValueAnimator.ofFloat(0,1); //change for
(0,1) if you want a fade in
ani.setDuration(2000);
ani.addUpdateListener(new ValueAnimator.AnimatorUpdateListener()
{
#Override
public void onAnimationUpdate(ValueAnimator animation) {
marker.setAlpha((float) animation.getAnimatedValue());
}
});
ani.start();
if(marker.getTitle().equals(cityList.get(0).getName()))
{
AppUtil.city=cityList.get(0);
}
else if(marker.getTitle().equals(cityList.get(1).getName()))
{
AppUtil.city=cityList.get(1);
}
else if(marker.getTitle().equals(cityList.get(2).getName()))
{
AppUtil.city=cityList.get(2);
}
else if(marker.getTitle().equals(cityList.get(3).getName()))
{
AppUtil.city=cityList.get(3);
}
else if(marker.getTitle().equals(cityList.get(4).getName()))
{
AppUtil.city=cityList.get(4);
}
FragmentTransaction transaction =
getFragmentManager().beginTransaction();
transaction.replace(R.id.frame_container, new
CityDetailFragment());
transaction.commit();
/*((CityDetailFragment) adapter.getItem(1)).setupData();
viewPager.setCurrentItem(1,false);*/
return true;
}
});
/**create for loop for get the latLngbuilder from the marker list*/
builder = new LatLngBounds.Builder();
for (Marker m : markersList) {
builder.include(m.getPosition());
}
/**initialize the padding for map boundary*/
final int padding = 150;
/**create the bounds from latlngBuilder to set into map camera*/
final LatLngBounds bounds = builder.build();
/**create the camera with bounds and padding to set into map*/
cu = CameraUpdateFactory.newLatLngBounds(bounds, padding);
/**call the map call back to know map is loaded or not*/
enter code here
googleMap.setOnMapLoadedCallback(new GoogleMap.OnMapLoadedCallback(){
#Override
public void onMapLoaded() {
googleMap.moveCamera(CameraUpdateFactory.newLatLngBounds(bounds,
padding));
googleMap.animateCamera(CameraUpdateFactory.zoomTo(12));
}
});
}
private Bitmap createStoreMarker() {
ViewGroup continer = null;
View markerLayout = view.inflate(null,
R.layout.store_marker_layout,continer);
markerLayout.measure(View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0,
View.MeasureSpec.UNSPECIFIED));
markerLayout.layout(0, 0, markerLayout.getMeasuredWidth(),
markerLayout.getMeasuredHeight());
final Bitmap bitmap =
Bitmap.createBitmap(markerLayout.getMeasuredWidth(),
markerLayout.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
markerLayout.draw(canvas);
return bitmap;
}
I have a google map with custom info window. Also I added some logic for centering the info window when the marker/pin is clicked. From what I have read the problem is with overriding the setOnMarkerClickListener. Although I set explicitly mMap.getUiSettings().setMapToolbarEnabled(true);
It’s not working. Here is my code:
mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
#Override
public boolean onMarkerClick(final Marker marker) {
// Description: Get device height
// ------------------------------------------------------------------------------------
WindowManager wm = (WindowManager) view.getContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int height = size.y;
// Description: Move the camera up so title of info window is visible
// ------------------------------------------------------------------------------------
LatLng markerLocation = marker.getPosition();
Point mappoint = mMap.getProjection().toScreenLocation(new LatLng(markerLocation.latitude, markerLocation.longitude));
mappoint.set(mappoint.x, mappoint.y - (height / 3));
CameraUpdate cu = CameraUpdateFactory.newLatLng(mMap.getProjection().fromScreenLocation(mappoint));
mMap.getUiSettings().setMapToolbarEnabled(true);
mMap.animateCamera(cu, new GoogleMap.CancelableCallback() {
#Override
public void onFinish() {
if (marker != null) {
marker.showInfoWindow();
mMap.getUiSettings().setMapToolbarEnabled(true);
}
}
#Override
public void onCancel() {
}
});
return true;
}
});
I had this problem, Return false on your onMarkerClick so that the default behavior would be displayed.
I want to change the background of the cluster marker on click. I do this via
#Override
onClusterClick(Cluster<MyObject> cluster) {
Marker marker = renderer.getMarker(cluster);
marker.setIcon(....);
}
This works fine expect for one case: When I zoom in or out and the number of cluster markers doesn't change. For example, if I had a 15 cluster and a 5 cluster, then zoom a level in or out, the same two clusters remain. Clicking on one of these now renderer.getMarker(cluster) returns null. If they re-cluster after zooming, getMarker is not null.
My DefaultClusterRenderer is below. I checked the marker on onClusteredRendered and it's never null. Is this a bug in the DefaultClusterRenderer or should I do something else?
private class MyRenderer extends DefaultClusterRenderer<MyObject> {
private IconGenerator iconGenerator;
private float density;
public MyRenderer(Context context, GoogleMap map, ClusterManager<MyObject> clusterManager) {
super(context, map, clusterManager);
density = context.getResources().getDisplayMetrics().density;
}
#Override
protected void onBeforeClusterItemRendered(MyObject item, MarkerOptions markerOptions) {
markerOptions.icon(BitmapDescriptorFactory.fromResource(R.drawable.my_pin));
}
#Override
protected void onBeforeClusterRendered(Cluster<MyObject> cluster, MarkerOptions markerOptions) {
if(iconGenerator == null) {
iconGenerator = new IconGenerator(getActivity());
iconGenerator.setContentView(makeTextView(getActivity()));
}
iconGenerator.setBackground(makeBackground(false));
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(iconGenerator.makeIcon(String.valueOf(cluster.getSize()))));
}
#Override
protected void onClusterRendered(Cluster<MyObject> cluster, Marker marker) {
super.onClusterRendered(cluster, marker);
// Marker is never null here
}
#Override
protected boolean shouldRenderAsCluster(Cluster<MyObject> cluster) {
return cluster.getSize() > 1;
}
private ShapeDrawable makeBackground(boolean isClicked) {
ShapeDrawable background = new ShapeDrawable(new OvalShape());
background.setColorFilter(ContextCompat.getColor(getActivity(),
isClicked ? R.color.cluster_marker_clicked : R.color.cluster_marker_unclicked), PorterDuff.Mode.SRC_ATOP);
return background;
}
private SquareTextView makeTextView(Context context) {
SquareTextView squareTextView = new SquareTextView(context);
ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(-2, -2);
squareTextView.setLayoutParams(layoutParams);
squareTextView.setTextColor(ContextCompat.getColor(getActivity(), R.color.white));
squareTextView.setTypeface(Utils.getFontBold(getActivity()));
squareTextView.setId(com.google.maps.android.R.id.text);
int twelveDpi = (int) (12.0F * density);
squareTextView.setPadding(twelveDpi, twelveDpi, twelveDpi, twelveDpi);
return squareTextView;
}
public IconGenerator getIconGenerator(boolean isClicked) {
iconGenerator.setBackground(makeBackground(isClicked));
return iconGenerator;
}
}
Initializing the ClusterManager:
final ClusterManager<MyObject> mClusterManager = new ClusterManager<>(getActivity(), googleMap);
mClusterManager.addItems(items);
renderer = new CustomRenderer(getActivity(), googleMap, mClusterManager);
mClusterManager.setRenderer(renderer);
mClusterManager.cluster();
mClusterManager.setOnClusterItemClickListener(this);
googleMap.setOnMarkerClickListener(mClusterManager);
#antonio: This initialization is working for me:
public class MapsActivity extends FragmentActivity
implements ClusterManager.OnClusterClickListener<MyObject> {
// ...
private void setUpClusterer() {
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(51.503186, -0.126446), 10));
mClusterManager = new ClusterManager<MyObject>(this, googleMap);
mClusterManager.setOnClusterClickListener(this);
renderer = new MyRenderer(this, googleMap, mClusterManager);
mClusterManager.setRenderer(renderer);
googleMap.setOnCameraChangeListener(mClusterManager);
googleMap.setOnMarkerClickListener(mClusterManager);
addItems();
}
private void addItems() {
// Set some lat/lng coordinates to start with.
double lat = 51.5145160;
double lng = -0.1270060;
// Add ten cluster items in close proximity, for purposes of this example.
for (int i = 0; i < 10; i++) {
double offset = i / 60d;
lat = lat + offset;
lng = lng + offset;
MyObject offsetItem = new MyObject(lat, lng);
mClusterManager.addItem(offsetItem);
}
}
#Override
public boolean onClusterClick(final Cluster<MyObject> cluster) {
Marker marker = renderer.getMarker(cluster);
marker.setIcon(BitmapDescriptorFactory.fromResource(R.drawable.my_newpin));
return true;
}
}
Couldn't get renderer.getMarker(cluster) to return a marker in that case above. A work around was to create:
Map <Cluster<MyObject>, Marker> clusterMarkerMap = new HashMap<>();
then add them on the DefaultClusterRenderer callback because the marker is never null there:
#Override
protected void onClusterRendered(Cluster<MyObject> cluster, Marker marker) {
super.onClusterRendered(cluster, marker);
clusterMarkerMap.put(cluster, marker);
}
Because the DefaultClusterManager clears them when the camera position changes, wipe the cluster marker map before it creates new ones:
googleMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition cameraPosition) {
// Clear the map here because the markers will be recreated
// when the manager is notified of a (zoom level) camera change
if(zoomLevelChanged)
clusterMarkerMap.clear();
mClusterManager.onCameraChange(cameraPosition);
}
});
Now I can get the marker successfully clusterMarkerMap.get(cluster)
On camera change gets called again and again while animation is going on in google maps. Is it getting triggered because the animation has not finished? If so, how to get the callback which notifies the animation has stopped.
Here is my code:
map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition cameraPosition) {
showLocations(location);
}
});
private void showLocations() {
for (int i = 0; i < 2; i++) {
Marker m = map.addMarker(new MarkerOptions().position(latlngs.get(i))
.icon(BitmapDescriptorFactory.fromResource(R.drawable.some_icon)));
markers.add(m);
}
LatLngBounds.Builder builder = new LatLngBounds.Builder();
for (Marker marker : markers) {
builder.include(marker.getPosition());
}
LatLngBounds bounds = builder.build();
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngBounds(bounds, 100);
map.animateCamera(cameraUpdate);
}
Calling map.animateCamera() causes the OnCameraChangeListener to be called, so you can't change the camera unless you're planning on removing the listener as part of its logic. For example:
map.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
#Override
public void onCameraChange(CameraPosition cameraPosition) {
map.setOnCameraChangeListener(null);
showLocations(location);
}
});