mirror of
https://github.com/ev-map/EVMap.git
synced 2026-05-19 04:16:24 -04:00
Add some stuff in detail view
This commit is contained in:
@@ -2,13 +2,13 @@
|
||||
<defs>
|
||||
<style>.cls-1{fill:none;stroke:#000;stroke-miterlimit:10;stroke-width:2px;}</style>
|
||||
</defs>
|
||||
<title>ccs</title>
|
||||
<title>connector_ccs</title>
|
||||
<path class="cls-1"
|
||||
d="M20,8.2a7.89,7.89,0,0,1-8,7.87A7.91,7.91,0,0,1,6.29,2.6H17.71A8,8,0,0,1,20,8.2Z" />
|
||||
<circle cx="12" cy="7.4" r="1.6" />
|
||||
<circle cx="9.6" cy="5" r="1" />
|
||||
<circle cx="14.4" cy="5" r="1" />
|
||||
<circle cx="9" cy="18.73" r="1.5" />
|
||||
<circle cx="15" cy="18.73" r="1.5" />
|
||||
<rect class="cls-1" x="6.24" y="16.07" width="11.52" height="5.33" rx="2.67" />
|
||||
<circle cx="9" cy="18.73" r="1.37" />
|
||||
<circle cx="15" cy="18.73" r="1.37" />
|
||||
<rect class="cls-1" x="6.25" y="16.07" width="11.51" height="5.33" rx="2.67" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 639 B After Width: | Height: | Size: 651 B |
@@ -29,6 +29,10 @@ android {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = JavaVersion.VERSION_1_8.toString()
|
||||
}
|
||||
|
||||
dataBinding {
|
||||
enabled = true
|
||||
}
|
||||
@@ -46,13 +50,14 @@ dependencies {
|
||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||
implementation 'com.google.maps.android:android-maps-utils:0.5'
|
||||
implementation 'com.github.johan12345:CustomBottomSheetBehavior:-SNAPSHOT'
|
||||
implementation 'com.github.johan12345:CustomBottomSheetBehavior:0d0e30d8f1'
|
||||
implementation 'com.google.android.gms:play-services-maps:17.0.0'
|
||||
implementation 'com.google.android.gms:play-services-location:17.0.0'
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.7.2'
|
||||
implementation 'com.squareup.retrofit2:converter-moshi:2.7.2'
|
||||
implementation 'com.squareup.moshi:moshi-kotlin:1.9.2'
|
||||
implementation 'com.squareup.picasso:picasso:2.71828'
|
||||
implementation 'com.jakewharton.threetenabp:threetenabp:1.2.2'
|
||||
|
||||
// debug tools
|
||||
implementation 'com.facebook.stetho:stetho:1.5.1'
|
||||
|
||||
@@ -2,10 +2,12 @@ package com.johan.evmap
|
||||
|
||||
import android.app.Application
|
||||
import com.facebook.stetho.Stetho
|
||||
import com.jakewharton.threetenabp.AndroidThreeTen
|
||||
|
||||
class EvMapApplication : Application() {
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
AndroidThreeTen.init(this);
|
||||
Stetho.initializeWithDefaults(this);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,9 @@
|
||||
package com.johan.evmap
|
||||
|
||||
import android.Manifest
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.net.Uri
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
@@ -20,8 +22,10 @@ import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.Marker
|
||||
import com.google.android.gms.maps.model.MarkerOptions
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.maps.android.ui.IconGenerator
|
||||
import com.johan.evmap.adapter.ConnectorAdapter
|
||||
import com.johan.evmap.adapter.DetailAdapter
|
||||
import com.johan.evmap.adapter.GalleryAdapter
|
||||
import com.johan.evmap.api.*
|
||||
import com.johan.evmap.databinding.ActivityMapsBinding
|
||||
@@ -51,21 +55,9 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
mapFragment.getMapAsync(this)
|
||||
api = GoingElectricApi.create(getString(R.string.goingelectric_key))
|
||||
|
||||
setupAdapters()
|
||||
|
||||
val behavior = BottomSheetBehaviorGoogleMapsLike.from(binding.bottomSheet)
|
||||
|
||||
binding.gallery.adapter = GalleryAdapter(this)
|
||||
binding.gallery.layoutManager =
|
||||
LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
|
||||
binding.gallery.addItemDecoration(DividerItemDecoration(
|
||||
this, LinearLayoutManager.HORIZONTAL
|
||||
).apply {
|
||||
setDrawable(getDrawable(R.drawable.gallery_divider)!!)
|
||||
})
|
||||
|
||||
binding.detailView.connectors.adapter = ConnectorAdapter()
|
||||
binding.detailView.connectors.layoutManager =
|
||||
LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
|
||||
|
||||
binding.addOnPropertyChangedCallback(object : Observable.OnPropertyChangedCallback() {
|
||||
var previousCharger = binding.charger
|
||||
|
||||
@@ -100,7 +92,62 @@ class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
|
||||
enableLocation(true)
|
||||
}
|
||||
}
|
||||
binding.fabDirections.setOnClickListener {
|
||||
val charger = binding.charger
|
||||
if (charger != null) {
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
val coord = charger.coordinates
|
||||
|
||||
// google maps navigation
|
||||
intent.data = Uri.parse("google.navigation:q=${coord.lat},${coord.lng}")
|
||||
if (intent.resolveActivity(packageManager) != null) {
|
||||
startActivity(intent);
|
||||
} else {
|
||||
// fallback: generic geo intent
|
||||
intent.data = Uri.parse("geo:${coord.lat},${coord.lng}")
|
||||
if (intent.resolveActivity(packageManager) != null) {
|
||||
startActivity(intent);
|
||||
} else {
|
||||
Snackbar.make(
|
||||
binding.root,
|
||||
R.string.no_maps_app_found,
|
||||
Snackbar.LENGTH_SHORT
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupAdapters() {
|
||||
binding.gallery.apply {
|
||||
adapter = GalleryAdapter(this@MapsActivity)
|
||||
layoutManager =
|
||||
LinearLayoutManager(this@MapsActivity, LinearLayoutManager.HORIZONTAL, false)
|
||||
addItemDecoration(DividerItemDecoration(
|
||||
this@MapsActivity, LinearLayoutManager.HORIZONTAL
|
||||
).apply {
|
||||
setDrawable(getDrawable(R.drawable.gallery_divider)!!)
|
||||
})
|
||||
}
|
||||
|
||||
binding.detailView.connectors.apply {
|
||||
adapter = ConnectorAdapter()
|
||||
layoutManager =
|
||||
LinearLayoutManager(this@MapsActivity, LinearLayoutManager.HORIZONTAL, false)
|
||||
}
|
||||
|
||||
binding.detailView.details.apply {
|
||||
adapter = DetailAdapter()
|
||||
layoutManager =
|
||||
LinearLayoutManager(this@MapsActivity, LinearLayoutManager.VERTICAL, false)
|
||||
addItemDecoration(
|
||||
DividerItemDecoration(
|
||||
this@MapsActivity,
|
||||
LinearLayoutManager.VERTICAL
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.johan.evmap.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.databinding.DataBindingUtil
|
||||
@@ -9,6 +10,7 @@ import androidx.recyclerview.widget.ListAdapter
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.johan.evmap.BR
|
||||
import com.johan.evmap.R
|
||||
import com.johan.evmap.api.ChargeLocation
|
||||
import com.johan.evmap.api.Chargepoint
|
||||
|
||||
interface Equatable {
|
||||
@@ -46,4 +48,35 @@ abstract class DataBindingAdapter<T : Equatable>() :
|
||||
|
||||
class ConnectorAdapter : DataBindingAdapter<Chargepoint>() {
|
||||
override fun getItemViewType(position: Int): Int = R.layout.item_connector
|
||||
}
|
||||
}
|
||||
|
||||
class DetailAdapter : DataBindingAdapter<DetailAdapter.Detail>() {
|
||||
data class Detail(val icon: Int, val contentDescription: Int, val text: CharSequence) :
|
||||
Equatable
|
||||
|
||||
override fun getItemViewType(position: Int): Int = R.layout.item_detail
|
||||
}
|
||||
|
||||
fun buildDetails(loc: ChargeLocation?, ctx: Context): List<DetailAdapter.Detail> {
|
||||
if (loc == null) return emptyList()
|
||||
|
||||
return listOfNotNull(
|
||||
DetailAdapter.Detail(R.drawable.ic_address, R.string.address, loc.address.toString()),
|
||||
if (loc.operator != null) DetailAdapter.Detail(
|
||||
R.drawable.ic_operator,
|
||||
R.string.operator,
|
||||
loc.operator
|
||||
) else null,
|
||||
if (loc.network != null) DetailAdapter.Detail(
|
||||
R.drawable.ic_network,
|
||||
R.string.network,
|
||||
loc.network
|
||||
) else null,
|
||||
// TODO: separate layout for opening hours with expandable details
|
||||
if (loc.openinghours != null) DetailAdapter.Detail(
|
||||
R.drawable.ic_hours,
|
||||
R.string.hours,
|
||||
loc.openinghours.getStatusText(ctx)
|
||||
) else null
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.johan.evmap.api
|
||||
|
||||
import com.squareup.moshi.*
|
||||
import org.threeten.bp.LocalTime
|
||||
import java.lang.reflect.Type
|
||||
|
||||
|
||||
@@ -101,3 +102,31 @@ private fun hasJsonObjectOrFalseAnnotation(annotations: Set<Annotation>?) =
|
||||
annotation class JsonObjectOrFalse {
|
||||
|
||||
}
|
||||
|
||||
internal class HoursAdapter {
|
||||
private val regex = Regex("from (.*) till (.*)")
|
||||
|
||||
@FromJson
|
||||
fun fromJson(str: String): Hours? {
|
||||
if (str == "closed") {
|
||||
return Hours(null, null)
|
||||
} else {
|
||||
val match = regex.find(str)
|
||||
?: throw IllegalArgumentException("$str does not match hours format")
|
||||
return Hours(
|
||||
LocalTime.parse(match.groupValues[1]),
|
||||
LocalTime.parse(match.groupValues[2])
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ToJson
|
||||
fun toJson(value: Hours): String {
|
||||
if (value.start == null || value.end == null) {
|
||||
return "closed"
|
||||
} else {
|
||||
return "from ${value.start} till ${value.end}"
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -38,6 +38,7 @@ interface GoingElectricApi {
|
||||
val moshi = Moshi.Builder()
|
||||
.add(ChargepointListItemJsonAdapterFactory())
|
||||
.add(JsonObjectOrFalseAdapter.Factory())
|
||||
.add(HoursAdapter())
|
||||
.build()
|
||||
|
||||
val retrofit = Retrofit.Builder()
|
||||
|
||||
@@ -1,8 +1,14 @@
|
||||
package com.johan.evmap.api
|
||||
|
||||
import android.content.Context
|
||||
import androidx.core.text.HtmlCompat
|
||||
import com.johan.evmap.R
|
||||
import com.johan.evmap.adapter.Equatable
|
||||
import com.squareup.moshi.Json
|
||||
import com.squareup.moshi.JsonClass
|
||||
import org.threeten.bp.DayOfWeek
|
||||
import org.threeten.bp.LocalDate
|
||||
import org.threeten.bp.LocalTime
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ChargepointList(
|
||||
@@ -26,8 +32,9 @@ data class ChargeLocation(
|
||||
// only shown in details:
|
||||
@JsonObjectOrFalse val operator: String?,
|
||||
@Json(name = "general_information") @JsonObjectOrFalse val generalInformation: String?,
|
||||
val photos: List<ChargerPhoto>?
|
||||
val photos: List<ChargerPhoto>?,
|
||||
//val chargecards: Boolean?
|
||||
val openinghours: OpeningHours?
|
||||
) : ChargepointListItem() {
|
||||
val maxPower: Double
|
||||
get() {
|
||||
@@ -41,6 +48,79 @@ data class ChargeLocation(
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class OpeningHours(
|
||||
@Json(name = "24/7") val twentyfourSeven: Boolean,
|
||||
@JsonObjectOrFalse val description: String?,
|
||||
val days: OpeningHoursDays?
|
||||
) {
|
||||
fun getStatusText(ctx: Context): CharSequence {
|
||||
if (twentyfourSeven) {
|
||||
return HtmlCompat.fromHtml(ctx.getString(R.string.open_247), 0)
|
||||
} else if (days != null) {
|
||||
val hours = days.getHoursForDate(LocalDate.now())
|
||||
if (hours.start == null || hours.end == null) {
|
||||
return HtmlCompat.fromHtml(ctx.getString(R.string.closed), 0)
|
||||
}
|
||||
|
||||
val now = LocalTime.now()
|
||||
if (hours.start.isBefore(now) && hours.end.isAfter(now)) {
|
||||
return HtmlCompat.fromHtml(
|
||||
ctx.getString(
|
||||
R.string.open_closesat,
|
||||
hours.end.toString()
|
||||
), 0
|
||||
)
|
||||
} else if (hours.end.isBefore(now)) {
|
||||
return HtmlCompat.fromHtml(ctx.getString(R.string.closed), 0)
|
||||
} else {
|
||||
return HtmlCompat.fromHtml(
|
||||
ctx.getString(
|
||||
R.string.closed_opensat,
|
||||
hours.start.toString()
|
||||
), 0
|
||||
)
|
||||
}
|
||||
} else if (description != null) {
|
||||
return description
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class OpeningHoursDays(
|
||||
val monday: Hours,
|
||||
val tuesday: Hours,
|
||||
val wednesday: Hours,
|
||||
val thursday: Hours,
|
||||
val friday: Hours,
|
||||
val saturday: Hours,
|
||||
val sunday: Hours,
|
||||
val holiday: Hours
|
||||
) {
|
||||
fun getHoursForDate(date: LocalDate): Hours {
|
||||
// TODO: check for holidays
|
||||
|
||||
@Suppress("WHEN_ENUM_CAN_BE_NULL_IN_JAVA")
|
||||
return when (date.dayOfWeek) {
|
||||
DayOfWeek.MONDAY -> monday
|
||||
DayOfWeek.TUESDAY -> tuesday
|
||||
DayOfWeek.WEDNESDAY -> wednesday
|
||||
DayOfWeek.THURSDAY -> thursday
|
||||
DayOfWeek.FRIDAY -> friday
|
||||
DayOfWeek.SATURDAY -> saturday
|
||||
DayOfWeek.SUNDAY -> sunday
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class Hours(
|
||||
val start: LocalTime?,
|
||||
val end: LocalTime?
|
||||
)
|
||||
|
||||
@JsonClass(generateAdapter = true)
|
||||
data class ChargerPhoto(val id: String)
|
||||
|
||||
|
||||
@@ -49,4 +49,14 @@ fun getConnectorItem(view: ImageView, type: String) {
|
||||
else -> 0
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
@BindingAdapter("srcCompat")
|
||||
fun setImageResource(imageView: ImageView, resource: Int) {
|
||||
imageView.setImageResource(resource)
|
||||
}
|
||||
|
||||
@BindingAdapter("android:contentDescription")
|
||||
fun setContentDescriptionResource(imageView: ImageView, resource: Int) {
|
||||
imageView.contentDescription = imageView.context.getString(resource)
|
||||
}
|
||||
@@ -19,12 +19,12 @@
|
||||
android:pathData="M14.4,5m-1,0a1,1 0,1 1,2 0a1,1 0,1 1,-2 0" />
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M9,18.73m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0" />
|
||||
android:pathData="M9,18.73m-1.37,0a1.37,1.37 0,1 1,2.74 0a1.37,1.37 0,1 1,-2.74 0" />
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15,18.73m-1.5,0a1.5,1.5 0,1 1,3 0a1.5,1.5 0,1 1,-3 0" />
|
||||
android:pathData="M15,18.73m-1.37,0a1.37,1.37 0,1 1,2.74 0a1.37,1.37 0,1 1,-2.74 0" />
|
||||
<path
|
||||
android:pathData="M8.91,16.07L15.09,16.07A2.67,2.665 0,0 1,17.76 18.735L17.76,18.735A2.67,2.665 0,0 1,15.09 21.4L8.91,21.4A2.67,2.665 0,0 1,6.24 18.735L6.24,18.735A2.67,2.665 0,0 1,8.91 16.07z"
|
||||
android:pathData="M8.92,16.07L15.09,16.07A2.67,2.665 0,0 1,17.76 18.735L17.76,18.735A2.67,2.665 0,0 1,15.09 21.4L8.92,21.4A2.67,2.665 0,0 1,6.25 18.735L6.25,18.735A2.67,2.665 0,0 1,8.92 16.07z"
|
||||
android:strokeWidth="2"
|
||||
android:fillColor="#00000000"
|
||||
android:strokeColor="#000" />
|
||||
|
||||
9
app/src/main/res/drawable/ic_address.xml
Normal file
9
app/src/main/res/drawable/ic_address.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<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="#FF000000"
|
||||
android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z" />
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_hours.xml
Normal file
9
app/src/main/res/drawable/ic_hours.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<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="#FF000000"
|
||||
android:pathData="M11.99,2C6.47,2 2,6.48 2,12s4.47,10 9.99,10C17.52,22 22,17.52 22,12S17.52,2 11.99,2zM12,20c-4.42,0 -8,-3.58 -8,-8s3.58,-8 8,-8 8,3.58 8,8 -3.58,8 -8,8zM12.5,7H11v6l5.25,3.15 0.75,-1.23 -4.5,-2.67z" />
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_network.xml
Normal file
9
app/src/main/res/drawable/ic_network.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<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="#FF000000"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM8,17.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5zM9.5,8c0,-1.38 1.12,-2.5 2.5,-2.5s2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5S9.5,9.38 9.5,8zM16,17.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z" />
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_operator.xml
Normal file
9
app/src/main/res/drawable/ic_operator.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<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="#FF000000"
|
||||
android:pathData="M12,7L12,3L2,3v18h20L22,7L12,7zM6,19L4,19v-2h2v2zM6,15L4,15v-2h2v2zM6,11L4,11L4,9h2v2zM6,7L4,7L4,5h2v2zM10,19L8,19v-2h2v2zM10,15L8,15v-2h2v2zM10,11L8,11L8,9h2v2zM10,7L8,7L8,5h2v2zM20,19h-8v-2h2v-2h-2v-2h2v-2h-2L12,9h8v10zM18,11h-2v2h2v-2zM18,15h-2v2h2v-2z" />
|
||||
</vector>
|
||||
@@ -1,11 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
|
||||
<import type="com.johan.evmap.api.ChargeLocation" />
|
||||
|
||||
<variable
|
||||
name="charger"
|
||||
type="ChargeLocation" />
|
||||
@@ -16,26 +17,42 @@
|
||||
</data>
|
||||
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout
|
||||
android:id="@+id/root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
android:fitsSystemWindows="false">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/map"
|
||||
android:name="com.google.android.gms.maps.SupportMapFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:context=".MapsActivity" />
|
||||
|
||||
<!--<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/appbarlayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay"
|
||||
app:layout_behavior="@string/ScrollingAppBarLayoutBehavior">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
</com.google.android.material.appbar.AppBarLayout>-->
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/gallery"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/gallery_height"
|
||||
android:background="?android:colorBackground"
|
||||
app:layout_behavior="@string/BackDropBottomSheetBehavior"
|
||||
android:fitsSystemWindows="true"
|
||||
app:data="@{charger.photos}"
|
||||
app:invisibleUnless="@{charger.photos != null && charger.photos.size() > 0}"
|
||||
app:data="@{charger.photos}" />
|
||||
app:layout_behavior="@string/BackDropBottomSheetBehavior" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_locate"
|
||||
@@ -52,16 +69,16 @@
|
||||
app:layout_behavior=".ui.HideOnScrollFabBehavior" />
|
||||
|
||||
<androidx.core.widget.NestedScrollView
|
||||
android:id="@+id/bottom_sheet"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
app:behavior_peekHeight="@dimen/peek_height"
|
||||
android:id="@+id/bottom_sheet"
|
||||
app:layout_behavior="@string/BottomSheetBehaviorGoogleMapsLike"
|
||||
app:anchorPoint="@dimen/gallery_height"
|
||||
app:defaultState="stateHidden"
|
||||
app:behavior_hideable="true"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical"
|
||||
app:anchorPoint="@dimen/gallery_height"
|
||||
app:behavior_hideable="true"
|
||||
app:behavior_peekHeight="@dimen/peek_height"
|
||||
app:defaultState="stateHidden"
|
||||
app:layout_behavior="@string/BottomSheetBehaviorGoogleMapsLike"
|
||||
tools:defaultState="stateCollapsed">
|
||||
|
||||
<include
|
||||
@@ -73,14 +90,20 @@
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_directions"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:src="@drawable/ic_directions"
|
||||
app:layout_anchor="@id/bottom_sheet"
|
||||
app:layout_anchorGravity="top|right|end"
|
||||
android:src="@drawable/ic_directions"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
app:layout_behavior="@string/ScrollAwareFABBehavior"
|
||||
android:clickable="true"
|
||||
android:focusable="true" />
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
app:layout_behavior="@string/ScrollAwareFABBehavior" />
|
||||
|
||||
<!--<com.mahc.custombottomsheetbehavior.MergedAppBarLayout
|
||||
android:id="@+id/mergedappbarlayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="@string/MergedAppBarLayoutBehavior"/>-->
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
</layout>
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
<import type="com.johan.evmap.api.ChargeLocation" />
|
||||
|
||||
<import type="com.johan.evmap.adapter.DataBindingAdaptersKt" />
|
||||
|
||||
<variable
|
||||
name="charger"
|
||||
type="ChargeLocation" />
|
||||
@@ -23,9 +25,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:background="?android:colorBackground"
|
||||
android:minHeight="600dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingTop="8dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="8dp">
|
||||
|
||||
<TextView
|
||||
@@ -36,8 +36,8 @@
|
||||
android:maxLines="1"
|
||||
android:text="@{charger.name}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Parkhaus" />
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
android:maxLines="1"
|
||||
android:text="@{charger.address.toString()}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView"
|
||||
tools:text="Beispielstraße 10, 12345 Berlin" />
|
||||
|
||||
@@ -62,8 +62,8 @@
|
||||
android:maxLines="1"
|
||||
android:text="@{charger.formatChargepoints()}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView2"
|
||||
tools:text="2x Typ 2 22 kW" />
|
||||
|
||||
@@ -71,28 +71,67 @@
|
||||
android:id="@+id/textView4"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@{charger.generalInformation}"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.937"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/connectors"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
tools:layout_editor_absoluteY="386dp"
|
||||
tools:text="Nur für Gäste." />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/connectors"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView3"
|
||||
app:data="@{charger.chargepoints}"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView7"
|
||||
tools:itemCount="3"
|
||||
tools:layoutManager="LinearLayoutManager"
|
||||
tools:listitem="@layout/item_connector"
|
||||
tools:orientation="horizontal" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView7"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/connectors"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
|
||||
android:textColor="?colorPrimary"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView3" />
|
||||
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_begin="16dp" />
|
||||
|
||||
<androidx.constraintlayout.widget.Guideline
|
||||
android:id="@+id/guideline2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintGuide_end="16dp" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/details"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:nestedScrollingEnabled="false"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="1.0"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/connectors"
|
||||
app:data="@{DataBindingAdaptersKt.buildDetails(charger, context)}"
|
||||
tools:itemCount="3"
|
||||
tools:listitem="@layout/item_detail" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
@@ -5,4 +5,5 @@
|
||||
android:layout_height="match_parent"
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
android:fitsSystemWindows="true"
|
||||
tools:srcCompat="@tools:sample/backgrounds/scenic" />
|
||||
@@ -20,11 +20,12 @@
|
||||
android:id="@+id/imageView"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:tint="?colorControlNormal"
|
||||
android:tintMode="src_in"
|
||||
android:contentDescription="@{item.type}"
|
||||
app:connectorIcon="@{item.type}"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
|
||||
47
app/src/main/res/layout/item_detail.xml
Normal file
47
app/src/main/res/layout/item_detail.xml
Normal file
@@ -0,0 +1,47 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<data>
|
||||
|
||||
<variable
|
||||
name="item"
|
||||
type="com.johan.evmap.adapter.DetailAdapter.Detail" />
|
||||
</data>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView9"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="19dp"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:maxLines="1"
|
||||
android:text="@{item.text}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/imageView3"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="Lorem ipsum" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:contentDescription="@{item.contentDescription}"
|
||||
android:tint="?colorPrimary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@{item.icon}"
|
||||
tools:srcCompat="@drawable/ic_address" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</layout>
|
||||
15
app/src/main/res/values-de/strings.xml
Normal file
15
app/src/main/res/values-de/strings.xml
Normal file
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">EV Map</string>
|
||||
<string name="title_activity_maps">Map</string>
|
||||
<string name="connectors">Anschlüsse</string>
|
||||
<string name="no_maps_app_found">Keine Navigations-App gefunden</string>
|
||||
<string name="address">Adresse</string>
|
||||
<string name="operator">Betreiber</string>
|
||||
<string name="network">Verbund</string>
|
||||
<string name="hours">Öffnungszeiten</string>
|
||||
<string name="open_247"><![CDATA[<b>24 Stunden geöffnet</b>]]></string>
|
||||
<string name="closed"><![CDATA[<b>Geschlossen</b>]]></string>
|
||||
<string name="open_closesat"><![CDATA[<b>Geöffnet</b> · Schließt um %s]]></string>
|
||||
<string name="closed_opensat"><![CDATA[<b>Geschlossen</b> · Öffnet um %s]]></string>
|
||||
</resources>
|
||||
@@ -1,8 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#6200EE</color>
|
||||
<color name="colorPrimaryDark">#3700B3</color>
|
||||
<color name="colorAccent">#03DAC5</color>
|
||||
<color name="colorPrimary">#4caf50</color>
|
||||
<color name="colorPrimaryVariant">#087f23</color>
|
||||
<color name="colorSecondary">#00e676</color>
|
||||
<color name="colorSecondaryVariant">#00b248</color>
|
||||
<color name="charger_100kw">#ffeb3b</color>
|
||||
<color name="charger_43kw">#ff9800</color>
|
||||
<color name="charger_20kw">#03a9f4</color>
|
||||
|
||||
@@ -1,4 +1,14 @@
|
||||
<resources>
|
||||
<string name="app_name">EV Map</string>
|
||||
<string name="title_activity_maps">Map</string>
|
||||
<string name="connectors">Connectors</string>
|
||||
<string name="no_maps_app_found">No navigation app found</string>
|
||||
<string name="address">Address</string>
|
||||
<string name="operator">Operator</string>
|
||||
<string name="network">Network</string>
|
||||
<string name="hours">Opening hours</string>
|
||||
<string name="open_247"><![CDATA[<b>Open 24/7</b>]]></string>
|
||||
<string name="closed"><![CDATA[<b>Closed</b>]]></string>
|
||||
<string name="open_closesat"><![CDATA[<b>Open</b> · Closes at %s]]></string>
|
||||
<string name="closed_opensat"><![CDATA[<b>Closed</b> · Opens at %s]]></string>
|
||||
</resources>
|
||||
|
||||
@@ -4,8 +4,12 @@
|
||||
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
<item name="colorPrimaryVariant">@color/colorPrimaryVariant</item>
|
||||
<item name="colorSecondary">@color/colorSecondary</item>
|
||||
<item name="colorSecondaryVariant">@color/colorSecondaryVariant</item>
|
||||
<item name="android:windowTranslucentStatus">true</item>
|
||||
<item name="android:navigationBarColor">@android:color/white</item>
|
||||
<item name="android:windowLightNavigationBar">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
Reference in New Issue
Block a user