После долгих чтений и обучения мне удалось полностью разработать дизайн, которым я доволен.Для тех, кто хочет того же взгляда, вот мой код и ресурсы ниже ...
Примечание: Это не совсем идеально, может выглядеть по-другому на некоторых других устройствах и не судитьмое кодирование слишком много (я новичок ... я могу провести рефакторинг, но он выполняет свою работу).
Дополнительные баллы:
- Написано вKotlin
- Уверен, требуется API 21+.Здесь не реализовано никакого обходного пути для более ранних версий
- При открытии / закрытии представления выбора используется анимация с круговым раскрытием, вместо того, чтобы расширять Googles (мне больше нравится моя реализация)
- Отсутствие оптимизации можетприводят к снижению производительности на младших устройствах
Ресурсы
type_default.png
type_s satellite.png
type_terrain.png
rounded_rectangle.xml
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#2962ff" />
<corners android:radius="10dp" />
</shape>
ic_map_layers.xml
<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>
Файл макета карты
Код, указанный здесь, также был вложен в макет ограничения с картой и другими FAB, но если вы читаете это, я не думаю, что вам нужно знать, какпоместить карту в ...
<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>
Фрагмент карты
Фрагмент кода из моей функции onMapReady.Это часть, которая не самая красивая, но выполняет свою работу.
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
}
}
Конечный результат
Это мой конецрезультат.Как я уже сказал, я только начинающий, все может быть лучше, но сейчас я очень доволен результатом.
