Trying to mimic the current google maps Bar at the bottom. I failed so hard and tried so much; CollapsingToolbar, BottomSheet, custom libs.
What I want: Making the map view adapt it's size and camera when the BottomSheet is sliding, so that the bottom sheet does not slide over the map but instead the map fits in the space that is left.
Take a look at this video to see what I mean (And I don't mean the zoom functionality)
The BottomBar library I used is deprecated. But perhaps my code gives you an idea how it could be done.
I reacted to onSlide events of the BottomSheet like this:
@Override
public void onSlide(@NonNull View bottomSheet, float slideOffset) {
switch (bssBehavior.getState()) {
case BottomSheetBehavior.STATE_DRAGGING:
setMapPaddingBotttom(slideOffset);
searchVM.map.moveCamera(CameraUpdateFactory.newLatLng(lastValidMapCenter));
break;
case BottomSheetBehavior.STATE_SETTLING:
setMapPaddingBotttom(slideOffset);
searchVM.map.moveCamera(CameraUpdateFactory.newLatLng(lastValidMapCenter));
break;
case BottomSheetBehavior.STATE_HIDDEN:
break;
case BottomSheetBehavior.STATE_EXPANDED:
break;
case BottomSheetBehavior.STATE_COLLAPSED:
break;
}
And smoothly resized the map by changing its padding. For calculating it accordingly I used sth. like this.
private void setMapPaddingBotttom(Float offset) {
//From 0.0 (min) - 1.0 (max)
Float maxMapPaddingBottom = bsExpanded - bsCollapsed;
//left,top,right,bottom
searchVM.map.setPadding(0, 0, 0, Math.round(offset * maxMapPaddingBottom));
}
Here is a full example to achieve the effect that the Google Map's padding automatically resizes when a BottomSheet on top of it moves/slides. This way the Google logo of the map always moves together with the bottomsheet.
<androidx.coordinatorlayout.widget.CoordinatorLayout
android:id="@+id/root_coordinator_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
class="com.google.android.gms.maps.SupportMapFragment"
android:id="@+id/map_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<LinearLayout
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/bottom_sheet_behavior"
android:elevation="4dp"
app:behavior_peekHeight="420dp"
android:orientation="vertical">
<!-- Your bottom sheet's content-->
</LinearLayout>
</androidx.coordinatorlayout.widget.CoordinatorLayout>
onSlide()
callback of the bottomsheet and adjust the map's bottom padding everytime.class MapWithSheetActivity : AppCompatActivity() {
private var googleMap: GoogleMap? = null
private var bottomSheetContainer: CoordinatorLayout? = null
private var bottomSheetLayout: LinearLayout? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_booking_detail)
this.bottomSheetLayout = findViewById<LinearLayout>(R.id.bottom_sheet)
this.bottomSheetContainer = findViewById<CoordinatorLayout>(R.id.root_coordinator_layout)
initMap()
initBottomSheet()
}
private fun initMap() {
val mapFragment = supportFragmentManager.findFragmentById(R.id.map_fragment) as? SupportMapFragment
mapFragment?.getMapAsync { googleMap ->
this.googleMap = googleMap
}
}
private fun initBottomSheet() {
val bottomSheetBehavior = BottomSheetBehavior.from(findViewById(R.id.bottom_sheet))
bottomSheetBehavior.addBottomSheetCallback(object :
BottomSheetBehavior.BottomSheetCallback() {
override fun onSlide(bottomSheet: View, slideOffset: Float) {
when (bottomSheetBehavior.state) {
BottomSheetBehavior.STATE_DRAGGING, BottomSheetBehavior.STATE_SETTLING -> {
adjustMapPaddingToBottomSheet()
}
else -> {
// No adjustment needed on other slide states.
}
}
}
override fun onStateChanged(bottomSheet: View, newState: Int) {
// Needed only in case you manually change the bottomsheet's state in code somewhere.
when (newState) {
BottomSheetBehavior.STATE_EXPANDED -> {
// Nothing to do here
}
else -> {
adjustMapPaddingToBottomSheet()
}
}
}
})
}
private fun adjustMapPaddingToBottomSheet() {
googleMap?.let { map ->
if (this.bottomSheetContainer != null && this.bottomSheetLayout != null) {
val bottomSheetContainerHeight = this.bottomSheetContainer.height
val currentBottomSheetTop = this.bottomSheetLayout.top
map.setPadding(
0, // left
0, // top
0, // right
bottomSheetContainerHeight - currentBottomSheetTop // bottom
)
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With