You can implement it yourself by adding a bottomsheet element to the parent layout of the MapFragment
and then setting a custom OnMarkerClickListener
.
For the bottom sheet to work, you should use the CoordinatorLayout
for the parent of the MapFragment
. To create a bottomsheet element, you should set app:layout_behavior="android.support.design.widget.BottomSheetBehavior
to a layout element, such as a NestedScrollView
.
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:fitsSystemWindows="true"
tools:context=".MainActivity">
<include layout="@layout/content_main" />
<android.support.v4.widget.NestedScrollView android:id="@+id/bottom_sheet"
android:layout_width="match_parent" android:layout_height="550dp"
android:background="@android:color/white" android:clipToPadding="true"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior">
<TextView android:id="@+id/detail_name" android:layout_width="0dp"
android:layout_height="wrap_content" android:layout_margin="25dp"
android:layout_weight="3" android:gravity="center_vertical"
android:textAppearance="?android:textAppearanceLarge" />
</android.support.v4.widget.NestedScrollView>
The map fragment:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context=".MainActivity"
tools:showIn="@layout/app_bar_main">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/map"
android:name="com.google.android.gms.maps.MapFragment"/>
</RelativeLayout>
Then in your activity class, you can set up the bottom sheet initial behaviour in onCreate()
:
private BottomSheetBehavior bottomSheetBehavior;
private View bottomSheet;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bottomSheet = findViewById(R.id.bottom_sheet);
bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
bottomSheetBehavior.setPeekHeight(200);
bottomSheetBehavior.setHideable(true);
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
}
Then modify the map behaviour in onMapReady()
:
@Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
map.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
@Override
public boolean onMarkerClick(Marker marker) {
updateBottomSheetContent(marker);
return true;
}
});
map.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
@Override
public void onMapClick(LatLng latLng) {
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
}
});
}
private void updateBottomSheetContent(Marker marker) {
TextView name = (TextView) bottomSheet.findViewById(R.id.detail_name);
name.setText(marker.getTitle());
bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
}
Of course, you can also use some data stored in the marker to query your database or ContentProvider
for appropriate record and then use the returned data to set more text, images, etc. in the bottom sheet.