Android谷歌地图-从FAB菜单选择地图类型
我正试图创建一个好看的菜单来更改地图类型,就像谷歌地图上的一样。。当您单击图层FAB时,它会出现。我不知道它是否是一个自定义的FAB菜单,或者它是否会设置动画并打开一个片段Android谷歌地图-从FAB菜单选择地图类型,android,android-layout,android-fragments,kotlin,material-ui,Android,Android Layout,Android Fragments,Kotlin,Material Ui,我正试图创建一个好看的菜单来更改地图类型,就像谷歌地图上的一样。。当您单击图层FAB时,它会出现。我不知道它是否是一个自定义的FAB菜单,或者它是否会设置动画并打开一个片段 如何实现这种外观?我现在能想到的最简单的解决方案是: 将添加到布局中: 在“活动”中,将“可见性”设置为“视图”。单击按钮上的“可见性”: fab.setOnClickListener{ cardview.visibility = View.VISIBLE } 经过大量的阅读和学习,我成功地设计出了令我满意的
如何实现这种外观?我现在能想到的最简单的解决方案是:
添加到布局中:fab.setOnClickListener{
cardview.visibility = View.VISIBLE
}
经过大量的阅读和学习,我成功地设计出了令我满意的外观。对于任何想要相同外观的人,下面是我的代码和参考资料 注意:它并不完美,在其他一些设备上可能看起来不一样,不要对我的编码判断太多(我是一个初学者……我可以进行一些重构,但它完成了工作) 额外要点:
- 用科特林写的
- 非常确定需要API 21+。尚未针对早期版本在此处实施任何变通方法
- 选择视图的“打开/关闭”使用圆形显示动画,而不是Google扩展的动画(我更喜欢我的实现)
- 缺乏优化可能会导致低端设备性能低下
资源
键入默认值.png type_satellite.png 键入地形.png 圆角矩形.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#2962ff" />
<corners android:radius="10dp" />
</shape>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#3C4043"
android:pathData="M11.99,18.54l-7.37,-5.73L3,14.07l9,7 9,-7 -1.63,-1.27
-7.38,5.74zM12,16l7.36,-5.73L21,9l-9,-7 -9,7 1.63,1.27L12,16z"/>
</vector>
最终结果
这是我的最终结果。就像我说的,我只是一个初学者,事情肯定会更好,但现在,我对结果非常满意
谢谢你的帮助,伙计。这对我的想法很有帮助:)我已经发布了我最终完成的答案。NicCoe如果Ro Ras post帮助投票,或者接受他的答案
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#2962ff" />
<corners android:radius="10dp" />
</shape>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#3C4043"
android:pathData="M11.99,18.54l-7.37,-5.73L3,14.07l9,7 9,-7 -1.63,-1.27
-7.38,5.74zM12,16l7.36,-5.73L21,9l-9,-7 -9,7 1.63,1.27L12,16z"/>
</vector>
<android.support.design.widget.FloatingActionButton
android:id="@+id/map_type_FAB"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginEnd="24dp"
android:layout_marginTop="24dp"
android:clickable="true"
android:focusable="true"
app:backgroundTint="#FFF"
app:fabSize="mini"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="@+id/map_view"
app:rippleColor="#eff5ff"
app:srcCompat="@drawable/ic_map_layers" />
<android.support.constraint.ConstraintLayout
android:id="@+id/map_type_selection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/map_type_background"
android:elevation="6dp"
android:padding="8dp"
android:visibility="invisible"
app:layout_constraintEnd_toEndOf="@+id/map_type_FAB"
app:layout_constraintTop_toTopOf="@+id/map_type_FAB">
<View
android:id="@+id/map_type_default_background"
android:layout_width="54dp"
android:layout_height="54dp"
android:background="@drawable/rounded_rectangle"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/map_type_default"
app:layout_constraintEnd_toEndOf="@+id/map_type_default"
app:layout_constraintStart_toStartOf="@+id/map_type_default"
app:layout_constraintTop_toTopOf="@+id/map_type_default" />
<ImageButton
android:id="@+id/map_type_default"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:background="@drawable/type_default"
android:scaleType="fitCenter"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView13" />
<View
android:id="@+id/map_type_satellite_background"
android:layout_width="54dp"
android:layout_height="54dp"
android:background="@drawable/rounded_rectangle"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/map_type_satellite"
app:layout_constraintEnd_toEndOf="@+id/map_type_satellite"
app:layout_constraintStart_toStartOf="@+id/map_type_satellite"
app:layout_constraintTop_toTopOf="@+id/map_type_satellite" />
<ImageButton
android:id="@+id/map_type_satellite"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginEnd="32dp"
android:layout_marginStart="32dp"
android:layout_marginTop="8dp"
android:background="@drawable/type_satellite"
android:scaleType="fitCenter"
app:layout_constraintEnd_toStartOf="@+id/map_type_terrain"
app:layout_constraintStart_toEndOf="@+id/map_type_default"
app:layout_constraintTop_toBottomOf="@+id/textView13" />
<View
android:id="@+id/map_type_terrain_background"
android:layout_width="54dp"
android:layout_height="54dp"
android:background="@drawable/rounded_rectangle"
android:visibility="invisible"
app:layout_constraintBottom_toBottomOf="@+id/map_type_terrain"
app:layout_constraintEnd_toEndOf="@+id/map_type_terrain"
app:layout_constraintStart_toStartOf="@+id/map_type_terrain"
app:layout_constraintTop_toTopOf="@+id/map_type_terrain" />
<ImageButton
android:id="@+id/map_type_terrain"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:background="@drawable/type_terrain"
android:scaleType="fitCenter"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView13" />
<TextView
android:id="@+id/textView13"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginTop="8dp"
android:fontFamily="sans-serif"
android:text="Map Type"
android:textAllCaps="true"
android:textColor="@android:color/black"
android:textSize="12sp"
android:textStyle="bold"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/map_type_default_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Default"
android:textColor="#808080"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="@+id/map_type_default"
app:layout_constraintStart_toStartOf="@+id/map_type_default"
app:layout_constraintTop_toBottomOf="@+id/map_type_default" />
<TextView
android:id="@+id/map_type_satellite_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Satellite"
android:textColor="#808080"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="@+id/map_type_satellite"
app:layout_constraintStart_toStartOf="@+id/map_type_satellite"
app:layout_constraintTop_toBottomOf="@+id/map_type_satellite" />
<TextView
android:id="@+id/map_type_terrain_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="Terrain"
android:textColor="#808080"
android:textSize="12sp"
app:layout_constraintEnd_toEndOf="@+id/map_type_terrain"
app:layout_constraintStart_toStartOf="@+id/map_type_terrain"
app:layout_constraintTop_toBottomOf="@+id/map_type_terrain" />
</android.support.constraint.ConstraintLayout>
override fun onMapReady(googleMap: GoogleMap) {
// Initialise the map variable
map = googleMap
// When map is initially loaded, determine which map type option to 'select'
when {
map.mapType == GoogleMap.MAP_TYPE_SATELLITE -> {
map_type_satellite_background.visibility = View.VISIBLE
map_type_satellite_text.setTextColor(Color.BLUE)
}
map.mapType == GoogleMap.MAP_TYPE_TERRAIN -> {
map_type_terrain_background.visibility = View.VISIBLE
map_type_terrain_text.setTextColor(Color.BLUE)
}
else -> {
map_type_default_background.visibility = View.VISIBLE
map_type_default_text.setTextColor(Color.BLUE)
}
}
// Set click listener on FAB to open the map type selection view
mapTypeFAB.setOnClickListener {
// Start animator to reveal the selection view, starting from the FAB itself
val anim = ViewAnimationUtils.createCircularReveal(
map_type_selection,
map_type_selection.width - (map_type_FAB.width / 2),
map_type_FAB.height / 2,
map_type_FAB.width / 2f,
map_type_selection.width.toFloat())
anim.duration = 200
anim.interpolator = AccelerateDecelerateInterpolator()
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator?) {
super.onAnimationEnd(animation)
map_type_selection.visibility = View.VISIBLE
}
})
anim.start()
mapTypeFAB.visibility = View.INVISIBLE
}
// Set click listener on the map to close the map type selection view
map.setOnMapClickListener {
// Conduct the animation if the FAB is invisible (window open)
if (map_type_FAB.visibility == View.INVISIBLE) {
// Start animator close and finish at the FAB position
val anim = ViewAnimationUtils.createCircularReveal(
map_type_selection,
map_type_selection.width - (map_type_FAB.width / 2),
map_type_FAB.height / 2,
map_type_selection.width.toFloat(),
map_type_FAB.width / 2f)
anim.duration = 200
anim.interpolator = AccelerateDecelerateInterpolator()
anim.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator?) {
super.onAnimationEnd(animation)
map_type_selection.visibility = View.INVISIBLE
}
})
// Set a delay to reveal the FAB. Looks better than revealing at end of animation
Handler().postDelayed({
kotlin.run {
mapTypeFAB.visibility = View.VISIBLE
}
}, 100)
anim.start()
}
}
// Handle selection of the Default map type
map_type_default.setOnClickListener {
map_type_default_background.visibility = View.VISIBLE
map_type_satellite_background.visibility = View.INVISIBLE
map_type_terrain_background.visibility = View.INVISIBLE
map_type_default_text.setTextColor(Color.BLUE)
map_type_satellite_text.setTextColor(Color.parseColor("#808080"))
map_type_terrain_text.setTextColor(Color.parseColor("#808080"))
map.mapType = GoogleMap.MAP_TYPE_NORMAL
}
// Handle selection of the Satellite map type
map_type_satellite.setOnClickListener {
map_type_default_background.visibility = View.INVISIBLE
map_type_satellite_background.visibility = View.VISIBLE
map_type_terrain_background.visibility = View.INVISIBLE
map_type_default_text.setTextColor(Color.parseColor("#808080"))
map_type_satellite_text.setTextColor(Color.BLUE)
map_type_terrain_text.setTextColor(Color.parseColor("#808080"))
map.mapType = GoogleMap.MAP_TYPE_SATELLITE
}
// Handle selection of the terrain map type
map_type_terrain.setOnClickListener {
map_type_default_background.visibility = View.INVISIBLE
map_type_satellite_background.visibility = View.INVISIBLE
map_type_terrain_background.visibility = View.VISIBLE
map_type_default_text.setTextColor(Color.parseColor("#808080"))
map_type_satellite_text.setTextColor(Color.parseColor("#808080"))
map_type_terrain_text.setTextColor(Color.BLUE)
map.mapType = GoogleMap.MAP_TYPE_TERRAIN
}
}