Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
385aa46686 | ||
|
|
3c9a0b3a50 | ||
|
|
761a690d76 | ||
|
|
7356b8a1be | ||
|
|
0c0a1f59a6 | ||
|
|
876d2759dd | ||
|
|
ae489aa6ef | ||
|
|
d21ac0a781 | ||
|
|
b4baa87e10 | ||
|
|
05ffe1c265 | ||
|
|
8d68dd5366 | ||
|
|
dbcde7cf7a | ||
|
|
4ea37ee10d | ||
|
|
ec7b08338c | ||
|
|
dc4c2394f9 | ||
|
|
4b4ee807b0 | ||
|
|
c55720edc7 | ||
|
|
57ba8db799 | ||
|
|
3151d74d1a | ||
|
|
af0fb6762d | ||
|
|
5571c33ebe | ||
|
|
388952ae28 | ||
|
|
94934aa130 | ||
|
|
63eddde837 | ||
|
|
a9f735d783 | ||
|
|
2dcd04c86e | ||
|
|
9ed23c7000 | ||
|
|
79a7200f7b | ||
|
|
0c315079ca | ||
|
|
7943d6669c | ||
|
|
a781591510 | ||
|
|
b8ba06bab1 | ||
|
|
955b64ec66 | ||
|
|
117ab0f159 | ||
|
|
bac3fd1048 | ||
|
|
7cc07ca511 | ||
|
|
80743fab7d | ||
|
|
c423974ffd | ||
|
|
b2d365755f | ||
|
|
9df24081d4 | ||
|
|
255001b768 | ||
|
|
55af84b7de |
2
.gitattributes
vendored
@@ -1,2 +0,0 @@
|
||||
_img/screenshots/**/*.png filter=lfs diff=lfs merge=lfs -text
|
||||
fastlane/metadata/android/**/images/**/*.png filter=lfs diff=lfs merge=lfs -text
|
||||
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 972 KiB After Width: | Height: | Size: 844 KiB |
|
Before Width: | Height: | Size: 352 KiB After Width: | Height: | Size: 200 KiB |
|
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 113 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 837 KiB After Width: | Height: | Size: 844 KiB |
|
Before Width: | Height: | Size: 341 KiB After Width: | Height: | Size: 200 KiB |
|
Before Width: | Height: | Size: 94 KiB After Width: | Height: | Size: 93 KiB |
|
Before Width: | Height: | Size: 134 KiB After Width: | Height: | Size: 131 KiB |
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 972 KiB After Width: | Height: | Size: 841 KiB |
|
Before Width: | Height: | Size: 343 KiB After Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 124 KiB |
|
Before Width: | Height: | Size: 837 KiB After Width: | Height: | Size: 841 KiB |
|
Before Width: | Height: | Size: 330 KiB After Width: | Height: | Size: 199 KiB |
|
Before Width: | Height: | Size: 95 KiB After Width: | Height: | Size: 95 KiB |
|
Before Width: | Height: | Size: 122 KiB After Width: | Height: | Size: 124 KiB |
@@ -13,8 +13,8 @@ android {
|
||||
applicationId "net.vonforst.evmap"
|
||||
minSdkVersion 21
|
||||
targetSdkVersion 31
|
||||
versionCode 66
|
||||
versionName "1.1.2"
|
||||
versionCode 68
|
||||
versionName "1.2.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@@ -111,14 +111,14 @@ android {
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||
implementation 'androidx.appcompat:appcompat:1.4.0'
|
||||
implementation 'androidx.core:core-ktx:1.7.0'
|
||||
implementation 'androidx.core:core-splashscreen:1.0.0-alpha02'
|
||||
implementation "androidx.activity:activity-ktx:1.4.0"
|
||||
implementation "androidx.fragment:fragment-ktx:1.3.6"
|
||||
implementation "androidx.fragment:fragment-ktx:1.4.0"
|
||||
implementation 'androidx.cardview:cardview:1.0.0'
|
||||
implementation 'androidx.preference:preference-ktx:1.1.1'
|
||||
implementation 'com.google.android.material:material:1.4.0'
|
||||
implementation 'com.google.android.material:material:1.5.0-rc01'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
|
||||
implementation 'androidx.recyclerview:recyclerview:1.2.1'
|
||||
implementation 'androidx.browser:browser:1.4.0'
|
||||
@@ -127,8 +127,8 @@ dependencies {
|
||||
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp-urlconnection:4.9.0'
|
||||
implementation 'com.squareup.moshi:moshi-kotlin:1.12.0'
|
||||
implementation 'com.squareup.moshi:moshi-adapters:1.12.0'
|
||||
implementation 'com.squareup.moshi:moshi-kotlin:1.13.0'
|
||||
implementation 'com.squareup.moshi:moshi-adapters:1.13.0'
|
||||
implementation 'moe.banana:moshi-jsonapi:3.5.0'
|
||||
implementation 'moe.banana:moshi-jsonapi-retrofit-converter:3.5.0'
|
||||
implementation 'io.coil-kt:coil:1.1.0'
|
||||
@@ -143,14 +143,14 @@ dependencies {
|
||||
implementation 'com.github.romandanylyk:PageIndicatorView:b1bad589b5'
|
||||
|
||||
// Android Auto
|
||||
googleImplementation 'androidx.car.app:app:1.1.0-rc01'
|
||||
googleImplementation 'androidx.car.app:app-projected:1.1.0-rc01'
|
||||
googleImplementation 'androidx.car.app:app:1.2.0-alpha02'
|
||||
googleImplementation 'androidx.car.app:app-projected:1.2.0-alpha02'
|
||||
|
||||
// AnyMaps
|
||||
def anyMapsVersion = '751daec281'
|
||||
implementation "com.github.johan12345.AnyMaps:anymaps-base:$anyMapsVersion"
|
||||
googleImplementation "com.github.johan12345.AnyMaps:anymaps-google:$anyMapsVersion"
|
||||
googleImplementation 'com.google.android.gms:play-services-maps:18.0.0'
|
||||
googleImplementation 'com.google.android.gms:play-services-maps:18.0.1'
|
||||
implementation "com.github.johan12345.AnyMaps:anymaps-mapbox:$anyMapsVersion"
|
||||
|
||||
// Google Places
|
||||
@@ -170,7 +170,7 @@ dependencies {
|
||||
implementation "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycle_version"
|
||||
|
||||
// room library
|
||||
def room_version = "2.3.0"
|
||||
def room_version = "2.4.0"
|
||||
implementation "androidx.room:room-runtime:$room_version"
|
||||
kapt "androidx.room:room-compiler:$room_version"
|
||||
implementation "androidx.room:room-ktx:$room_version"
|
||||
@@ -196,7 +196,7 @@ dependencies {
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
|
||||
|
||||
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.12.0"
|
||||
kapt "com.squareup.moshi:moshi-kotlin-codegen:1.13.0"
|
||||
|
||||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import net.vonforst.evmap.MapsActivity
|
||||
import net.vonforst.evmap.R
|
||||
import net.vonforst.evmap.databinding.FragmentDonateBinding
|
||||
@@ -15,11 +16,17 @@ import net.vonforst.evmap.databinding.FragmentDonateBinding
|
||||
class DonateFragment : Fragment() {
|
||||
private lateinit var binding: FragmentDonateBinding
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
): View {
|
||||
binding = FragmentDonateBinding.inflate(inflater, container, false)
|
||||
return binding.root
|
||||
}
|
||||
@@ -27,16 +34,13 @@ class DonateFragment : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
(requireActivity() as AppCompatActivity).setSupportActionBar(binding.toolbar)
|
||||
|
||||
binding.btnDonate.setOnClickListener {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.paypal_link))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
binding.btnDonate.setOnClickListener {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.paypal_link))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnDonate"
|
||||
style="@style/Widget.MaterialComponents.Button.Icon"
|
||||
style="@style/Widget.Material3.Button.Icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
|
||||
4
app/src/foss/res/xml/settings_variantspecific.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen>
|
||||
|
||||
</PreferenceScreen>
|
||||
@@ -8,6 +8,7 @@ import androidx.car.app.CarContext
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.Session
|
||||
import androidx.car.app.hardware.CarHardwareManager
|
||||
import androidx.car.app.hardware.common.CarValue
|
||||
import androidx.car.app.hardware.info.CarHardwareLocation
|
||||
import androidx.car.app.hardware.info.CarSensors
|
||||
import androidx.car.app.validation.HostValidator
|
||||
@@ -90,11 +91,13 @@ class EVMapSession(val cas: CarAppService) : Session(), LifecycleObserver {
|
||||
}
|
||||
|
||||
private fun onCarHardwareLocationReceived(loc: CarHardwareLocation) {
|
||||
updateLocation(loc.location.value)
|
||||
if (loc.location.status == CarValue.STATUS_SUCCESS && loc.location.value != null) {
|
||||
updateLocation(loc.location.value)
|
||||
|
||||
// we successfully received a location from the car hardware,
|
||||
// so we don't need the smartphone location anymore.
|
||||
unbindLocationService()
|
||||
// we successfully received a location from the car hardware,
|
||||
// so we don't need the smartphone location anymore.
|
||||
unbindLocationService()
|
||||
}
|
||||
}
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_START)
|
||||
|
||||
19
app/src/google/java/net/vonforst/evmap/auto/CarModels.kt
Normal file
@@ -0,0 +1,19 @@
|
||||
package net.vonforst.evmap.auto
|
||||
|
||||
/**
|
||||
* This file lists known mappings between the vehicle model provided by Android Auto's CarInfo API
|
||||
* and human-readable vehicle models as listed by Chargeprice in their vehicle database.
|
||||
*/
|
||||
|
||||
private val models = mapOf(
|
||||
"Audi" to mapOf(
|
||||
"516 (G4x)" to "e-tron"
|
||||
)
|
||||
)
|
||||
|
||||
fun getVehicleModel(manufacturer: String?, model: String?) =
|
||||
if (manufacturer != null && model != null) {
|
||||
models[manufacturer]?.get(model) ?: model
|
||||
} else {
|
||||
null
|
||||
}
|
||||
@@ -8,6 +8,7 @@ import androidx.browser.customtabs.CustomTabsIntent
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.constraints.ConstraintManager
|
||||
import androidx.car.app.hardware.CarHardwareManager
|
||||
import androidx.car.app.hardware.info.Model
|
||||
import androidx.car.app.model.*
|
||||
@@ -37,9 +38,11 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c
|
||||
}
|
||||
private var prices: List<ChargePrice>? = null
|
||||
private var meta: ChargepriceChargepointMeta? = null
|
||||
private val maxRows = 6
|
||||
private val maxRows = if (ctx.carAppApiLevel >= 2) {
|
||||
ctx.constraintManager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_LIST)
|
||||
} else 6
|
||||
private var errorMessage: String? = null
|
||||
private val batteryRange = listOf(20.0, 80.0)
|
||||
private val batteryRange = prefs.chargepriceBatteryRangeAndroidAuto
|
||||
|
||||
override fun onGetTemplate(): Template {
|
||||
if (prices == null) loadData()
|
||||
@@ -168,47 +171,10 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c
|
||||
private fun loadPrices(model: Model?) {
|
||||
val dataAdapter = getDataAdapter() ?: return
|
||||
val manufacturer = model?.manufacturer?.value
|
||||
val modelName = model?.name?.value
|
||||
val modelName = getVehicleModel(model?.manufacturer?.value, model?.name?.value)
|
||||
lifecycleScope.launch {
|
||||
try {
|
||||
var vehicles = api.getVehicles().filter {
|
||||
it.id in prefs.chargepriceMyVehicles
|
||||
}
|
||||
if (vehicles.isEmpty()) {
|
||||
errorMessage = carContext.getString(R.string.chargeprice_select_car_first)
|
||||
invalidate()
|
||||
return@launch
|
||||
} else if (vehicles.size > 1) {
|
||||
if (manufacturer != null && modelName != null) {
|
||||
vehicles = vehicles.filter {
|
||||
it.brand == manufacturer && it.name.startsWith(modelName)
|
||||
}
|
||||
if (vehicles.isEmpty()) {
|
||||
errorMessage = carContext.getString(
|
||||
R.string.auto_chargeprice_vehicle_unknown,
|
||||
manufacturer,
|
||||
modelName
|
||||
)
|
||||
invalidate()
|
||||
return@launch
|
||||
} else if (vehicles.size > 1) {
|
||||
errorMessage = carContext.getString(
|
||||
R.string.auto_chargeprice_vehicle_ambiguous,
|
||||
manufacturer,
|
||||
modelName
|
||||
)
|
||||
invalidate()
|
||||
return@launch
|
||||
}
|
||||
} else {
|
||||
errorMessage =
|
||||
carContext.getString(R.string.auto_chargeprice_vehicle_unavailable)
|
||||
invalidate()
|
||||
return@launch
|
||||
}
|
||||
}
|
||||
val car = vehicles[0]
|
||||
|
||||
val car = determineVehicle(manufacturer, modelName)
|
||||
val cpStation = ChargepriceStation.fromEvmap(charger, car.compatibleEvmapConnectors)
|
||||
val result = api.getChargePrices(ChargepriceRequest().apply {
|
||||
this.dataAdapter = dataAdapter
|
||||
@@ -229,7 +195,7 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c
|
||||
}
|
||||
} else null
|
||||
options = ChargepriceOptions(
|
||||
batteryRange = batteryRange,
|
||||
batteryRange = batteryRange.map { it.toDouble() },
|
||||
providerCustomerTariffs = prefs.chargepriceShowProviderCustomerTariffs,
|
||||
maxMonthlyFees = if (prefs.chargepriceNoBaseFee) 0.0 else null,
|
||||
currency = prefs.chargepriceCurrency
|
||||
@@ -283,10 +249,73 @@ class ChargepriceScreen(ctx: CarContext, val charger: ChargeLocation) : Screen(c
|
||||
)
|
||||
.show()
|
||||
}
|
||||
} catch (e: NoVehicleSelectedException) {
|
||||
errorMessage = carContext.getString(R.string.chargeprice_select_car_first)
|
||||
invalidate()
|
||||
} catch (e: VehicleUnknownException) {
|
||||
errorMessage = carContext.getString(
|
||||
R.string.auto_chargeprice_vehicle_unknown,
|
||||
manufacturer,
|
||||
modelName
|
||||
)
|
||||
invalidate()
|
||||
} catch (e: VehicleAmbiguousException) {
|
||||
errorMessage = carContext.getString(
|
||||
R.string.auto_chargeprice_vehicle_ambiguous,
|
||||
manufacturer,
|
||||
modelName
|
||||
)
|
||||
invalidate()
|
||||
} catch (e: VehicleUnavailableException) {
|
||||
errorMessage =
|
||||
carContext.getString(R.string.auto_chargeprice_vehicle_unavailable)
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class NoVehicleSelectedException : Exception()
|
||||
private class VehicleUnknownException : Exception()
|
||||
private class VehicleAmbiguousException : Exception()
|
||||
private class VehicleUnavailableException : Exception()
|
||||
|
||||
private suspend fun determineVehicle(
|
||||
manufacturer: String?,
|
||||
modelName: String?
|
||||
): ChargepriceCar {
|
||||
var vehicles = api.getVehicles().filter {
|
||||
it.id in prefs.chargepriceMyVehicles
|
||||
}
|
||||
if (vehicles.isEmpty()) {
|
||||
throw NoVehicleSelectedException()
|
||||
} else if (vehicles.size > 1) {
|
||||
if (manufacturer != null) {
|
||||
vehicles = vehicles.filter {
|
||||
it.brand == manufacturer
|
||||
}
|
||||
if (vehicles.isEmpty()) {
|
||||
throw VehicleUnknownException()
|
||||
} else if (vehicles.size > 1) {
|
||||
if (modelName != null) {
|
||||
vehicles = vehicles.filter {
|
||||
it.name.startsWith(modelName)
|
||||
}
|
||||
if (vehicles.isEmpty()) {
|
||||
throw VehicleUnknownException()
|
||||
} else if (vehicles.size > 1) {
|
||||
throw VehicleAmbiguousException()
|
||||
}
|
||||
} else {
|
||||
throw VehicleAmbiguousException()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw VehicleUnavailableException()
|
||||
}
|
||||
}
|
||||
return vehicles[0]
|
||||
}
|
||||
|
||||
private fun getDataAdapter(): String? = when (charger.dataSource) {
|
||||
"goingelectric" -> ChargepriceApi.DATA_SOURCE_GOINGELECTRIC
|
||||
"openchargemap" -> ChargepriceApi.DATA_SOURCE_OPENCHARGEMAP
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.vonforst.evmap.auto
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.drawable.BitmapDrawable
|
||||
import android.net.Uri
|
||||
import android.text.SpannableStringBuilder
|
||||
@@ -9,8 +10,11 @@ import android.text.Spanned
|
||||
import androidx.car.app.CarContext
|
||||
import androidx.car.app.CarToast
|
||||
import androidx.car.app.Screen
|
||||
import androidx.car.app.constraints.ConstraintManager
|
||||
import androidx.car.app.model.*
|
||||
import androidx.core.graphics.drawable.IconCompat
|
||||
import androidx.core.graphics.scale
|
||||
import androidx.core.text.HtmlCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import coil.imageLoader
|
||||
import coil.request.ImageRequest
|
||||
@@ -50,10 +54,18 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
|
||||
private val referenceData = api.getReferenceData(lifecycleScope, carContext)
|
||||
|
||||
private val imageSize = 128 // images should be 128dp according to docs
|
||||
private val imageHeightLarge = 480 // images should be 480 x 854 dp according to docs
|
||||
private val imageWidthLarge = 854
|
||||
|
||||
private val iconGen =
|
||||
ChargerIconGenerator(carContext, null, oversize = 1.4f, height = imageSize)
|
||||
|
||||
private val maxRows = if (ctx.carAppApiLevel >= 2) {
|
||||
ctx.constraintManager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_PANE)
|
||||
} else 2
|
||||
private val largeImageSupported =
|
||||
ctx.carAppApiLevel >= 4 // since API 4, Row.setImage is supported
|
||||
|
||||
init {
|
||||
referenceData.observe(this) {
|
||||
loadCharger()
|
||||
@@ -66,86 +78,21 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
|
||||
return PaneTemplate.Builder(
|
||||
Pane.Builder().apply {
|
||||
charger?.let { charger ->
|
||||
addRow(Row.Builder().apply {
|
||||
setTitle(charger.address.toString())
|
||||
|
||||
val icon = iconGen.getBitmap(
|
||||
tint = getMarkerTint(charger),
|
||||
fault = charger.faultReport != null,
|
||||
multi = charger.isMulti()
|
||||
)
|
||||
setImage(
|
||||
CarIcon.Builder(IconCompat.createWithBitmap(icon)).build(),
|
||||
Row.IMAGE_TYPE_LARGE
|
||||
)
|
||||
|
||||
val chargepointsText = SpannableStringBuilder()
|
||||
charger.chargepointsMerged.forEachIndexed { i, cp ->
|
||||
if (i > 0) chargepointsText.append(" · ")
|
||||
chargepointsText.append(
|
||||
"${cp.count}× ${
|
||||
nameForPlugType(
|
||||
carContext.stringProvider(),
|
||||
cp.type
|
||||
if (largeImageSupported && photo != null) {
|
||||
setImage(CarIcon.Builder(IconCompat.createWithBitmap(photo)).build())
|
||||
}
|
||||
generateRows(charger).forEach { addRow(it) }
|
||||
addAction(
|
||||
Action.Builder()
|
||||
.setIcon(
|
||||
CarIcon.Builder(
|
||||
IconCompat.createWithResource(
|
||||
carContext,
|
||||
R.drawable.ic_navigation
|
||||
)
|
||||
} ${cp.formatPower()}"
|
||||
).build()
|
||||
)
|
||||
availability?.status?.get(cp)?.let { status ->
|
||||
chargepointsText.append(
|
||||
" (${availabilityText(status)}/${cp.count})",
|
||||
ForegroundCarColorSpan.create(carAvailabilityColor(status)),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
}
|
||||
addText(chargepointsText)
|
||||
}.build())
|
||||
addRow(Row.Builder().apply {
|
||||
photo?.let {
|
||||
setImage(
|
||||
CarIcon.Builder(IconCompat.createWithBitmap(photo)).build(),
|
||||
Row.IMAGE_TYPE_LARGE
|
||||
)
|
||||
}
|
||||
val operatorText = StringBuilder().apply {
|
||||
charger.operator?.let { append(it) }
|
||||
charger.network?.let {
|
||||
if (isNotEmpty()) append(" · ")
|
||||
append(it)
|
||||
}
|
||||
}.ifEmpty {
|
||||
carContext.getString(R.string.unknown_operator)
|
||||
}
|
||||
setTitle(operatorText)
|
||||
|
||||
charger.cost?.let { addText(it.getStatusText(carContext, emoji = true)) }
|
||||
charger.faultReport?.created?.let {
|
||||
addText(
|
||||
carContext.getString(
|
||||
R.string.auto_fault_report_date,
|
||||
it.atZone(ZoneId.systemDefault())
|
||||
.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/*val types = charger.chargepoints.map { it.type }.distinct()
|
||||
if (types.size == 1) {
|
||||
setImage(
|
||||
CarIcon.of(IconCompat.createWithResource(carContext, iconForPlugType(types[0]))),
|
||||
Row.IMAGE_TYPE_ICON)
|
||||
}*/
|
||||
}.build())
|
||||
addAction(Action.Builder()
|
||||
.setIcon(
|
||||
CarIcon.Builder(
|
||||
IconCompat.createWithResource(
|
||||
carContext,
|
||||
R.drawable.ic_navigation
|
||||
)
|
||||
).build()
|
||||
)
|
||||
.setTitle(carContext.getString(R.string.navigate))
|
||||
.setTitle(carContext.getString(R.string.navigate))
|
||||
.setBackgroundColor(CarColor.PRIMARY)
|
||||
.setOnClickListener {
|
||||
navigateToCharger(charger)
|
||||
@@ -197,6 +144,144 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
|
||||
}.build()
|
||||
}
|
||||
|
||||
private fun generateRows(charger: ChargeLocation): List<Row> {
|
||||
val rows = mutableListOf<Row>()
|
||||
|
||||
// Row 1: address + chargepoints
|
||||
rows.add(Row.Builder().apply {
|
||||
setTitle(charger.address.toString())
|
||||
|
||||
if (photo == null) {
|
||||
// show just the icon
|
||||
val icon = iconGen.getBitmap(
|
||||
tint = getMarkerTint(charger),
|
||||
fault = charger.faultReport != null,
|
||||
multi = charger.isMulti()
|
||||
)
|
||||
setImage(
|
||||
CarIcon.Builder(IconCompat.createWithBitmap(icon)).build(),
|
||||
Row.IMAGE_TYPE_LARGE
|
||||
)
|
||||
} else if (!largeImageSupported) {
|
||||
// show the photo with icon
|
||||
setImage(
|
||||
CarIcon.Builder(IconCompat.createWithBitmap(photo)).build(),
|
||||
Row.IMAGE_TYPE_LARGE
|
||||
)
|
||||
}
|
||||
addText(generateChargepointsText(charger))
|
||||
}.build())
|
||||
if (maxRows <= 3) {
|
||||
// row 2: operator + cost + fault report
|
||||
rows.add(Row.Builder().apply {
|
||||
if (photo != null && !largeImageSupported) {
|
||||
setImage(
|
||||
CarIcon.Builder(IconCompat.createWithBitmap(photo)).build(),
|
||||
Row.IMAGE_TYPE_LARGE
|
||||
)
|
||||
}
|
||||
val operatorText = generateOperatorText(charger)
|
||||
setTitle(operatorText)
|
||||
|
||||
charger.cost?.let { addText(it.getStatusText(carContext, emoji = true)) }
|
||||
charger.faultReport?.let { fault ->
|
||||
addText(
|
||||
carContext.getString(
|
||||
R.string.auto_fault_report_date,
|
||||
fault.created?.atZone(ZoneId.systemDefault())
|
||||
?.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))
|
||||
)
|
||||
)
|
||||
}
|
||||
}.build())
|
||||
} else {
|
||||
// row 2: operator + cost + cost description
|
||||
rows.add(Row.Builder().apply {
|
||||
if (photo != null && !largeImageSupported) {
|
||||
setImage(
|
||||
CarIcon.Builder(IconCompat.createWithBitmap(photo)).build(),
|
||||
Row.IMAGE_TYPE_LARGE
|
||||
)
|
||||
}
|
||||
val operatorText = generateOperatorText(charger)
|
||||
setTitle(operatorText)
|
||||
charger.cost?.let {
|
||||
addText(it.getStatusText(carContext, emoji = true))
|
||||
(it.descriptionShort ?: it.descriptionLong)?.let { addText(it) }
|
||||
}
|
||||
}.build())
|
||||
// row 3: fault report (if exists)
|
||||
charger.faultReport?.let { fault ->
|
||||
rows.add(Row.Builder().apply {
|
||||
setTitle(
|
||||
carContext.getString(
|
||||
R.string.auto_fault_report_date,
|
||||
fault.created?.atZone(ZoneId.systemDefault())
|
||||
?.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT))
|
||||
)
|
||||
)
|
||||
fault.description?.let {
|
||||
addText(
|
||||
HtmlCompat.fromHtml(
|
||||
it.replace("\n", " · "),
|
||||
HtmlCompat.FROM_HTML_MODE_LEGACY
|
||||
)
|
||||
)
|
||||
}
|
||||
}.build())
|
||||
}
|
||||
// row 4: opening hours + location description
|
||||
charger.openinghours?.let { hours ->
|
||||
rows.add(Row.Builder().apply {
|
||||
setTitle(hours.getStatusText(carContext))
|
||||
hours.description?.let { addText(it) }
|
||||
charger.locationDescription?.let { addText(it) }
|
||||
}.build())
|
||||
}
|
||||
}
|
||||
return rows
|
||||
}
|
||||
|
||||
private fun generateChargepointsText(charger: ChargeLocation): SpannableStringBuilder {
|
||||
val chargepointsText = SpannableStringBuilder()
|
||||
charger.chargepointsMerged.forEachIndexed { i, cp ->
|
||||
if (i > 0) chargepointsText.append(" · ")
|
||||
chargepointsText.append(
|
||||
"${cp.count}× ${
|
||||
nameForPlugType(
|
||||
carContext.stringProvider(),
|
||||
cp.type
|
||||
)
|
||||
} ${cp.formatPower()}"
|
||||
)
|
||||
availability?.status?.get(cp)?.let { status ->
|
||||
chargepointsText.append(
|
||||
" (${availabilityText(status)}/${cp.count})",
|
||||
ForegroundCarColorSpan.create(carAvailabilityColor(status)),
|
||||
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
|
||||
)
|
||||
}
|
||||
}
|
||||
return chargepointsText
|
||||
}
|
||||
|
||||
private fun generateOperatorText(charger: ChargeLocation) =
|
||||
if (charger.operator != null && charger.network != null) {
|
||||
if (charger.operator.contains(charger.network)) {
|
||||
charger.operator
|
||||
} else if (charger.network.contains(charger.operator)) {
|
||||
charger.network
|
||||
} else {
|
||||
"${charger.operator} · ${charger.network}"
|
||||
}
|
||||
} else if (charger.operator != null) {
|
||||
charger.operator
|
||||
} else if (charger.network != null) {
|
||||
charger.network
|
||||
} else {
|
||||
carContext.getString(R.string.unknown_operator)
|
||||
}
|
||||
|
||||
private fun navigateToCharger(charger: ChargeLocation) {
|
||||
val coord = charger.coordinates
|
||||
val intent =
|
||||
@@ -212,18 +297,47 @@ class ChargerDetailScreen(ctx: CarContext, val chargerSparse: ChargeLocation) :
|
||||
lifecycleScope.launch {
|
||||
val response = api.getChargepointDetail(referenceData, chargerSparse.id)
|
||||
if (response.status == Status.SUCCESS) {
|
||||
charger = response.data!!
|
||||
val charger = response.data!!
|
||||
|
||||
val photo = charger?.photos?.firstOrNull()
|
||||
val photo = charger.photos?.firstOrNull()
|
||||
photo?.let {
|
||||
val size = (carContext.resources.displayMetrics.density * 64).roundToInt()
|
||||
val url = photo.getUrl(size = size)
|
||||
val density = carContext.resources.displayMetrics.density
|
||||
val url = if (largeImageSupported) {
|
||||
photo.getUrl(
|
||||
width = (imageWidthLarge * density).roundToInt(),
|
||||
height = (imageHeightLarge * density).roundToInt()
|
||||
)
|
||||
} else {
|
||||
photo.getUrl(size = (imageSize * density).roundToInt())
|
||||
}
|
||||
val request = ImageRequest.Builder(carContext).data(url).build()
|
||||
this@ChargerDetailScreen.photo =
|
||||
var img =
|
||||
(carContext.imageLoader.execute(request).drawable as BitmapDrawable).bitmap
|
||||
}
|
||||
|
||||
availability = charger?.let { getAvailability(it).data }
|
||||
// draw icon on top of image
|
||||
val icon = iconGen.getBitmap(
|
||||
tint = getMarkerTint(charger),
|
||||
fault = charger.faultReport != null,
|
||||
multi = charger.isMulti()
|
||||
)
|
||||
|
||||
img = img.copy(Bitmap.Config.ARGB_8888, true)
|
||||
val iconSmall = icon.scale(
|
||||
(img.height * 0.4 / icon.height * icon.width).roundToInt(),
|
||||
(img.height * 0.4).roundToInt()
|
||||
)
|
||||
val canvas = Canvas(img)
|
||||
canvas.drawBitmap(
|
||||
iconSmall,
|
||||
0f,
|
||||
(img.height - iconSmall.height * 1.1).toFloat(),
|
||||
null
|
||||
)
|
||||
this@ChargerDetailScreen.photo = img
|
||||
}
|
||||
this@ChargerDetailScreen.charger = charger
|
||||
|
||||
availability = getAvailability(charger).data
|
||||
|
||||
invalidate()
|
||||
} else {
|
||||
|
||||
@@ -59,7 +59,12 @@ class VehicleDataScreen(ctx: CarContext) : Screen(ctx), LifecycleObserver {
|
||||
return GridTemplate.Builder().apply {
|
||||
setTitle(
|
||||
if (model != null && model.manufacturer.value != null && model.name.value != null) {
|
||||
"${model.manufacturer.value} ${model.name.value}"
|
||||
"${model.manufacturer.value} ${
|
||||
getVehicleModel(
|
||||
model.manufacturer.value,
|
||||
model.name.value
|
||||
)
|
||||
}"
|
||||
} else {
|
||||
carContext.getString(R.string.auto_vehicle_data)
|
||||
}
|
||||
|
||||
@@ -12,7 +12,9 @@ import androidx.lifecycle.Observer
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import net.vonforst.evmap.MapsActivity
|
||||
import net.vonforst.evmap.R
|
||||
import net.vonforst.evmap.adapter.DonationAdapter
|
||||
@@ -23,6 +25,12 @@ class DonateFragment : Fragment() {
|
||||
private lateinit var binding: FragmentDonateBinding
|
||||
private val vm: DonateViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@@ -31,12 +39,18 @@ class DonateFragment : Fragment() {
|
||||
binding = DataBindingUtil.inflate(inflater, R.layout.fragment_donate, container, false)
|
||||
binding.lifecycleOwner = this
|
||||
binding.vm = vm
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
(requireActivity() as AppCompatActivity).setSupportActionBar(binding.toolbar)
|
||||
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
binding.productsList.apply {
|
||||
adapter = DonationAdapter().apply {
|
||||
onClickListener = {
|
||||
@@ -56,13 +70,8 @@ class DonateFragment : Fragment() {
|
||||
vm.purchaseFailed.observe(viewLifecycleOwner, Observer {
|
||||
Snackbar.make(view, R.string.donation_failed, Snackbar.LENGTH_LONG).show()
|
||||
})
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
// Workaround for AndroidX bug: https://github.com/material-components/material-components-android/issues/1984
|
||||
view.setBackgroundColor(MaterialColors.getColor(view, android.R.attr.windowBackground))
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package net.vonforst.evmap.fragment.preference
|
||||
|
||||
import android.content.SharedPreferences
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.preference.MultiSelectListPreference
|
||||
import net.vonforst.evmap.R
|
||||
import net.vonforst.evmap.ui.RangeSliderPreference
|
||||
import net.vonforst.evmap.viewmodel.SettingsViewModel
|
||||
import net.vonforst.evmap.viewmodel.viewModelFactory
|
||||
import java.text.NumberFormat
|
||||
|
||||
class AndroidAutoSettingsFragment : BaseSettingsFragment() {
|
||||
override val isTopLevel = false
|
||||
|
||||
private lateinit var rangePreference: RangeSliderPreference
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
rangePreference = findPreference("chargeprice_battery_range_android_auto")!!
|
||||
rangePreference.labelFormatter = { value: Float ->
|
||||
val fmt = NumberFormat.getNumberInstance()
|
||||
fmt.maximumFractionDigits = 0
|
||||
fmt.format(value.toDouble()) + "%"
|
||||
}
|
||||
updateRangePreferenceSummary()
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.settings_android_auto, rootKey)
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
when (key) {
|
||||
"chargeprice_battery_range_android_auto_min", "chargeprice_battery_range_android_auto_max" -> {
|
||||
updateRangePreferenceSummary()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateRangePreferenceSummary() {
|
||||
val range = prefs.chargepriceBatteryRangeAndroidAuto
|
||||
rangePreference.summary = getString(R.string.chargeprice_battery_range, range[0], range[1])
|
||||
}
|
||||
}
|
||||
10
app/src/google/res/drawable/ic_android_auto.xml
Normal file
@@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="m22.78,17.91c0.16,0.25 0.22,0.51 0.22,0.79 0,0.38 -0.13,0.69 -0.43,0.94s-0.63,0.36 -1.01,0.36h-2.48l-6.66,-12h-0.84l-6.66,12h-2.53c-0.47,0 -0.86,-0.2 -1.17,-0.62s-0.33,-0.88 -0.05,-1.38l9.61,-16.31c0.31,-0.47 0.72,-0.69 1.22,-0.69 0.53,0 0.92,0.22 1.17,0.69zM4.78,22.31 L12,9.38 19.22,22.31 18.5,23 12,20.34 5.44,23z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="72dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/welcome_android_auto"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/img_android_auto" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="56dp"
|
||||
android:breakStrategy="balanced"
|
||||
android:text="@string/welcome_android_auto_detail"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/welcomeTitle" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="@string/sounds_cool"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/welcomeText" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img_android_auto"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:layout_marginStart="72dp"
|
||||
android:layout_marginBottom="28dp"
|
||||
android:background="@drawable/circle_bg_logo"
|
||||
android:backgroundTint="@color/android_auto_accent"
|
||||
android:scaleType="center"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.65"
|
||||
app:srcCompat="@drawable/android_auto" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_android_auto"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="56dp"
|
||||
android:breakStrategy="balanced"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_android_auto_detail"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="@string/sounds_cool"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/img_android_auto"
|
||||
android:layout_width="72dp"
|
||||
android:layout_height="72dp"
|
||||
android:layout_marginTop="28dp"
|
||||
android:layout_marginBottom="28dp"
|
||||
android:background="@drawable/circle_bg_logo"
|
||||
android:backgroundTint="@color/android_auto_accent"
|
||||
android:scaleType="center"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeTitle"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.7"
|
||||
app:srcCompat="@drawable/android_auto" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -13,7 +13,7 @@
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_android_auto"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
@@ -29,7 +29,7 @@
|
||||
android:breakStrategy="balanced"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_android_auto_detail"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:text="@{item.sku.title}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/textView21"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
@@ -42,7 +42,7 @@
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{item.sku.price}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
<string name="welcome_android_auto_detail">Auf unterstützen Autos kannst du EVMap auch mit Android Auto nutzen. Öffne dazu einfach die EVMap-App aus dem Menü von Android Auto.</string>
|
||||
<string name="sounds_cool">klingt cool</string>
|
||||
<string name="auto_chargeprice_vehicle_unavailable">EVMap konnte das Fahrzeugmodell nicht erkennen.</string>
|
||||
<string name="auto_chargeprice_vehicle_unknown">Keins der in der App ausgewählten Fahrzeuge passt zu diesem Fahrzeug (%s %s).</string>
|
||||
<string name="auto_chargeprice_vehicle_ambiguous">Mehrere der in der App ausgewählten Fahrzeuge passen zu diesem Fahrzeug (%s %s).</string>
|
||||
<string name="auto_chargeprice_vehicle_unknown">Keins der in der App ausgewählten Fahrzeuge passt zu diesem Fahrzeug (%1$s %2$s).</string>
|
||||
<string name="auto_chargeprice_vehicle_ambiguous">Mehrere der in der App ausgewählten Fahrzeuge passen zu diesem Fahrzeug (%1$s %2$s).</string>
|
||||
<string name="settings_android_auto_chargeprice_range">Ladebereich für Preisvergleich</string>
|
||||
</resources>
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
<style name="CarAppTheme">
|
||||
<item name="carColorPrimary">@color/colorPrimary</item>
|
||||
<item name="carColorPrimaryDark">@color/colorPrimaryVariant</item>
|
||||
<item name="carColorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="carColorSecondary">@color/colorSecondary</item>
|
||||
<item name="carColorSecondaryDark">@color/colorSecondaryVariant</item>
|
||||
<item name="carColorSecondaryDark">@color/colorSecondaryDark</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -41,6 +41,7 @@
|
||||
<string name="welcome_android_auto_detail">You can also use EVMap from within Android Auto on supported cars. Simply select the EVMap app in the Android Auto menu.</string>
|
||||
<string name="sounds_cool">sounds cool</string>
|
||||
<string name="auto_chargeprice_vehicle_unavailable">EVMap could not determine your vehicle model.</string>
|
||||
<string name="auto_chargeprice_vehicle_unknown">None of the vehicles selected in the app matches this vehicle (%s %s).</string>
|
||||
<string name="auto_chargeprice_vehicle_ambiguous">Mehrere der in der App ausgewählten Fahrzeuge passen zu diesem Fahrzeug (%s %s).</string>
|
||||
<string name="auto_chargeprice_vehicle_unknown">None of the vehicles selected in the app matches this vehicle (%1$s %2$s).</string>
|
||||
<string name="auto_chargeprice_vehicle_ambiguous">Mehrere der in der App ausgewählten Fahrzeuge passen zu diesem Fahrzeug (%1$s %2$s).</string>
|
||||
<string name="settings_android_auto_chargeprice_range">Charging range for price comparison</string>
|
||||
</resources>
|
||||
14
app/src/google/res/xml/settings_android_auto.xml
Normal file
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen 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">
|
||||
<net.vonforst.evmap.ui.RangeSliderPreference
|
||||
android:key="chargeprice_battery_range_android_auto"
|
||||
android:title="@string/settings_android_auto_chargeprice_range"
|
||||
android:valueFrom="0.0"
|
||||
android:valueTo="100.0"
|
||||
app:updatesContinuously="true"
|
||||
android:defaultValue="20.0,80.0"
|
||||
android:layout="@layout/preference_widget_rangeslider"
|
||||
tools:summary="@string/chargeprice_battery_range" />
|
||||
</PreferenceScreen>
|
||||
7
app/src/google/res/xml/settings_variantspecific.xml
Normal file
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<Preference
|
||||
android:fragment="net.vonforst.evmap.fragment.preference.AndroidAutoSettingsFragment"
|
||||
android:title="@string/settings_android_auto"
|
||||
android:icon="@drawable/ic_android_auto" />
|
||||
</PreferenceScreen>
|
||||
@@ -256,6 +256,10 @@
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
</intent-filter>
|
||||
|
||||
<meta-data
|
||||
android:name="android.app.shortcuts"
|
||||
android:resource="@xml/shortcuts" />
|
||||
</activity>
|
||||
|
||||
<!-- Override services of the com.mapzen.android.lost library with exported:false
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package net.vonforst.evmap
|
||||
|
||||
import android.app.PendingIntent
|
||||
import android.content.ActivityNotFoundException
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
@@ -18,7 +19,6 @@ import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.fragment.FragmentNavigator
|
||||
import androidx.navigation.ui.AppBarConfiguration
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
@@ -27,8 +27,10 @@ import androidx.preference.PreferenceFragmentCompat
|
||||
import com.car2go.maps.model.LatLng
|
||||
import com.google.android.material.navigation.NavigationView
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import net.vonforst.evmap.fragment.MapFragmentArgs
|
||||
import net.vonforst.evmap.model.ChargeLocation
|
||||
import net.vonforst.evmap.navigation.NavHostFragment
|
||||
import net.vonforst.evmap.storage.PreferenceDataSource
|
||||
import net.vonforst.evmap.utils.LocaleContextWrapper
|
||||
import net.vonforst.evmap.utils.getLocationFromIntent
|
||||
@@ -38,6 +40,7 @@ const val REQUEST_LOCATION_PERMISSION = 1
|
||||
const val EXTRA_CHARGER_ID = "chargerId"
|
||||
const val EXTRA_LAT = "lat"
|
||||
const val EXTRA_LON = "lon"
|
||||
const val EXTRA_FAVORITES = "favorites"
|
||||
|
||||
class MapsActivity : AppCompatActivity(),
|
||||
PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
|
||||
@@ -65,8 +68,6 @@ class MapsActivity : AppCompatActivity(),
|
||||
|
||||
setContentView(R.layout.activity_maps)
|
||||
|
||||
navController = findNavController(R.id.nav_host_fragment)
|
||||
val navGraph = navController.navInflater.inflate(R.navigation.nav_graph)
|
||||
appBarConfiguration = AppBarConfiguration(
|
||||
setOf(
|
||||
R.id.map,
|
||||
@@ -76,6 +77,10 @@ class MapsActivity : AppCompatActivity(),
|
||||
),
|
||||
findViewById<DrawerLayout>(R.id.drawer_layout)
|
||||
)
|
||||
val navHostFragment =
|
||||
supportFragmentManager.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||||
navController = navHostFragment.navController
|
||||
val navGraph = navController.navInflater.inflate(R.navigation.nav_graph)
|
||||
val navView = findViewById<NavigationView>(R.id.nav_view)
|
||||
navView.setupWithNavController(navController)
|
||||
|
||||
@@ -112,55 +117,57 @@ class MapsActivity : AppCompatActivity(),
|
||||
return
|
||||
} else {
|
||||
navGraph.setStartDestination(R.id.map)
|
||||
navController.graph = navGraph
|
||||
}
|
||||
navController.setGraph(navGraph, MapFragmentArgs(appStart = true).toBundle())
|
||||
var deepLink: PendingIntent? = null
|
||||
|
||||
if (intent?.scheme == "geo") {
|
||||
val query = intent.data?.query?.split("=")?.get(1)
|
||||
val coords = getLocationFromIntent(intent)
|
||||
|
||||
if (intent?.scheme == "geo") {
|
||||
val query = intent.data?.query?.split("=")?.get(1)
|
||||
val coords = getLocationFromIntent(intent)
|
||||
|
||||
if (coords != null) {
|
||||
val lat = coords[0]
|
||||
val lon = coords[1]
|
||||
val deepLink = navController.createDeepLink()
|
||||
.setGraph(R.navigation.nav_graph)
|
||||
if (coords != null) {
|
||||
val lat = coords[0]
|
||||
val lon = coords[1]
|
||||
deepLink = navController.createDeepLink()
|
||||
.setGraph(R.navigation.nav_graph)
|
||||
.setDestination(R.id.map)
|
||||
.setArguments(MapFragmentArgs(latLng = LatLng(lat, lon)).toBundle())
|
||||
.createPendingIntent()
|
||||
} else if (query != null && query.isNotEmpty()) {
|
||||
deepLink = navController.createDeepLink()
|
||||
.setGraph(R.navigation.nav_graph)
|
||||
.setDestination(R.id.map)
|
||||
.setArguments(MapFragmentArgs(locationName = query).toBundle())
|
||||
.createPendingIntent()
|
||||
}
|
||||
} else if (intent?.scheme == "https" && intent?.data?.host == "www.goingelectric.de") {
|
||||
val id = intent.data?.pathSegments?.last()?.toLongOrNull()
|
||||
if (id != null) {
|
||||
deepLink = navController.createDeepLink()
|
||||
.setGraph(R.navigation.nav_graph)
|
||||
.setDestination(R.id.map)
|
||||
.setArguments(MapFragmentArgs(chargerId = id).toBundle())
|
||||
.createPendingIntent()
|
||||
}
|
||||
} else if (intent.hasExtra(EXTRA_CHARGER_ID)) {
|
||||
deepLink = navController.createDeepLink()
|
||||
.setDestination(R.id.map)
|
||||
.setArguments(MapFragmentArgs(latLng = LatLng(lat, lon)).toBundle())
|
||||
.setArguments(
|
||||
MapFragmentArgs(
|
||||
chargerId = intent.getLongExtra(EXTRA_CHARGER_ID, 0),
|
||||
latLng = LatLng(
|
||||
intent.getDoubleExtra(EXTRA_LAT, 0.0),
|
||||
intent.getDoubleExtra(EXTRA_LON, 0.0)
|
||||
)
|
||||
).toBundle()
|
||||
)
|
||||
.createPendingIntent()
|
||||
deepLink.send()
|
||||
} else if (query != null && query.isNotEmpty()) {
|
||||
val deepLink = navController.createDeepLink()
|
||||
.setGraph(R.navigation.nav_graph)
|
||||
.setDestination(R.id.map)
|
||||
.setArguments(MapFragmentArgs(locationName = query).toBundle())
|
||||
} else if (intent.hasExtra(EXTRA_FAVORITES)) {
|
||||
deepLink = navController.createDeepLink()
|
||||
.setDestination(R.id.favs)
|
||||
.createPendingIntent()
|
||||
deepLink.send()
|
||||
}
|
||||
} else if (intent?.scheme == "https" && intent?.data?.host == "www.goingelectric.de") {
|
||||
val id = intent.data?.pathSegments?.last()?.toLongOrNull()
|
||||
if (id != null) {
|
||||
val deepLink = navController.createDeepLink()
|
||||
.setGraph(R.navigation.nav_graph)
|
||||
.setDestination(R.id.map)
|
||||
.setArguments(MapFragmentArgs(chargerId = id).toBundle())
|
||||
.createPendingIntent()
|
||||
deepLink.send()
|
||||
}
|
||||
} else if (intent.hasExtra(EXTRA_CHARGER_ID)) {
|
||||
navController.createDeepLink()
|
||||
.setDestination(R.id.map)
|
||||
.setArguments(
|
||||
MapFragmentArgs(
|
||||
chargerId = intent.getLongExtra(EXTRA_CHARGER_ID, 0),
|
||||
latLng = LatLng(
|
||||
intent.getDoubleExtra(EXTRA_LAT, 0.0),
|
||||
intent.getDoubleExtra(EXTRA_LON, 0.0)
|
||||
)
|
||||
).toBundle()
|
||||
)
|
||||
.createPendingIntent()
|
||||
.send()
|
||||
|
||||
deepLink?.send()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,6 +176,7 @@ class MapsActivity : AppCompatActivity(),
|
||||
val coord = charger.coordinates
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.data = Uri.parse("google.navigation:q=${coord.lat},${coord.lng}")
|
||||
intent.`package` = "com.google.android.apps.maps"
|
||||
if (prefs.navigateUseMaps && intent.resolveActivity(packageManager) != null) {
|
||||
startActivity(intent);
|
||||
} else {
|
||||
@@ -180,7 +188,11 @@ class MapsActivity : AppCompatActivity(),
|
||||
fun showLocation(charger: ChargeLocation) {
|
||||
val coord = charger.coordinates
|
||||
val intent = Intent(Intent.ACTION_VIEW)
|
||||
intent.data = Uri.parse("geo:0,0?q=${coord.lat},${coord.lng}(${charger.name})")
|
||||
intent.data = Uri.parse(
|
||||
"geo:${coord.lat},${coord.lng}?q=${coord.lat},${coord.lng}(${
|
||||
Uri.encode(charger.name)
|
||||
})"
|
||||
)
|
||||
if (intent.resolveActivity(packageManager) != null) {
|
||||
startActivity(intent);
|
||||
} else {
|
||||
@@ -225,6 +237,9 @@ class MapsActivity : AppCompatActivity(),
|
||||
caller: PreferenceFragmentCompat,
|
||||
pref: Preference
|
||||
): Boolean {
|
||||
caller.exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||
caller.reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||
|
||||
// Identify the Navigation Destination
|
||||
val navDestination = navController.graph
|
||||
.find { target -> target is FragmentNavigator.Destination && pref.fragment == target.className }
|
||||
|
||||
@@ -144,10 +144,9 @@ class CheckableConnectorAdapter : DataBindingAdapter<Chargepoint>() {
|
||||
field = value
|
||||
checkedItem?.let {
|
||||
if (value != null && getItem(it).type !in value) {
|
||||
val index = currentList.indexOfFirst {
|
||||
checkedItem = currentList.indexOfFirst {
|
||||
it.type in value
|
||||
}
|
||||
checkedItem = if (index == -1) null else index
|
||||
}.takeIf { it != -1 }
|
||||
onCheckedItemChangedListener?.invoke(getCheckedItem())
|
||||
}
|
||||
}
|
||||
@@ -168,7 +167,7 @@ class CheckableConnectorAdapter : DataBindingAdapter<Chargepoint>() {
|
||||
}
|
||||
root.setOnCheckedChangeListener { v: View, checked: Boolean ->
|
||||
if (checked) {
|
||||
checkedItem = holder.bindingAdapterPosition
|
||||
checkedItem = holder.bindingAdapterPosition.takeIf { it != -1 }
|
||||
root.post {
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
@@ -180,7 +179,7 @@ class CheckableConnectorAdapter : DataBindingAdapter<Chargepoint>() {
|
||||
fun getCheckedItem(): Chargepoint? = checkedItem?.let { getItem(it) }
|
||||
|
||||
fun setCheckedItem(item: Chargepoint?) {
|
||||
checkedItem = item?.let { currentList.indexOf(item) }
|
||||
checkedItem = item?.let { currentList.indexOf(item) }.takeIf { it != -1 }
|
||||
}
|
||||
|
||||
var onCheckedItemChangedListener: ((Chargepoint?) -> Unit)? = null
|
||||
|
||||
@@ -73,7 +73,7 @@ fun buildDetails(
|
||||
)
|
||||
} ?: "",
|
||||
loc.faultReport.description?.let {
|
||||
HtmlCompat.fromHtml(it, HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
HtmlCompat.fromHtml(it.replace("\n", "<br>"), HtmlCompat.FROM_HTML_MODE_LEGACY)
|
||||
} ?: "",
|
||||
clickable = true
|
||||
) else null,
|
||||
|
||||
@@ -2,7 +2,6 @@ package net.vonforst.evmap.api.availability
|
||||
|
||||
import com.facebook.stetho.okhttp3.StethoInterceptor
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.withContext
|
||||
import net.vonforst.evmap.api.RateLimitInterceptor
|
||||
import net.vonforst.evmap.api.await
|
||||
@@ -24,7 +23,6 @@ interface AvailabilityDetector {
|
||||
suspend fun getAvailability(location: ChargeLocation): ChargeLocationStatus
|
||||
}
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
abstract class BaseAvailabilityDetector(private val client: OkHttpClient) : AvailabilityDetector {
|
||||
protected val radius = 150 // max radius in meters
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package net.vonforst.evmap.api.availability
|
||||
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import net.vonforst.evmap.api.iterator
|
||||
import net.vonforst.evmap.model.ChargeLocation
|
||||
import net.vonforst.evmap.model.Chargepoint
|
||||
@@ -8,12 +7,10 @@ import okhttp3.OkHttpClient
|
||||
import org.json.JSONObject
|
||||
import java.io.IOException
|
||||
|
||||
@ExperimentalCoroutinesApi
|
||||
class ChargecloudAvailabilityDetector(
|
||||
client: OkHttpClient,
|
||||
private val operatorId: String
|
||||
) : BaseAvailabilityDetector(client) {
|
||||
@ExperimentalCoroutinesApi
|
||||
override suspend fun getAvailability(location: ChargeLocation): ChargeLocationStatus {
|
||||
val url =
|
||||
"https://app.chargecloud.de/emobility:ocpi/$operatorId/app/2.0/locations?latitude=${location.coordinates.lat}&longitude=${location.coordinates.lng}&radius=$radius&offset=0&limit=10"
|
||||
|
||||
@@ -126,16 +126,21 @@ internal class HoursAdapter {
|
||||
private val regex = Regex("from (.*) till (.*)")
|
||||
|
||||
@FromJson
|
||||
fun fromJson(str: String): GEHours? {
|
||||
fun fromJson(str: String): GEHours {
|
||||
if (str == "closed") {
|
||||
return GEHours(null, null)
|
||||
} else if (str == "around the clock") {
|
||||
return GEHours(LocalTime.MIN, LocalTime.MAX)
|
||||
} else {
|
||||
val match = regex.find(str)
|
||||
if (match != null) {
|
||||
return GEHours(
|
||||
LocalTime.parse(match.groupValues[1]),
|
||||
val start = LocalTime.parse(match.groupValues[1])
|
||||
val end = if (match.groupValues[2] == "24:00") {
|
||||
LocalTime.MAX
|
||||
} else {
|
||||
LocalTime.parse(match.groupValues[2])
|
||||
)
|
||||
}
|
||||
return GEHours(start, end)
|
||||
} else {
|
||||
// I cannot reproduce this case, but it seems to occur once in a while
|
||||
Log.e("GoingElectricApi", "invalid hours value: " + str)
|
||||
|
||||
@@ -2,12 +2,9 @@ package net.vonforst.evmap.fragment
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.MotionEvent
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.*
|
||||
import androidx.databinding.DataBindingUtil
|
||||
import androidx.fragment.app.DialogFragment
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.viewModels
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.navigation.fragment.findNavController
|
||||
@@ -15,7 +12,9 @@ import androidx.navigation.fragment.navArgs
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.transition.MaterialContainerTransform
|
||||
import net.vonforst.evmap.MapsActivity
|
||||
import net.vonforst.evmap.R
|
||||
import net.vonforst.evmap.adapter.ChargepriceAdapter
|
||||
@@ -30,7 +29,7 @@ import net.vonforst.evmap.viewmodel.Status
|
||||
import net.vonforst.evmap.viewmodel.viewModelFactory
|
||||
import java.text.NumberFormat
|
||||
|
||||
class ChargepriceFragment : DialogFragment() {
|
||||
class ChargepriceFragment : Fragment() {
|
||||
private lateinit var binding: FragmentChargepriceBinding
|
||||
private var connectionErrorSnackbar: Snackbar? = null
|
||||
|
||||
@@ -43,9 +42,9 @@ class ChargepriceFragment : DialogFragment() {
|
||||
}
|
||||
})
|
||||
|
||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||
super.onActivityCreated(savedInstanceState)
|
||||
dialog?.window?.attributes?.windowAnimations = R.style.ChargepriceDialogAnimation
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
sharedElementEnterTransition = MaterialContainerTransform()
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
@@ -66,20 +65,15 @@ class ChargepriceFragment : DialogFragment() {
|
||||
return binding.root
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
// dialog with 95% screen height
|
||||
dialog?.window?.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
(resources.displayMetrics.heightPixels * 0.95).toInt()
|
||||
)
|
||||
}
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
val fragmentArgs: ChargepriceFragmentArgs by navArgs()
|
||||
val charger = fragmentArgs.charger
|
||||
val dataSource = fragmentArgs.dataSource
|
||||
@@ -171,10 +165,6 @@ class ChargepriceFragment : DialogFragment() {
|
||||
|
||||
binding.toolbar.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.menu_close -> {
|
||||
dismiss()
|
||||
true
|
||||
}
|
||||
R.id.menu_help -> {
|
||||
(activity as? MapsActivity)?.openUrl(getString(R.string.chargeprice_faq_link))
|
||||
true
|
||||
@@ -207,14 +197,9 @@ class ChargepriceFragment : DialogFragment() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Workaround for AndroidX bug: https://github.com/material-components/material-components-android/issues/1984
|
||||
view.setBackgroundColor(MaterialColors.getColor(view, android.R.attr.windowBackground))
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,9 @@ import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.car2go.maps.model.LatLng
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
import com.mapzen.android.lost.api.LocationServices
|
||||
import com.mapzen.android.lost.api.LostApiClient
|
||||
import net.vonforst.evmap.MapsActivity
|
||||
@@ -51,6 +53,9 @@ class FavoritesFragment : Fragment(), LostApiClient.ConnectionCallbacks {
|
||||
super.onCreate(savedInstanceState)
|
||||
locationClient = LostApiClient.Builder(requireContext())
|
||||
.addConnectionCallbacks(this).build()
|
||||
|
||||
enterTransition = MaterialFadeThrough()
|
||||
exitTransition = MaterialFadeThrough()
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
@@ -70,6 +75,13 @@ class FavoritesFragment : Fragment(), LostApiClient.ConnectionCallbacks {
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
// Workaround for AndroidX bug: https://github.com/material-components/material-components-android/issues/1984
|
||||
view.setBackgroundColor(MaterialColors.getColor(view, android.R.attr.windowBackground))
|
||||
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
adapter = FavoritesAdapter(onDelete = {
|
||||
delete(it.charger)
|
||||
@@ -254,9 +266,5 @@ class FavoritesFragment : Fragment(), LostApiClient.ConnectionCallbacks {
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,8 @@ import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import kotlinx.coroutines.launch
|
||||
import net.vonforst.evmap.MapsActivity
|
||||
import net.vonforst.evmap.R
|
||||
@@ -24,6 +26,12 @@ class FilterFragment : Fragment() {
|
||||
private lateinit var binding: FragmentFilterBinding
|
||||
private val vm: FilterViewModel by viewModels()
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@@ -43,6 +51,17 @@ class FilterFragment : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
(requireActivity() as AppCompatActivity).setSupportActionBar(binding.toolbar)
|
||||
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
vm.filterProfile.observe(viewLifecycleOwner) {
|
||||
if (it != null) {
|
||||
binding.toolbar.title = getString(R.string.edit_filter_profile, it.name)
|
||||
}
|
||||
}
|
||||
|
||||
binding.filtersList.apply {
|
||||
adapter = FiltersAdapter()
|
||||
layoutManager =
|
||||
@@ -57,6 +76,9 @@ class FilterFragment : Fragment() {
|
||||
binding.toolbar.setNavigationOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
|
||||
// Workaround for AndroidX bug: https://github.com/material-components/material-components-android/issues/1984
|
||||
view.setBackgroundColor(MaterialColors.getColor(view, android.R.attr.windowBackground))
|
||||
}
|
||||
|
||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||
@@ -108,18 +130,4 @@ class FilterFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
vm.filterProfile.observe(viewLifecycleOwner) {
|
||||
if (it != null) {
|
||||
binding.toolbar.title = getString(R.string.edit_filter_profile, it.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,9 @@ import androidx.recyclerview.widget.DividerItemDecoration
|
||||
import androidx.recyclerview.widget.ItemTouchHelper
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import kotlinx.coroutines.launch
|
||||
import net.vonforst.evmap.MapsActivity
|
||||
import net.vonforst.evmap.R
|
||||
@@ -43,6 +45,12 @@ class FilterProfilesFragment : Fragment() {
|
||||
private var deleteSnackbar: Snackbar? = null
|
||||
private var toDelete: FilterProfile? = null
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@@ -58,6 +66,11 @@ class FilterProfilesFragment : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
(requireActivity() as AppCompatActivity).setSupportActionBar(binding.toolbar)
|
||||
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
touchHelper = ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(
|
||||
ItemTouchHelper.UP or ItemTouchHelper.DOWN,
|
||||
ItemTouchHelper.RIGHT or ItemTouchHelper.LEFT
|
||||
@@ -201,14 +214,9 @@ class FilterProfilesFragment : Fragment() {
|
||||
binding.toolbar.setNavigationOnClickListener {
|
||||
findNavController().popBackStack()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
// Workaround for AndroidX bug: https://github.com/material-components/material-components-android/issues/1984
|
||||
view.setBackgroundColor(MaterialColors.getColor(view, android.R.attr.windowBackground))
|
||||
}
|
||||
|
||||
fun delete(fp: FilterProfile) {
|
||||
|
||||
@@ -32,6 +32,7 @@ import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.Observer
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.navigation.fragment.FragmentNavigatorExtras
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
@@ -53,6 +54,8 @@ import com.car2go.maps.model.MarkerOptions
|
||||
import com.google.android.material.snackbar.Snackbar
|
||||
import com.google.android.material.transition.MaterialArcMotion
|
||||
import com.google.android.material.transition.MaterialContainerTransform
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import com.mahc.custombottomsheetbehavior.BottomSheetBehaviorGoogleMapsLike
|
||||
import com.mahc.custombottomsheetbehavior.BottomSheetBehaviorGoogleMapsLike.STATE_COLLAPSED
|
||||
import com.mahc.custombottomsheetbehavior.BottomSheetBehaviorGoogleMapsLike.STATE_HIDDEN
|
||||
@@ -147,8 +150,13 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
.build()
|
||||
locationClient.connect()
|
||||
clusterIconGenerator = ClusterIconGenerator(requireContext())
|
||||
|
||||
enterTransition = MaterialFadeThrough()
|
||||
exitTransition = MaterialFadeThrough()
|
||||
}
|
||||
|
||||
private val mapFragmentTag = "map"
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
@@ -159,6 +167,10 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
binding.vm = vm
|
||||
|
||||
val provider = prefs.mapProvider
|
||||
if (mapFragment == null) {
|
||||
mapFragment =
|
||||
requireActivity().supportFragmentManager.findFragmentByTag(mapFragmentTag) as MapFragment?
|
||||
}
|
||||
if (mapFragment == null || mapFragment!!.priority[0] != provider) {
|
||||
mapFragment = MapFragment()
|
||||
mapFragment!!.priority = arrayOf(
|
||||
@@ -172,7 +184,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
)
|
||||
requireActivity().supportFragmentManager
|
||||
.beginTransaction()
|
||||
.replace(R.id.map, mapFragment!!)
|
||||
.replace(R.id.map, mapFragment!!, mapFragmentTag)
|
||||
.commit()
|
||||
|
||||
// reset map-related stuff (map provider may have changed)
|
||||
@@ -194,7 +206,11 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
val density = resources.displayMetrics.density
|
||||
// status bar height + toolbar height + margin
|
||||
val margin =
|
||||
insets.systemWindowInsetTop + (48 * density).toInt() + (24 * density).toInt()
|
||||
if (binding.toolbarContainer.layoutParams.width == ViewGroup.LayoutParams.MATCH_PARENT) {
|
||||
insets.systemWindowInsetTop + (48 * density).toInt() + (28 * density).toInt()
|
||||
} else {
|
||||
insets.systemWindowInsetTop + (12 * density).toInt()
|
||||
}
|
||||
binding.fabLayers.updateLayoutParams<ViewGroup.MarginLayoutParams> {
|
||||
topMargin = margin
|
||||
}
|
||||
@@ -234,6 +250,11 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
setupAdapters()
|
||||
(activity as? MapsActivity)?.setSupportActionBar(binding.toolbar)
|
||||
|
||||
binding.toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
if (prefs.appStartCounter > 5 && !prefs.opensourceDonationsDialogShown) {
|
||||
try {
|
||||
findNavController().navigate(R.id.action_map_to_opensource_donations)
|
||||
@@ -250,6 +271,32 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
// when there is already another navigation going on
|
||||
}
|
||||
}*/
|
||||
|
||||
val fragmentArgs: MapFragmentArgs by navArgs()
|
||||
if (savedInstanceState == null && fragmentArgs.appStart) {
|
||||
// logo animation after starting the app
|
||||
binding.appLogo.root.visibility = View.VISIBLE
|
||||
binding.appLogo.root.alpha = 0f
|
||||
binding.search.visibility = View.GONE
|
||||
|
||||
binding.appLogo.root.animate().alpha(1f)
|
||||
.withEndAction {
|
||||
binding.appLogo.root.animate().alpha(0f).apply {
|
||||
startDelay = 1000
|
||||
}.withEndAction {
|
||||
binding.appLogo.root.visibility = View.GONE
|
||||
binding.search.visibility = View.VISIBLE
|
||||
binding.search.alpha = 0f
|
||||
binding.search.animate().alpha(1f).start()
|
||||
}.start()
|
||||
}.apply {
|
||||
startDelay = 100
|
||||
}.start()
|
||||
arguments = fragmentArgs.copy(appStart = false).toBundle()
|
||||
} else {
|
||||
binding.appLogo.root.visibility = View.GONE
|
||||
binding.search.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
@@ -257,12 +304,6 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
val hostActivity = activity as? MapsActivity ?: return
|
||||
hostActivity.fragmentCallback = this
|
||||
|
||||
val navController = findNavController()
|
||||
binding.toolbar.setupWithNavController(
|
||||
navController,
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
vm.reloadPrefs()
|
||||
if (requestingLocationUpdates && requireContext().checkAnyLocationPermission()
|
||||
&& locationClient.isConnected
|
||||
@@ -311,9 +352,12 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
OpenChargeMapApiWrapper::class.java -> "open_charge_map"
|
||||
else -> throw IllegalArgumentException("unsupported data source")
|
||||
}
|
||||
val extras =
|
||||
FragmentNavigatorExtras(binding.detailView.btnChargeprice to getString(R.string.shared_element_chargeprice))
|
||||
findNavController().navigate(
|
||||
R.id.action_map_to_chargepriceFragment,
|
||||
ChargepriceFragmentArgs(charger, dataSource).toBundle()
|
||||
ChargepriceFragmentArgs(charger, dataSource).toBundle(),
|
||||
null, extras
|
||||
)
|
||||
}
|
||||
binding.detailView.topPart.setOnClickListener {
|
||||
@@ -392,6 +436,7 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
binding.search.onFocusChangeListener = View.OnFocusChangeListener { v, hasFocus ->
|
||||
if (hasFocus) {
|
||||
binding.search.keyListener = searchKeyListener
|
||||
binding.search.text = binding.search.text // workaround to fix copy/paste
|
||||
} else {
|
||||
binding.search.keyListener = null
|
||||
}
|
||||
@@ -417,28 +462,38 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
|
||||
private fun openLayersMenu() {
|
||||
binding.fabLayers.tag = false
|
||||
val materialTransform = MaterialContainerTransform().apply {
|
||||
startView = binding.fabLayers
|
||||
endView = binding.layersSheet
|
||||
setPathMotion(MaterialArcMotion())
|
||||
duration = 250
|
||||
scrimColor = Color.TRANSPARENT
|
||||
}
|
||||
TransitionManager.beginDelayedTransition(binding.root, materialTransform)
|
||||
vm.layersMenuOpen.value = true
|
||||
|
||||
binding.fabLayers.postDelayed({
|
||||
val materialTransform = MaterialContainerTransform().apply {
|
||||
startView = binding.fabLayers
|
||||
endView = binding.layersSheet
|
||||
setPathMotion(MaterialArcMotion())
|
||||
duration = 250
|
||||
scrimColor = Color.TRANSPARENT
|
||||
addTarget(binding.layersSheet)
|
||||
isElevationShadowEnabled = false
|
||||
}
|
||||
TransitionManager.beginDelayedTransition(binding.root, materialTransform)
|
||||
vm.layersMenuOpen.value = true
|
||||
}, 100)
|
||||
}
|
||||
|
||||
private fun closeLayersMenu() {
|
||||
binding.fabLayers.tag = true
|
||||
val materialTransform = MaterialContainerTransform().apply {
|
||||
startView = binding.layersSheet
|
||||
endView = binding.fabLayers
|
||||
setPathMotion(MaterialArcMotion())
|
||||
duration = 200
|
||||
scrimColor = Color.TRANSPARENT
|
||||
}
|
||||
TransitionManager.beginDelayedTransition(binding.root, materialTransform)
|
||||
vm.layersMenuOpen.value = false
|
||||
|
||||
binding.fabLayers.postDelayed({
|
||||
val materialTransform = MaterialContainerTransform().apply {
|
||||
startView = binding.layersSheet
|
||||
endView = binding.fabLayers
|
||||
setPathMotion(MaterialArcMotion())
|
||||
duration = 200
|
||||
scrimColor = Color.TRANSPARENT
|
||||
addTarget(binding.fabLayers)
|
||||
isElevationShadowEnabled = false
|
||||
}
|
||||
TransitionManager.beginDelayedTransition(binding.root, materialTransform)
|
||||
vm.layersMenuOpen.value = false
|
||||
}, 100)
|
||||
}
|
||||
|
||||
private fun toggleFavorite() {
|
||||
@@ -557,8 +612,8 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
updateBackPressedCallback()
|
||||
})
|
||||
vm.layersMenuOpen.observe(viewLifecycleOwner, Observer { open ->
|
||||
binding.fabLayers.visibility = if (open) View.GONE else View.VISIBLE
|
||||
binding.layersSheet.visibility = if (open) View.VISIBLE else View.GONE
|
||||
binding.fabLayers.visibility = if (open) View.INVISIBLE else View.VISIBLE
|
||||
binding.layersSheet.visibility = if (open) View.VISIBLE else View.INVISIBLE
|
||||
updateBackPressedCallback()
|
||||
})
|
||||
vm.mapType.observe(viewLifecycleOwner, Observer {
|
||||
@@ -877,7 +932,11 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
} else if (locationName != null) {
|
||||
lifecycleScope.launch {
|
||||
val address = withContext(Dispatchers.IO) {
|
||||
Geocoder(requireContext()).getFromLocationName(locationName, 1).getOrNull(0)
|
||||
try {
|
||||
Geocoder(requireContext()).getFromLocationName(locationName, 1).getOrNull(0)
|
||||
} catch (e: IOException) {
|
||||
null
|
||||
}
|
||||
}
|
||||
address?.let {
|
||||
val latLng = LatLng(it.latitude, it.longitude)
|
||||
@@ -1070,12 +1129,18 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
filterView?.setOnClickListener {
|
||||
var profilesMap: MutableBiMap<Long, MenuItem> = HashBiMap()
|
||||
|
||||
val popup = PopupMenu(requireContext(), it, Gravity.END)
|
||||
val popup = PopupMenu(
|
||||
ContextThemeWrapper(requireContext(), R.style.RoundedPopup),
|
||||
it,
|
||||
Gravity.END
|
||||
)
|
||||
popup.menuInflater.inflate(R.menu.popup_filter, popup.menu)
|
||||
MenuCompat.setGroupDividerEnabled(popup.menu, true)
|
||||
popup.setOnMenuItemClickListener {
|
||||
when (it.itemId) {
|
||||
R.id.menu_edit_filters -> {
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
|
||||
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
lifecycleScope.launch {
|
||||
vm.copyFiltersToCustom()
|
||||
requireView().findNavController().navigate(
|
||||
@@ -1085,6 +1150,8 @@ class MapFragment : Fragment(), OnMapReadyCallback, MapsActivity.FragmentCallbac
|
||||
true
|
||||
}
|
||||
R.id.menu_manage_filter_profiles -> {
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
|
||||
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
|
||||
requireView().findNavController().navigate(
|
||||
R.id.action_map_to_filterProfilesFragment
|
||||
)
|
||||
|
||||
@@ -4,6 +4,7 @@ import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import androidx.appcompat.app.AppCompatDialogFragment
|
||||
import androidx.core.widget.doAfterTextChanged
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@@ -14,6 +15,7 @@ import net.vonforst.evmap.databinding.DialogMultiSelectBinding
|
||||
import java.util.*
|
||||
import kotlin.collections.HashMap
|
||||
import kotlin.collections.HashSet
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class MultiSelectDialog : AppCompatDialogFragment() {
|
||||
companion object {
|
||||
@@ -53,9 +55,13 @@ class MultiSelectDialog : AppCompatDialogFragment() {
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
val density = resources.displayMetrics.density
|
||||
val width = resources.displayMetrics.widthPixels
|
||||
val maxWidth = (500 * density).roundToInt()
|
||||
|
||||
// dialog with 95% screen height
|
||||
dialog?.window?.setLayout(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
if (width < maxWidth) WindowManager.LayoutParams.MATCH_PARENT else maxWidth,
|
||||
(resources.displayMetrics.heightPixels * 0.95).toInt()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -52,8 +52,17 @@ class OnboardingFragment : Fragment() {
|
||||
|
||||
override fun onPageSelected(position: Int) {
|
||||
binding.pageIndicatorView.selection = position
|
||||
binding.forward?.visibility =
|
||||
if (position == adapter.itemCount - 1) View.INVISIBLE else View.VISIBLE
|
||||
binding.backward?.visibility = if (position == 0) View.INVISIBLE else View.VISIBLE
|
||||
}
|
||||
})
|
||||
binding.forward?.setOnClickListener {
|
||||
binding.viewPager.setCurrentItem(binding.viewPager.currentItem + 1, true)
|
||||
}
|
||||
binding.backward?.setOnClickListener {
|
||||
binding.viewPager.setCurrentItem(binding.viewPager.currentItem - 1, true)
|
||||
}
|
||||
|
||||
return binding.root
|
||||
}
|
||||
|
||||
@@ -1,11 +1,15 @@
|
||||
package net.vonforst.evmap.fragment.preference
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.Toolbar
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import com.mikepenz.aboutlibraries.LibsBuilder
|
||||
import net.vonforst.evmap.BuildConfig
|
||||
import net.vonforst.evmap.MapsActivity
|
||||
@@ -13,14 +17,23 @@ import net.vonforst.evmap.R
|
||||
|
||||
|
||||
class AboutFragment : PreferenceFragmentCompat() {
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
val toolbar = requireView().findViewById(R.id.toolbar) as Toolbar
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
enterTransition = MaterialFadeThrough()
|
||||
exitTransition = MaterialFadeThrough()
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
|
||||
toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
// Workaround for AndroidX bug: https://github.com/material-components/material-components-android/issues/1984
|
||||
view.setBackgroundColor(MaterialColors.getColor(view, android.R.attr.windowBackground))
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
@@ -54,6 +67,8 @@ class AboutFragment : PreferenceFragmentCompat() {
|
||||
true
|
||||
}
|
||||
"donate" -> {
|
||||
exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||
reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||
findNavController().navigate(R.id.action_about_to_donateFragment)
|
||||
true
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ import androidx.appcompat.widget.Toolbar
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.ui.setupWithNavController
|
||||
import androidx.preference.PreferenceFragmentCompat
|
||||
import com.google.android.material.color.MaterialColors
|
||||
import com.google.android.material.transition.MaterialFadeThrough
|
||||
import com.google.android.material.transition.MaterialSharedAxis
|
||||
import net.vonforst.evmap.MapsActivity
|
||||
import net.vonforst.evmap.R
|
||||
import net.vonforst.evmap.storage.PreferenceDataSource
|
||||
@@ -14,22 +17,38 @@ import net.vonforst.evmap.storage.PreferenceDataSource
|
||||
abstract class BaseSettingsFragment : PreferenceFragmentCompat(),
|
||||
SharedPreferences.OnSharedPreferenceChangeListener {
|
||||
protected lateinit var prefs: PreferenceDataSource
|
||||
protected abstract val isTopLevel: Boolean
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
if (isTopLevel) {
|
||||
enterTransition = MaterialFadeThrough()
|
||||
exitTransition = MaterialFadeThrough()
|
||||
} else {
|
||||
enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
|
||||
returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
|
||||
val toolbar = view.findViewById<Toolbar>(R.id.toolbar)
|
||||
toolbar.setupWithNavController(
|
||||
findNavController(),
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
|
||||
prefs = PreferenceDataSource(requireContext())
|
||||
|
||||
// Workaround for AndroidX bug: https://github.com/material-components/material-components-android/issues/1984
|
||||
view.setBackgroundColor(MaterialColors.getColor(view, android.R.attr.windowBackground))
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
preferenceManager.sharedPreferences.registerOnSharedPreferenceChangeListener(this)
|
||||
|
||||
val navController = findNavController()
|
||||
val toolbar = requireView().findViewById(R.id.toolbar) as Toolbar
|
||||
toolbar.setupWithNavController(
|
||||
navController,
|
||||
(requireActivity() as MapsActivity).appBarConfiguration
|
||||
)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
|
||||
@@ -10,6 +10,8 @@ import net.vonforst.evmap.viewmodel.SettingsViewModel
|
||||
import net.vonforst.evmap.viewmodel.viewModelFactory
|
||||
|
||||
class ChargepriceSettingsFragment : BaseSettingsFragment() {
|
||||
override val isTopLevel = false
|
||||
|
||||
private val vm: SettingsViewModel by viewModels(factoryProducer = {
|
||||
viewModelFactory {
|
||||
SettingsViewModel(
|
||||
|
||||
@@ -11,6 +11,8 @@ import net.vonforst.evmap.viewmodel.SettingsViewModel
|
||||
import net.vonforst.evmap.viewmodel.viewModelFactory
|
||||
|
||||
class DataSettingsFragment : BaseSettingsFragment() {
|
||||
override val isTopLevel = false
|
||||
|
||||
private val vm: SettingsViewModel by viewModels(factoryProducer = {
|
||||
viewModelFactory {
|
||||
SettingsViewModel(
|
||||
|
||||
@@ -7,13 +7,15 @@ import net.vonforst.evmap.R
|
||||
|
||||
|
||||
class SettingsFragment : BaseSettingsFragment() {
|
||||
override val isTopLevel = true
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.settings, rootKey)
|
||||
addPreferencesFromResource(R.xml.settings)
|
||||
addPreferencesFromResource(R.xml.settings_variantspecific)
|
||||
}
|
||||
|
||||
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) {
|
||||
|
||||
@@ -6,6 +6,8 @@ import net.vonforst.evmap.R
|
||||
import net.vonforst.evmap.ui.updateNightMode
|
||||
|
||||
class UiSettingsFragment : BaseSettingsFragment() {
|
||||
override val isTopLevel = false
|
||||
|
||||
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
|
||||
setPreferencesFromResource(R.xml.settings_ui, rootKey)
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import androidx.navigation.fragment.findNavController
|
||||
import net.vonforst.evmap.R
|
||||
import net.vonforst.evmap.databinding.DialogOpensourceDonationsBinding
|
||||
import net.vonforst.evmap.storage.PreferenceDataSource
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
class OpensourceDonationsDialogFramgent : AppCompatDialogFragment() {
|
||||
private lateinit var binding: DialogOpensourceDonationsBinding
|
||||
@@ -43,8 +44,13 @@ class OpensourceDonationsDialogFramgent : AppCompatDialogFragment() {
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
|
||||
val density = resources.displayMetrics.density
|
||||
val width = resources.displayMetrics.widthPixels
|
||||
val maxWidth = (500 * density).roundToInt()
|
||||
|
||||
dialog?.window?.setLayout(
|
||||
WindowManager.LayoutParams.MATCH_PARENT,
|
||||
if (width < maxWidth) WindowManager.LayoutParams.MATCH_PARENT else maxWidth,
|
||||
WindowManager.LayoutParams.WRAP_CONTENT
|
||||
)
|
||||
}
|
||||
|
||||
@@ -152,7 +152,7 @@ data class Cost(
|
||||
val parking =
|
||||
if (freeparking) ctx.getString(R.string.free) else ctx.getString(R.string.paid)
|
||||
return if (emoji) {
|
||||
"⚡ $parking"
|
||||
"\uD83C\uDD7F $parking"
|
||||
} else {
|
||||
HtmlCompat.fromHtml(ctx.getString(R.string.cost_detail_parking, parking), 0)
|
||||
}
|
||||
|
||||
@@ -168,6 +168,17 @@ class PreferenceDataSource(val context: Context) {
|
||||
.apply()
|
||||
}
|
||||
|
||||
var chargepriceBatteryRangeAndroidAuto: List<Float>
|
||||
get() = listOf(
|
||||
sp.getFloat("chargeprice_battery_range_android_auto_min", 20f),
|
||||
sp.getFloat("chargeprice_battery_range_android_auto_max", 80f),
|
||||
)
|
||||
set(value) {
|
||||
sp.edit().putFloat("chargeprice_battery_range_android_auto_min", value[0])
|
||||
.putFloat("chargeprice_battery_range_android_auto_max", value[1])
|
||||
.apply()
|
||||
}
|
||||
|
||||
/** App start counter, introduced with Version 1.0.0 */
|
||||
var appStartCounter: Long
|
||||
get() = sp.getLong("app_start_counter", 0)
|
||||
|
||||
117
app/src/main/java/net/vonforst/evmap/ui/RangeSliderPreference.kt
Normal file
@@ -0,0 +1,117 @@
|
||||
package net.vonforst.evmap.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.MotionEvent
|
||||
import androidx.preference.Preference
|
||||
import androidx.preference.PreferenceViewHolder
|
||||
import com.google.android.material.slider.RangeSlider
|
||||
import net.vonforst.evmap.R
|
||||
|
||||
class RangeSliderPreference(context: Context, attrs: AttributeSet) : Preference(context, attrs) {
|
||||
var valueFrom: Float = 0f
|
||||
set(value) {
|
||||
val v = if (value > valueTo) valueTo else value
|
||||
if (v != valueFrom) {
|
||||
field = v
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
var valueTo: Float = 100f
|
||||
set(value) {
|
||||
val v = if (value < valueFrom) valueFrom else value
|
||||
if (v != valueTo) {
|
||||
field = v
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
var stepSize: Float? = null
|
||||
set(value) {
|
||||
if (value != stepSize) {
|
||||
field = value
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
var updatesContinuously: Boolean
|
||||
var defaultValue: List<Float>
|
||||
var labelFormatter: ((Float) -> String)? = null
|
||||
set(value) {
|
||||
if (value != labelFormatter) {
|
||||
field = value
|
||||
notifyChanged()
|
||||
}
|
||||
}
|
||||
|
||||
private lateinit var slider: RangeSlider
|
||||
private var dragging = false
|
||||
|
||||
var values: List<Float>
|
||||
get() = if ((sharedPreferences.contains(key + "_min") && sharedPreferences.contains(key + "_max"))) {
|
||||
listOf(
|
||||
sharedPreferences.getFloat(key + "_min", 0f),
|
||||
sharedPreferences.getFloat(key + "_max", 0f)
|
||||
)
|
||||
} else defaultValue
|
||||
set(value) {
|
||||
sharedPreferences.edit()
|
||||
.putFloat(key + "_min", value[0])
|
||||
.putFloat(key + "_max", value[1])
|
||||
.apply()
|
||||
}
|
||||
|
||||
init {
|
||||
val a = context.obtainStyledAttributes(
|
||||
attrs, R.styleable.RangeSliderPreference
|
||||
)
|
||||
|
||||
// The ordering of these two statements are important. If we want to set max first, we need
|
||||
// to perform the same steps by changing min/max to max/min as following:
|
||||
// mMax = a.getInt(...) and setMin(...).
|
||||
valueFrom = a.getFloat(R.styleable.RangeSliderPreference_android_valueFrom, 0f)
|
||||
valueTo = a.getFloat(R.styleable.RangeSliderPreference_android_valueTo, 100f)
|
||||
stepSize =
|
||||
a.getFloat(R.styleable.RangeSliderPreference_android_stepSize, -1f).takeIf { it != -1f }
|
||||
updatesContinuously = a.getBoolean(
|
||||
R.styleable.RangeSliderPreference_updatesContinuously,
|
||||
false
|
||||
)
|
||||
defaultValue =
|
||||
a.getString(R.styleable.RangeSliderPreference_android_defaultValue)?.split(",")
|
||||
?.map { it.toFloat() } ?: listOf(valueFrom, valueTo)
|
||||
|
||||
a.recycle()
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: PreferenceViewHolder) {
|
||||
super.onBindViewHolder(holder)
|
||||
slider = holder.findViewById(R.id.rangeSlider) as RangeSlider
|
||||
slider.valueFrom = valueFrom
|
||||
slider.valueTo = valueTo
|
||||
stepSize?.let { slider.stepSize = it }
|
||||
|
||||
slider.addOnChangeListener { slider, value, fromUser ->
|
||||
if (fromUser && (updatesContinuously || !dragging)) {
|
||||
syncValueInternal(slider)
|
||||
}
|
||||
}
|
||||
slider.setOnTouchListener { v, event ->
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN -> dragging = true
|
||||
MotionEvent.ACTION_UP -> dragging = false
|
||||
}
|
||||
false
|
||||
}
|
||||
slider.values = values
|
||||
slider.isEnabled = isEnabled
|
||||
slider.setLabelFormatter(labelFormatter)
|
||||
}
|
||||
|
||||
private fun syncValueInternal(slider: RangeSlider) {
|
||||
val newValues = slider.values
|
||||
if (callChangeListener(newValues)) {
|
||||
values = newValues
|
||||
} else {
|
||||
slider.values = values
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -214,7 +214,7 @@ class ChargepriceViewModel(application: Application, chargepriceApiKey: String)
|
||||
val dataSource = dataSource.value
|
||||
val myTariffs = myTariffs.value
|
||||
val myTariffsAll = myTariffsAll.value
|
||||
if (charger == null || car == null || compatibleConnectors == null || dataSource == null || myTariffs == null || myTariffsAll == null) {
|
||||
if (charger == null || car == null || compatibleConnectors == null || dataSource == null || myTariffsAll == null || myTariffsAll == false && myTariffs == null) {
|
||||
chargePrices.value = Resource.error(null, null)
|
||||
return
|
||||
}
|
||||
@@ -229,7 +229,7 @@ class ChargepriceViewModel(application: Application, chargepriceApiKey: String)
|
||||
station = cpStation
|
||||
vehicle = HasOne(car)
|
||||
tariffs = if (!myTariffsAll) {
|
||||
HasMany<ChargepriceTariff>(*myTariffs.map {
|
||||
HasMany<ChargepriceTariff>(*myTariffs!!.map {
|
||||
ResourceIdentifier(
|
||||
"tariff",
|
||||
it
|
||||
|
||||
5
app/src/main/res/color/hint_text_color.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:state_focused="true" android:color="?android:attr/textColorSecondary" android:alpha="0.38" />
|
||||
<item android:state_focused="false" android:color="?android:attr/textColorPrimary" />
|
||||
</selector>
|
||||
11
app/src/main/res/drawable/ic_arrow_back.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z" />
|
||||
</vector>
|
||||
11
app/src/main/res/drawable/ic_arrow_forward.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24"
|
||||
android:tint="?attr/colorControlNormal"
|
||||
android:autoMirrored="true">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z" />
|
||||
</vector>
|
||||
9
app/src/main/res/drawable/ic_shortcut_fav.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"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="@color/colorSecondary"
|
||||
android:pathData="M12,21.35l-1.45,-1.32C5.4,15.36 2,12.28 2,8.5 2,5.42 4.42,3 7.5,3c1.74,0 3.41,0.81 4.5,2.09C13.09,3.81 14.76,3 16.5,3 19.58,3 22,5.42 22,8.5c0,3.78 -3.4,6.86 -8.55,11.54L12,21.35z" />
|
||||
</vector>
|
||||
6
app/src/main/res/drawable/rounded_rect_24dp.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="?colorSurface" />
|
||||
<corners android:radius="24dp" />
|
||||
</shape>
|
||||
6
app/src/main/res/drawable/rounded_rect_8dp.xml
Normal file
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="?android:colorBackground" />
|
||||
<corners android:radius="8dp" />
|
||||
</shape>
|
||||
@@ -31,7 +31,7 @@
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/pref_data_source"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
@@ -46,7 +46,7 @@
|
||||
android:layout_marginBottom="28dp"
|
||||
android:breakStrategy="balanced"
|
||||
android:text="@string/data_sources_description"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.MaterialComponents.Button"
|
||||
style="@style/Widget.Material3.Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
android:layout_marginStart="72dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="< 11 kW"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintBottom_toTopOf="@id/icon4"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel2"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
@@ -51,7 +51,7 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 11 kW"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel3"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel1"
|
||||
@@ -75,7 +75,7 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 20 kW"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel4"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel2"
|
||||
@@ -100,7 +100,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 43 kW"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel5"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
@@ -126,7 +126,7 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 100 kW"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toEndOf="@id/iconLabel3"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel4"
|
||||
app:layout_constraintTop_toBottomOf="@+id/icon5" />
|
||||
@@ -139,7 +139,7 @@
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/welcome_2_title"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel3"
|
||||
@@ -154,7 +154,7 @@
|
||||
android:layout_marginBottom="42dp"
|
||||
android:breakStrategy="balanced"
|
||||
android:text="@string/welcome_2"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
@@ -163,7 +163,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="72dp"
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:text="@string/welcome_to_evmap"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
@@ -39,7 +39,7 @@
|
||||
android:layout_marginBottom="56dp"
|
||||
android:breakStrategy="balanced"
|
||||
android:text="@string/welcome_1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
@@ -48,7 +48,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
style="@style/Widget.Material3.Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
|
||||
74
app/src/main/res/layout-sw720dp/fragment_onboarding.xml
Normal file
@@ -0,0 +1,74 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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"
|
||||
android:fitsSystemWindows="true"
|
||||
android:background="?colorPrimaryContainer">
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/card"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="540dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@id/forward"
|
||||
app:layout_constraintStart_toEndOf="@id/backward"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintWidth_max="540dp">
|
||||
|
||||
<androidx.viewpager2.widget.ViewPager2
|
||||
android:id="@+id/viewPager"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:overScrollMode="never">
|
||||
|
||||
</androidx.viewpager2.widget.ViewPager2>
|
||||
</androidx.cardview.widget.CardView>
|
||||
|
||||
|
||||
<com.rd.PageIndicatorView
|
||||
android:id="@+id/pageIndicatorView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/card"
|
||||
app:piv_animationType="worm"
|
||||
app:piv_dynamicCount="true"
|
||||
app:piv_interactiveAnimation="true"
|
||||
app:piv_padding="8dp"
|
||||
app:piv_radius="6dp"
|
||||
app:piv_selectedColor="@color/colorPrimary"
|
||||
app:piv_unselectedColor="@color/pager_unselected"
|
||||
app:piv_viewPager="@id/viewPager" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/forward"
|
||||
style="@style/Widget.App.Button.ElevatedButton.IconOnly"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="48dp"
|
||||
android:layout_marginEnd="48dp"
|
||||
app:icon="@drawable/ic_arrow_forward"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/card"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/card"
|
||||
app:layout_constraintTop_toTopOf="@+id/card" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/backward"
|
||||
style="@style/Widget.App.Button.ElevatedButton.IconOnly"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="48dp"
|
||||
android:layout_marginEnd="48dp"
|
||||
app:icon="@drawable/ic_arrow_back"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/card"
|
||||
app:layout_constraintEnd_toStartOf="@+id/card"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/card" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView 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"
|
||||
android:fillViewport="true">
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<include
|
||||
android:id="@+id/rg_data_source"
|
||||
layout="@layout/data_source_select"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
android:layout_marginEnd="24dp"
|
||||
android:layout_marginBottom="56dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/pref_data_source"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeText2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="32dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/data_sources_description"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:breakStrategy="balanced"
|
||||
app:layout_constraintBottom_toTopOf="@+id/rg_data_source"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.Material3.Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="@string/lets_go"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</ScrollView>
|
||||
189
app/src/main/res/layout-sw720dp/fragment_onboarding_icons.xml
Normal file
@@ -0,0 +1,189 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="28dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/iconLabel1"
|
||||
app:layout_constraintEnd_toEndOf="@+id/iconLabel1"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="@+id/iconLabel1"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.7"
|
||||
app:layout_constraintVertical_chainStyle="packed"
|
||||
app:srcCompat="@drawable/ic_map_marker_charging"
|
||||
app:tint="@color/charger_low"
|
||||
app:tintMode="multiply" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/iconLabel1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="28dp"
|
||||
android:text="< 11 kW"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeTitle"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel2"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/icon1" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="@+id/iconLabel2"
|
||||
app:layout_constraintStart_toStartOf="@+id/iconLabel2"
|
||||
app:layout_constraintTop_toTopOf="@id/icon1"
|
||||
app:srcCompat="@drawable/ic_map_marker_charging"
|
||||
app:tint="@color/charger_11kw"
|
||||
app:tintMode="multiply" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/iconLabel2"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 11 kW"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel3"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel1"
|
||||
app:layout_constraintTop_toBottomOf="@+id/icon2" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="@+id/iconLabel3"
|
||||
app:layout_constraintStart_toStartOf="@+id/iconLabel3"
|
||||
app:layout_constraintTop_toTopOf="@id/icon1"
|
||||
app:srcCompat="@drawable/ic_map_marker_charging"
|
||||
app:tint="@color/charger_20kw"
|
||||
app:tintMode="multiply" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/iconLabel3"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 20 kW"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel4"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel2"
|
||||
app:layout_constraintTop_toBottomOf="@+id/icon3" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon4"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="@+id/iconLabel4"
|
||||
app:layout_constraintStart_toStartOf="@+id/iconLabel4"
|
||||
app:layout_constraintTop_toTopOf="@id/icon1"
|
||||
app:srcCompat="@drawable/ic_map_marker_charging"
|
||||
app:tint="@color/charger_43kw"
|
||||
app:tintMode="multiply" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/iconLabel4"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 43 kW"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel5"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel3"
|
||||
app:layout_constraintTop_toBottomOf="@+id/icon4" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/icon5"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="@+id/iconLabel5"
|
||||
app:layout_constraintStart_toStartOf="@+id/iconLabel5"
|
||||
app:layout_constraintTop_toTopOf="@id/icon1"
|
||||
app:srcCompat="@drawable/ic_map_marker_charging"
|
||||
app:tint="@color/charger_100kw"
|
||||
app:tintMode="multiply" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/iconLabel5"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 100 kW"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel4"
|
||||
app:layout_constraintTop_toBottomOf="@+id/icon5" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_2_title"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeText2"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_2_detail"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:breakStrategy="balanced"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeText"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:breakStrategy="balanced"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="@string/got_it"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/animation_view"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginTop="28dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="28dp"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeTitle"
|
||||
app:layout_constraintDimensionRatio="1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHeight_max="256dp"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintVertical_bias="0.85"
|
||||
app:layout_constraintWidth_max="256dp"
|
||||
app:srcCompat="@drawable/intro_anim_onboarding"
|
||||
android:contentDescription="@string/app_name" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeTitle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_to_evmap"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/welcomeText1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="32dp"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:layout_marginBottom="56dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_1"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:breakStrategy="balanced"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.Material3.Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
android:text="@string/get_started"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -5,7 +5,7 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<fragment
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="net.vonforst.evmap.navigation.NavHostFragment"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/app_name"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline4"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineLarge"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
|
||||
34
app/src/main/res/layout/app_logo_small.xml
Normal file
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout 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="wrap_content"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/imageView2"
|
||||
android:layout_width="48dp"
|
||||
android:layout_height="48dp"
|
||||
android:padding="-4dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/textView14"
|
||||
app:layout_constraintHorizontal_chainStyle="packed"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_launcher_foreground" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView14"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="32dp"
|
||||
android:text="@string/app_name"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleLarge"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@id/imageView2"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/rbGoingElectric"
|
||||
@@ -9,7 +10,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/data_source_goingelectric"
|
||||
android:textColor="#098ac7"
|
||||
android:buttonTint="#098ac7"
|
||||
app:buttonTint="#098ac7"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
@@ -28,7 +29,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/data_source_openchargemap"
|
||||
android:textColor="#587e25"
|
||||
android:buttonTint="#587e25"
|
||||
app:buttonTint="#587e25"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
android:ellipsize="end"
|
||||
android:maxLines="@{expanded ? 3 : 1}"
|
||||
android:text="@{charger.data.name}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
|
||||
app:layout_constrainedWidth="true"
|
||||
app:layout_constraintEnd_toStartOf="@+id/txtAvailability"
|
||||
app:layout_constraintHorizontal_bias="0.0"
|
||||
@@ -99,7 +99,7 @@
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@{charger.data.address.toString()}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
app:layout_constraintTop_toBottomOf="@+id/txtName"
|
||||
@@ -115,7 +115,7 @@
|
||||
android:maxLines="1"
|
||||
android:minWidth="50dp"
|
||||
android:text="@{BindingAdaptersKt.distance(distance)}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/txtConnectors"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
tools:text="10 km" />
|
||||
@@ -131,7 +131,7 @@
|
||||
android:maxLines="1"
|
||||
android:padding="2dp"
|
||||
android:text="@{String.format("%s/%d", BindingAdaptersKt.availabilityText(BindingAdaptersKt.flatten(filteredAvailability.data.status.values())), filteredAvailability.data.totalChargepoints)}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
android:textColor="@android:color/white"
|
||||
app:backgroundTintAvailability="@{BindingAdaptersKt.flatten(availability.data.status.values())}"
|
||||
app:invisibleUnlessAnimated="@{availability.data != null && !expanded}"
|
||||
@@ -149,7 +149,7 @@
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:text="@{charger.data.formatChargepoints(ChargepointApiKt.stringProvider(context))}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/txtDistance"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
app:layout_constraintTop_toBottomOf="@+id/textView2"
|
||||
@@ -174,7 +174,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/connectors"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
|
||||
android:textColor="?colorPrimary"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
@@ -186,7 +186,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/amenities"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
|
||||
android:textColor="?colorPrimary"
|
||||
app:goneUnless="@{charger.data.amenities != null}"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
@@ -200,7 +200,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:text="@{charger.data.amenities}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:autoLink="web"
|
||||
android:linksClickable="true"
|
||||
app:goneUnless="@{charger.data.amenities != null}"
|
||||
@@ -216,7 +216,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/general_info"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
|
||||
android:textColor="?colorPrimary"
|
||||
app:goneUnless="@{charger.data.generalInformation != null}"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
@@ -230,7 +230,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="2dp"
|
||||
android:text="@{charger.data.generalInformation}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:autoLink="web"
|
||||
android:linksClickable="true"
|
||||
app:goneUnless="@{charger.data.generalInformation != null}"
|
||||
@@ -277,7 +277,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/sourceButton"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
style="@style/Widget.Material3.Button.TextButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
@@ -293,7 +293,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="right|end"
|
||||
android:text="@{availability.status == Status.SUCCESS ? @string/realtime_data_source(availability.data.source) : availability.status == Status.LOADING ? @string/realtime_data_loading : @string/realtime_data_unavailable}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline"
|
||||
app:layout_constraintTop_toBottomOf="@+id/connectors"
|
||||
@@ -312,11 +312,12 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnChargeprice"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton.Icon"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/go_to_chargeprice"
|
||||
android:transitionName="@string/shared_element_chargeprice"
|
||||
app:goneUnless="@{charger.data != null && charger.data.chargepriceData != null && charger.data.chargepriceData.country != null && ChargepriceApi.isCountrySupported(charger.data.chargepriceData.country, charger.data.dataSource)}"
|
||||
app:icon="@drawable/ic_chargeprice"
|
||||
app:layout_constraintEnd_toStartOf="@+id/guideline2"
|
||||
@@ -362,7 +363,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:textAlignment="center"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
android:textStyle="italic"
|
||||
android:text="@{charger.data.license}"
|
||||
android:breakStrategy="balanced"
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
android:layout_marginTop="18dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/pref_data_source"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
@@ -41,7 +41,7 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/data_sources_description"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent" />
|
||||
|
||||
@@ -60,7 +60,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnOK"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCancel"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
<TextView
|
||||
android:id="@+id/dialogTitle"
|
||||
style="@style/MaterialAlertDialog.MaterialComponents.Title.Text"
|
||||
style="@style/MaterialAlertDialog.Material3.Title.Text"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="24dp"
|
||||
@@ -31,7 +31,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnAll"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/all"
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnOK"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
@@ -51,7 +51,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnCancel"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
@@ -61,7 +61,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnNone"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginEnd="8dp"
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/tilSearch"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox.Dense"
|
||||
style="@style/Widget.Material3.TextInputLayout.OutlinedBox.Dense"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:maxWidth="200dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ScrollView
|
||||
@@ -44,7 +43,7 @@
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/donation_dialog_title"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/topPanel" />
|
||||
@@ -57,7 +56,7 @@
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:text="@string/donation_dialog_detail"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/welcomeTitle" />
|
||||
@@ -76,7 +75,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGithubSponsors"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
@@ -90,7 +89,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnDonate"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/donate"
|
||||
@@ -100,7 +99,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnOk"
|
||||
style="@style/Widget.MaterialComponents.Button.TextButton.Dialog"
|
||||
style="@style/Widget.Material3.Button.TextButton.Dialog"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/ok"
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
android:id="@+id/linearLayout5"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical">
|
||||
android:orientation="vertical"
|
||||
android:transitionName="@string/shared_element_chargeprice">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/toolbar_container"
|
||||
@@ -27,9 +28,10 @@
|
||||
android:fitsSystemWindows="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:liftOnScroll="true">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:actionBarSize">
|
||||
@@ -48,7 +50,7 @@
|
||||
app:srcCompat="@drawable/ic_powered_by_chargeprice"
|
||||
app:tint="?android:textColorPrimary"
|
||||
tools:ignore="RtlSymmetry" />
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
@@ -68,7 +70,7 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/chargeprice_select_connector"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
|
||||
android:textColor="?colorPrimary"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/vehicle_selection" />
|
||||
@@ -94,7 +96,7 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@{String.format(@string/chargeprice_battery_range, vm.batteryRange[0], vm.batteryRange[1])}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
|
||||
android:textColor="?colorPrimary"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@+id/connectors_list"
|
||||
@@ -107,7 +109,7 @@
|
||||
android:layout_marginStart="4dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@{@string/chargeprice_duration(BindingAdaptersKt.time((int) Math.round(vm.chargepriceMetaForChargepoint.data.duration)))}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
|
||||
android:textColor="?colorPrimary"
|
||||
app:invisibleUnlessAnimated="@{!vm.batteryRangeSliderDragging && vm.chargepriceMetaForChargepoint.status == Status.SUCCESS}"
|
||||
app:layout_constraintStart_toEndOf="@+id/textView2"
|
||||
@@ -122,7 +124,7 @@
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:text="@string/chargeprice_vehicle"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.TitleSmall"
|
||||
android:textColor="?colorPrimary"
|
||||
app:goneUnless="@{vm.vehicles.data != null && vm.vehicles.data.size() > 1}"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -226,7 +228,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnSettings"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="16dp"
|
||||
|
||||
@@ -23,9 +23,10 @@
|
||||
android:fitsSystemWindows="true"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:liftOnScroll="true">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
@@ -70,7 +71,7 @@
|
||||
android:breakStrategy="balanced"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/favorites_empty_state"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:goneUnless="@{vm.listData.size() == 0}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
||||
@@ -21,9 +21,10 @@
|
||||
android:id="@+id/toolbar_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true">
|
||||
android:fitsSystemWindows="true"
|
||||
app:liftOnScroll="true">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:actionBarSize" />
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
@@ -56,7 +56,7 @@
|
||||
android:breakStrategy="balanced"
|
||||
android:gravity="center_horizontal"
|
||||
android:text="@string/filterprofiles_empty_state"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:goneUnless="@{vm.filterProfiles.size() == 0}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
|
||||
@@ -42,78 +42,101 @@
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/toolbar_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_width="@dimen/map_toolbar_width"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true"
|
||||
app:layout_behavior="@string/ScrollingAppBarLayoutBehavior">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
style="?attr/materialCardViewElevatedStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
android:elevation="8dp"
|
||||
android:background="@drawable/rounded_rect_4dp"
|
||||
android:backgroundTint="?android:colorBackground">
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginBottom="8dp"
|
||||
app:cardElevation="4dp"
|
||||
app:cardCornerRadius="24dp"
|
||||
android:theme="@style/NoElevationOverlay">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
app:contentInsetStartWithNavigation="70dp">
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<LinearLayout
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true">
|
||||
android:layout_height="48dp"
|
||||
app:contentInsetStartWithNavigation="70dp">
|
||||
|
||||
<net.vonforst.evmap.ui.AutocompleteTextViewWithSuggestions
|
||||
android:id="@+id/search"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent"
|
||||
android:singleLine="true"
|
||||
android:scrollHorizontally="true"
|
||||
android:ellipsize="end"
|
||||
android:background="@null"
|
||||
android:gravity="center_vertical"
|
||||
android:hint="@string/search"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Subtitle1"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:dropDownVerticalOffset="8dp"
|
||||
android:popupBackground="@drawable/rounded_rect_4dp" />
|
||||
<FrameLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageButton
|
||||
android:id="@+id/clearSearch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
app:invisibleUnless="@{search.text.length() > 0}"
|
||||
app:tint="?colorControlNormal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/handle"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_close"
|
||||
android:contentDescription="@string/delete" />
|
||||
</LinearLayout>
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="horizontal"
|
||||
android:gravity="center_vertical"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true">
|
||||
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
<net.vonforst.evmap.ui.AutocompleteTextViewWithSuggestions
|
||||
android:id="@+id/search"
|
||||
android:layout_width="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_height="match_parent"
|
||||
android:singleLine="true"
|
||||
android:scrollHorizontally="true"
|
||||
android:ellipsize="end"
|
||||
android:background="@null"
|
||||
android:gravity="center_vertical"
|
||||
android:hint="@string/search"
|
||||
android:textSize="18sp"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyLarge"
|
||||
android:textColorHint="@color/hint_text_color"
|
||||
android:dropDownVerticalOffset="8dp"
|
||||
android:popupElevation="2dp"
|
||||
android:popupBackground="@drawable/rounded_rect_24dp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar2"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-10dp"
|
||||
android:layout_marginBottom="-7dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="visible"
|
||||
app:goneUnless="@{ vm.chargepoints.status == Status.LOADING }" />
|
||||
<ImageButton
|
||||
android:id="@+id/clearSearch"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="?attr/selectableItemBackgroundBorderless"
|
||||
app:invisibleUnless="@{search.text.length() > 0}"
|
||||
app:tint="?colorControlNormal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/handle"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:srcCompat="@drawable/ic_close"
|
||||
android:contentDescription="@string/delete" />
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
<include
|
||||
layout="@layout/app_logo_small"
|
||||
android:id="@+id/app_logo"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
</FrameLayout>
|
||||
|
||||
</com.google.android.material.appbar.MaterialToolbar>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar2"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="-10dp"
|
||||
android:layout_marginBottom="-7dp"
|
||||
android:indeterminate="true"
|
||||
android:visibility="visible"
|
||||
app:goneUnless="@{ vm.chargepoints.status == Status.LOADING }" />
|
||||
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
@@ -190,14 +213,15 @@
|
||||
android:src="@drawable/ic_directions"
|
||||
app:layout_anchor="@id/bottom_sheet"
|
||||
app:layout_anchorGravity="top|right|end"
|
||||
app:layout_behavior="@string/ScrollAwareFABBehavior" />
|
||||
app:layout_behavior="@string/ScrollAwareFABBehavior"
|
||||
android:theme="@style/NoElevationOverlay" />
|
||||
|
||||
<com.mahc.custombottomsheetbehavior.MergedAppBarLayout
|
||||
android:id="@+id/detail_app_bar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_behavior="@string/MergedAppBarLayoutBehavior"
|
||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark.ActionBar" />
|
||||
android:theme="@style/ThemeOverlay.Material3.Dark.ActionBar" />
|
||||
|
||||
<com.google.android.material.floatingactionbutton.FloatingActionButton
|
||||
android:id="@+id/fab_layers"
|
||||
@@ -206,25 +230,25 @@
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:layout_gravity="top|end"
|
||||
android:layout_marginEnd="12dp"
|
||||
android:layout_marginTop="96dp"
|
||||
android:elevation="-1dp"
|
||||
android:layout_marginEnd="20dp"
|
||||
android:layout_marginTop="@dimen/layers_fab_top_padding"
|
||||
app:tint="?android:colorControlNormal"
|
||||
app:backgroundTint="?android:colorBackground"
|
||||
app:borderWidth="0dp"
|
||||
app:fabSize="mini"
|
||||
app:srcCompat="@drawable/ic_layers"
|
||||
app:layout_behavior="net.vonforst.evmap.ui.HideOnExpandFabBehavior"/>
|
||||
app:layout_behavior="net.vonforst.evmap.ui.HideOnExpandFabBehavior"
|
||||
android:theme="@style/NoElevationOverlay" />
|
||||
|
||||
<androidx.cardview.widget.CardView
|
||||
android:id="@+id/layers_sheet"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="200dp"
|
||||
android:layout_gravity="top|end"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:layout_marginTop="96dp"
|
||||
android:elevation="-1dp"
|
||||
android:visibility="gone"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginTop="@dimen/layers_fab_top_padding"
|
||||
android:visibility="invisible"
|
||||
app:cardCornerRadius="16dp"
|
||||
tools:visibility="visible">
|
||||
|
||||
<include
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical"
|
||||
android:id="@+id/rl_create_account"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true">
|
||||
@@ -26,7 +25,7 @@
|
||||
app:piv_dynamicCount="true"
|
||||
app:piv_interactiveAnimation="true"
|
||||
app:piv_selectedColor="@color/colorPrimary"
|
||||
app:piv_unselectedColor="@color/colorPrimaryTransparent"
|
||||
app:piv_unselectedColor="@color/colorPrimaryContainer"
|
||||
app:piv_viewPager="@id/viewPager"
|
||||
app:piv_padding="8dp"
|
||||
app:piv_radius="6dp" />
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/pref_data_source"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
@@ -46,7 +46,7 @@
|
||||
android:layout_marginBottom="32dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/data_sources_description"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:breakStrategy="balanced"
|
||||
app:layout_constraintBottom_toTopOf="@+id/rg_data_source"
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.MaterialComponents.Button"
|
||||
style="@style/Widget.Material3.Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
android:layout_marginTop="4dp"
|
||||
android:layout_marginBottom="28dp"
|
||||
android:text="< 11 kW"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeTitle"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel2"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
@@ -51,7 +51,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 11 kW"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel3"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel1"
|
||||
@@ -74,7 +74,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 20 kW"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel4"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel2"
|
||||
@@ -97,7 +97,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 43 kW"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toStartOf="@+id/iconLabel5"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel3"
|
||||
@@ -120,7 +120,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="≥ 100 kW"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
app:layout_constraintStart_toEndOf="@+id/iconLabel4"
|
||||
@@ -135,7 +135,7 @@
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_2_title"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
@@ -150,7 +150,7 @@
|
||||
android:layout_marginBottom="8dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_2_detail"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:breakStrategy="balanced"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
@@ -168,7 +168,7 @@
|
||||
android:breakStrategy="balanced"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_2"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText2"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
@@ -177,7 +177,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
style="@style/Widget.Material3.Button.TonalButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
android:layout_marginBottom="16dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_to_evmap"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Headline6"
|
||||
android:textAppearance="@style/TextAppearance.Material3.HeadlineSmall"
|
||||
app:layout_constraintBottom_toTopOf="@+id/welcomeText1"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintHorizontal_bias="0.5"
|
||||
@@ -48,7 +48,7 @@
|
||||
android:layout_marginBottom="56dp"
|
||||
android:gravity="center"
|
||||
android:text="@string/welcome_1"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
android:textColor="?android:textColorSecondary"
|
||||
android:breakStrategy="balanced"
|
||||
app:layout_constraintBottom_toTopOf="@+id/btnGetStarted"
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnGetStarted"
|
||||
style="@style/Widget.MaterialComponents.Button.OutlinedButton"
|
||||
style="@style/Widget.Material3.Button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="24dp"
|
||||
|
||||
@@ -3,15 +3,17 @@
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/toolbar_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true">
|
||||
android:fitsSystemWindows="true"
|
||||
app:liftOnScroll="true">
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
<com.google.android.material.appbar.MaterialToolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:actionBarSize" />
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:text="@{item.primaryText}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/icon"
|
||||
@@ -63,7 +63,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@{BindingAdaptersKt.distance(item.distanceMeters)}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:goneUnless="@{item.distanceMeters != null}"
|
||||
app:layout_constraintEnd_toEndOf="@+id/icon"
|
||||
app:layout_constraintStart_toStartOf="@+id/icon"
|
||||
@@ -80,7 +80,7 @@
|
||||
android:ellipsize="end"
|
||||
android:singleLine="true"
|
||||
android:text="@{item.secondaryText}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/title"
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{item.tariffName}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body2"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodyMedium"
|
||||
app:layout_constraintBottom_toTopOf="@+id/txtProvider"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ivLogo"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
@@ -57,7 +57,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{item.provider}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:goneUnless="@{!item.tariffName.toLowerCase().startsWith(item.provider.toLowerCase())}"
|
||||
app:layout_constraintBottom_toTopOf="@+id/rvTags"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ivLogo"
|
||||
@@ -83,7 +83,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/chargeprice_provider_customer_tariff"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:goneUnless="@{item.providerCustomerTariff}"
|
||||
app:layout_constraintBottom_toTopOf="@id/txtMonthlyFee"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ivLogo"
|
||||
@@ -96,7 +96,7 @@
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@{item.formatMonthlyFees(context)}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:goneUnless="@{item.totalMonthlyFee > 0 || item.monthlyMinSales > 0}"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toStartOf="@+id/ivLogo"
|
||||
@@ -127,7 +127,7 @@
|
||||
android:gravity="end"
|
||||
android:text="@{String.format(item.chargepointPrices.get(0).priceDistribution.isOnlyKwh ? @string/charge_price_kwh_format : @string/charge_price_average_format, item.chargepointPrices.get(0).price / meta.energy, BindingAdaptersKt.currency(item.currency))}"
|
||||
app:goneUnless="@{item.chargepointPrices.get(0).price > 0}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintBottom_toTopOf="@id/txtPriceDetails"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline5"
|
||||
@@ -142,7 +142,7 @@
|
||||
android:gravity="end"
|
||||
android:text="@{item.chargepointPrices.get(0).formatDistribution(context)}"
|
||||
app:goneUnless="@{!item.chargepointPrices.get(0).formatDistribution(context).empty}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="@+id/guideline5"
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
android:background="@drawable/rounded_rect_16dp"
|
||||
android:maxLines="3"
|
||||
android:text="@{item.text}"
|
||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Caption"
|
||||
android:textAppearance="@style/TextAppearance.Material3.BodySmall"
|
||||
android:textColor="?android:textColorPrimary"
|
||||
android:theme="@style/ThemeOverlay.MaterialComponents.Dark"
|
||||
android:theme="@style/ThemeOverlay.Material3.Dark"
|
||||
android:gravity="center_vertical"
|
||||
android:drawablePadding="4dp"
|
||||
android:paddingEnd="8dp"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
</data>
|
||||
|
||||
<com.google.android.material.chip.Chip
|
||||
style="@style/Widget.MaterialComponents.Chip.Choice"
|
||||
style="@style/Widget.Material3.Chip.Filter"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="4dp"
|
||||
|
||||