假设我有这样的布局:
<androidx.core.widget.NestedScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<com.google.android.gms.maps.MapView
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="300dp"
app:uiMapToolbar="false"
/>
</LinearLayout>
</androidx.core.widget.NestedScrollView>
将满足我的需求,就是
尽管我看到了两个问题:
我也尝试过使地图成为适配器的一项,但是在滚动列表时会引入很多麻烦,而且很尴尬,因为您需要将转发生命周期与地图的回收期适配器中的项的“生命周期”协调起来。
那么您如何在列表下显示地图而不丢失回收或平滑滚动?
NestedScrollView
解决方案存在另一个问题,即:
所以我最终得到了另一个使地图成为适配器项的解决方案:
onViewCreated
中扩大地图时的问题,而不是当适配器确定在滚动期间需要地图时,这不是问题onCreateViewHolder
和片段中的onViewCreated
onViewCreated -> onCreate
,onDestroyView -> onDestroy
,onStart
,onStop
,onResume
,onPause
,onSaveInstanceState
和onLowMemory
生命周期回调onDestroyView
中的引用(当分离片段后试图保存已破坏的映射的状态时)片段代码:
private var mapView: MapView? = null
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
mapView = adapter.inflateMapView(recyclerView)
mapView?.onCreate(savedInstanceState?.getBundle(GOOGLE_MAPS_BUNDLE))
}
override fun onDestroyView() {
mapView?.onDestroy()
mapView = null
adapter.clearViewReferences()
super.onDestroyView()
}
override fun onStart() {
super.onStart()
mapView?.onStart()
}
override fun onStop() {
mapView?.onStop()
super.onStop()
}
override fun onResume() {
super.onResume()
mapView?.onResume()
}
override fun onPause() {
mapView?.onPause()
super.onPause()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
if (GOOGLE_MAPS_BUNDLE !in outState.keySet()) {
outState.putBundle(GOOGLE_MAPS_BUNDLE, Bundle())
}
mapView?.onSaveInstanceState(outState.getBundle(GOOGLE_MAPS_BUNDLE))
}
override fun onLowMemory() {
super.onLowMemory()
mapView?.onLowMemory()
}
适配器代码:
private var mapViewHolder: MapViewHolder? = null
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) = when (viewType) {
VIEW_TYPE_FOO -> FooViewHolder(parent)
VIEW_TYPE_MAP -> getMapViewHolder(parent)
else -> error("Unknown viewType $viewType")
}
fun inflateMapView(parent: ViewGroup): MapView = getMapViewHolder(parent).mapView
fun clearViewReferences() {
mapViewHolder = null
}
private fun getMapViewHolder(parent: ViewGroup): MapViewHolder {
return mapViewHolder ?: MapViewHolder(parent).also { mapViewHolder = it }
}
此外,布局使用的是MapView
子类,它将在可滚动容器中工作:
override fun dispatchTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_DOWN && parent is ScrollingView) {
parent.requestDisallowInterceptTouchEvent(true)
}
return super.dispatchTouchEvent(event)
}