尝试模仿当前Google Maps底部的栏。
我一直在尝试但都失败了,包括CollapsingToolbar、BottomSheet和自定义库。
我的目标:当BottomSheet滑动时,让地图视图适应其大小和相机,使底部表单不会滑过地图,而是使地图适合剩余的空间。
可以查看这个视频,了解我的意思(我指的不是缩放功能)。
尝试模仿当前Google Maps底部的栏。
我一直在尝试但都失败了,包括CollapsingToolbar、BottomSheet和自定义库。
我的目标:当BottomSheet滑动时,让地图视图适应其大小和相机,使底部表单不会滑过地图,而是使地图适合剩余的空间。
可以查看这个视频,了解我的意思(我指的不是缩放功能)。
我是这样处理 BottomSheet 的 onSlide 事件的:
@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;
}
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));
}
<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()
回调,并在每次调整地图的底部填充时进行调整。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
)
}
}
}
}