diff options
Diffstat (limited to 'androidApp/src')
29 files changed, 684 insertions, 41 deletions
diff --git a/androidApp/src/main/AndroidManifest.xml b/androidApp/src/main/AndroidManifest.xml index 889342f..5d56847 100644 --- a/androidApp/src/main/AndroidManifest.xml +++ b/androidApp/src/main/AndroidManifest.xml @@ -23,5 +23,8 @@ <activity android:name=".units.UnitsActivity" android:exported="false"/> + <activity + android:name=".details.DetailsActivity" + android:exported="false"/> </application> </manifest>
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt index e23c0de..7929832 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/TrackerApp.kt @@ -1,6 +1,7 @@ package mx.trackermap.TrackerMap.android import android.app.Application +import mx.trackermap.TrackerMap.android.details.information.UnitInformationViewModel import mx.trackermap.TrackerMap.android.session.LoginViewModel import mx.trackermap.TrackerMap.android.units.UnitsViewModel import mx.trackermap.TrackerMap.client.apis.DevicesApi @@ -27,6 +28,7 @@ class TrackerApp : Application() { single { UnitsController(get(), get()) } viewModel { LoginViewModel(get(), get()) } + viewModel { UnitInformationViewModel() } single { UnitsViewModel(get()) } } diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt new file mode 100644 index 0000000..12ab79e --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/DetailsActivity.kt @@ -0,0 +1,57 @@ +package mx.trackermap.TrackerMap.android.details + +import android.os.Bundle +import android.util.Log +import androidx.appcompat.app.AppCompatActivity +import com.google.android.material.tabs.TabLayoutMediator +import mx.trackermap.TrackerMap.android.databinding.DetailsActivityBinding +import mx.trackermap.TrackerMap.android.devices.Action + +class DetailsActivity: AppCompatActivity() { + private var _binding: DetailsActivityBinding? = null + private val binding get() = _binding!! + private lateinit var adapter: UnitDetailsAdapter + private var deviceId: Int = 0 + + companion object { + val DEVICE_ID_EXTRA = "device_id" + val ACTION_EXTRA = "action" + } + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + _binding = DetailsActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + + initialize() + } + + override fun onDestroy() { + super.onDestroy() + + _binding = null + } + + private fun initialize() { + deviceId = intent.getIntExtra(DEVICE_ID_EXTRA, 0) + val initialSection = intent.getSerializableExtra(ACTION_EXTRA) as Action + Log.d("DetailsActivity", "Device ID - $deviceId") + Log.d("DetailsActivity", "Initial Section - $initialSection") + + adapter = UnitDetailsAdapter(this, deviceId) + binding.detailsPager.adapter = adapter + TabLayoutMediator(binding.detailsTabs, binding.detailsPager) { tab, position -> + tab.text = when(position) { + 0 -> "Details" + 1 -> "Reports" + else -> "Commands" + } + }.attach() + binding.detailsPager.setCurrentItem(when(initialSection) { + Action.DETAILS -> 0 + Action.REPORTS -> 1 + else -> 2 + }, false) + } +}
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/UnitDetailsAdapter.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/UnitDetailsAdapter.kt new file mode 100644 index 0000000..df13b51 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/UnitDetailsAdapter.kt @@ -0,0 +1,34 @@ +package mx.trackermap.TrackerMap.android.details + +import android.os.Bundle +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentActivity +import androidx.viewpager2.adapter.FragmentStateAdapter +import mx.trackermap.TrackerMap.android.details.commands.UnitCommandsFragment +import mx.trackermap.TrackerMap.android.details.information.UnitInformationFragment +import mx.trackermap.TrackerMap.android.details.reports.UnitReportsFragment + +class UnitDetailsAdapter( + activity: FragmentActivity, + private val deviceId: Int +) : FragmentStateAdapter(activity) { + + companion object { + val DEVICE_ID_ARG = "device_id" + } + + override fun getItemCount(): Int = 3 + + override fun createFragment(position: Int): Fragment { + val fragment = when (position) { + 0 -> UnitInformationFragment() + 1 -> UnitReportsFragment() + else -> UnitCommandsFragment() + } + fragment.arguments = Bundle().apply { + putInt(DEVICE_ID_ARG, deviceId) + } + return fragment + } + +}
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/commands/UnitCommandsFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/commands/UnitCommandsFragment.kt new file mode 100644 index 0000000..0391c16 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/commands/UnitCommandsFragment.kt @@ -0,0 +1,34 @@ +package mx.trackermap.TrackerMap.android.details.commands + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import mx.trackermap.TrackerMap.android.databinding.UnitDetailsCommandsBinding +import mx.trackermap.TrackerMap.android.details.UnitDetailsAdapter + +class UnitCommandsFragment: Fragment() { + private var _binding: UnitDetailsCommandsBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = UnitDetailsCommandsBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val id = arguments?.getInt(UnitDetailsAdapter.DEVICE_ID_ARG) + binding.unitCommandsText.text = "COMMANDS for ID - $id" + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +}
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/information/UnitInformationFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/information/UnitInformationFragment.kt new file mode 100644 index 0000000..758ba36 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/information/UnitInformationFragment.kt @@ -0,0 +1,86 @@ +package mx.trackermap.TrackerMap.android.details.information + +import android.os.Bundle +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.TableRow +import android.widget.TextView +import androidx.fragment.app.Fragment +import mx.trackermap.TrackerMap.android.R +import mx.trackermap.TrackerMap.android.databinding.UnitDetailsInformationBinding +import mx.trackermap.TrackerMap.android.details.UnitDetailsAdapter +import mx.trackermap.TrackerMap.client.models.UnitInformation +import org.koin.androidx.viewmodel.ext.android.viewModel + +class UnitInformationFragment : Fragment() { + + private var _binding: UnitDetailsInformationBinding? = null + private val binding get() = _binding!! + + private val unitInformationViewModel: UnitInformationViewModel by viewModel() + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = UnitDetailsInformationBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + setupObservers() + fetchInformation() + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } + + private fun setupObservers() { + unitInformationViewModel.unit.observe(this) { unitInformation -> + Log.d("UnitInformationFragment", "Unit Information Fetched - $unitInformation") + unitInformation?.let { + displayInformation(it) + } + } + } + + private fun fetchInformation() { + val id = arguments?.getInt(UnitDetailsAdapter.DEVICE_ID_ARG) + unitInformationViewModel.fetchUnit(id ?: 0) + } + + private fun displayInformation(unit: UnitInformation) { + val context = context!! + val details: MutableMap<String, String> = mutableMapOf() + details["Contact"] = unit.device.contact ?: "" + details["Speed"] = context.getString( + R.string.unit_speed_format, + unit.position?.speed?.toInt() ?: 0 + ) + details["Address"] = unit.position?.address ?: "" + details["Latitude"] = "${unit.position?.latitude}" + details["Longitude"] = "${unit.position?.longitude}" + details["Protocol"] = unit.position?.protocol ?: "" + + binding.nameDetail.text = unit.device.name + details.forEach { entry -> + val row = TableRow(context) + val keyText = TextView(context) + val valueText = TextView(context) + + row.addView(keyText) + row.addView(valueText) + binding.informationTable.addView(row) + + keyText.text = entry.key + valueText.text = entry.value + } + } +}
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/information/UnitInformationViewModel.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/information/UnitInformationViewModel.kt new file mode 100644 index 0000000..e7100e1 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/information/UnitInformationViewModel.kt @@ -0,0 +1,26 @@ +package mx.trackermap.TrackerMap.android.details.information + +import android.util.Log +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.launch +import mx.trackermap.TrackerMap.client.models.UnitInformation +import mx.trackermap.TrackerMap.controllers.UnitsController +import org.koin.core.component.KoinComponent +import org.koin.core.component.inject + +class UnitInformationViewModel: ViewModel(), KoinComponent { + @DelicateCoroutinesApi + private val unitsController: UnitsController by inject() + var unit = MutableLiveData<UnitInformation?>() + + init { + Log.d("UnitInformationVM", "Initializing Unit Information View Model") + } + + fun fetchUnit(deviceId: Int) { + unit.postValue(unitsController.getUnit(deviceId)) + } +}
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt new file mode 100644 index 0000000..a2faec8 --- /dev/null +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/details/reports/UnitReportsFragment.kt @@ -0,0 +1,34 @@ +package mx.trackermap.TrackerMap.android.details.reports + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import mx.trackermap.TrackerMap.android.databinding.UnitDetailsReportsBinding +import mx.trackermap.TrackerMap.android.details.UnitDetailsAdapter + +class UnitReportsFragment: Fragment() { + private var _binding: UnitDetailsReportsBinding? = null + private val binding get() = _binding!! + + override fun onCreateView( + inflater: LayoutInflater, + container: ViewGroup?, + savedInstanceState: Bundle? + ): View { + _binding = UnitDetailsReportsBinding.inflate(inflater, container, false) + return binding.root + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + val id = arguments?.getInt(UnitDetailsAdapter.DEVICE_ID_ARG) + binding.unitReportsText.text = "COMMANDS for ID - $id" + } + + override fun onDestroyView() { + super.onDestroyView() + _binding = null + } +}
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt index 4aa210d..c54e8bf 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesAdapter.kt @@ -1,9 +1,15 @@ package mx.trackermap.TrackerMap.android.devices +import android.graphics.Color +import android.graphics.ColorFilter +import android.util.Log import android.view.LayoutInflater import android.view.View import android.view.ViewGroup +import android.view.ViewStructure +import androidx.core.content.res.ResourcesCompat import androidx.recyclerview.widget.RecyclerView +import kotlinx.serialization.json.JsonNull import mx.trackermap.TrackerMap.android.R import mx.trackermap.TrackerMap.android.databinding.UnitItemBinding import mx.trackermap.TrackerMap.client.models.UnitInformation @@ -29,11 +35,46 @@ class DevicesAdapter( holder.toggleOptions(false) val unit = units[position] + val context = holder.itemView.context holder.binding.apply { + + unit.position?.let { position -> + /* Status icon */ + position.speed?.let { speed -> + if (speed >= 2) { + statusIcon.setColorFilter(Color.GREEN) + } else { + statusIcon.setColorFilter(Color.RED) + } + } ?: run { + statusIcon.setColorFilter(Color.GRAY) + } + + /* Engine stop */ + val attributes = position.attributes + if (attributes["out1"].toString() == "null") { + engineStopIcon.visibility = View.GONE + } else { + engineStopIcon.visibility = View.VISIBLE + engineStopIcon.setImageResource( + when (attributes["out1"].toString()) { + "true" -> R.drawable.ic_baseline_lock_24 + "false" -> R.drawable.ic_baseline_lock_open_24 + else -> R.drawable.ic_baseline_lock_open_24 + } + ) + engineStopIcon.contentDescription = when (attributes["out1"].toString()) { + "true" -> context.getString(R.string.unit_lock_on) + "false" -> context.getString(R.string.unit_lock_off) + else -> context.getString(R.string.unit_lock_on) + } + } + } + unitName.text = unit.device.name driverName.text = unit.device.contact - unitSpeed.text = "${unit.position?.speed ?: "--"} Km/h" - lastAddress.text = unit.position?.address ?: "Unknown location" + unitSpeed.text = context.getString(R.string.unit_speed_format, unit.position?.speed?.toInt() ?: 0) + lastAddress.text = unit.position?.address lastDate.text = "yyyy/mm/dd, hh:mm" actionCallback?.let { callback -> detailsButton.setOnClickListener { callback(unit, Action.DETAILS) } @@ -47,17 +88,20 @@ class DevicesAdapter( inner class ViewHolder(val binding: UnitItemBinding) : RecyclerView.ViewHolder(binding.root) { init { - binding.unitCard.setOnClickListener { + binding.unitCard.setOnLongClickListener { toggleOptions(binding.itemOptions.visibility == View.GONE) + true } } fun toggleOptions(shouldExpand: Boolean) { val context = binding.root.context binding.unitCard.setCardBackgroundColor( - context - .resources - .getColor(if (shouldExpand) R.color.background else R.color.darkBackground) + ResourcesCompat.getColor( + context.resources, + if (shouldExpand) R.color.background else R.color.darkBackground, + context.theme + ) ) binding.itemOptions.visibility = if (shouldExpand) View.VISIBLE else View.GONE binding.unitCard.cardElevation = if (shouldExpand) 5.0F else 0.0F diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt index a3ed7a8..6beacec 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/devices/DevicesFragment.kt @@ -1,5 +1,6 @@ package mx.trackermap.TrackerMap.android.devices +import android.content.Intent import android.os.Bundle import android.util.Log import android.view.LayoutInflater @@ -9,6 +10,7 @@ import androidx.fragment.app.Fragment import androidx.recyclerview.widget.LinearLayoutManager import kotlinx.coroutines.DelicateCoroutinesApi import mx.trackermap.TrackerMap.android.databinding.DevicesFragmentBinding +import mx.trackermap.TrackerMap.android.details.DetailsActivity import mx.trackermap.TrackerMap.android.units.UnitsViewModel import mx.trackermap.TrackerMap.client.models.UnitInformation import org.koin.androidx.viewmodel.ext.android.viewModel @@ -62,5 +64,10 @@ class DevicesFragment : Fragment() { private fun itemAction(unit: UnitInformation, action: Action) { Log.d("DevicesFragment", "Action: $action - Unit: $unit") + val activity = requireActivity() + val intent = Intent(activity.applicationContext, DetailsActivity::class.java) + intent.putExtra(DetailsActivity.DEVICE_ID_EXTRA, unit.device.id) + intent.putExtra(DetailsActivity.ACTION_EXTRA, action) + startActivity(intent) } }
\ No newline at end of file diff --git a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt index 60218db..ea40d91 100644 --- a/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt +++ b/androidApp/src/main/java/mx/trackermap/TrackerMap/android/units/UnitsActivity.kt @@ -56,10 +56,19 @@ class UnitsActivity : AppCompatActivity() { private fun setupObservers() { unitsViewModel.unitsDisplayMode.observe(this) { displayMode -> + binding.displayModeToggle.setImageResource( + when (displayMode) { + UnitsViewModel.UnitsDisplayMode.LIST -> R.drawable.ic_baseline_map_24 + UnitsViewModel.UnitsDisplayMode.MAP -> R.drawable.ic_baseline_list_24 + else -> R.drawable.ic_baseline_map_24 + } + ) + val newFragment = when (displayMode) { UnitsViewModel.UnitsDisplayMode.LIST -> DevicesFragment() UnitsViewModel.UnitsDisplayMode.MAP -> MapFragment() + else -> DevicesFragment() } supportFragmentManager.commit { replace(R.id.displayContainer, newFragment) diff --git a/androidApp/src/main/res/drawable/ic_baseline_calendar_today_24.xml b/androidApp/src/main/res/drawable/ic_baseline_calendar_today_24.xml new file mode 100644 index 0000000..e059617 --- /dev/null +++ b/androidApp/src/main/res/drawable/ic_baseline_calendar_today_24.xml @@ -0,0 +1,5 @@ +<vector android:height="14dp" android:tint="?attr/colorControlNormal" + android:viewportHeight="24" android:viewportWidth="24" + android:width="14sp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M20,3h-1L19,1h-2v2L7,3L7,1L5,1v2L4,3c-1.1,0 -2,0.9 -2,2v16c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,5c0,-1.1 -0.9,-2 -2,-2zM20,21L4,21L4,8h16v13z"/> +</vector> diff --git a/androidApp/src/main/res/drawable/ic_baseline_fiber_manual_record_24.xml b/androidApp/src/main/res/drawable/ic_baseline_fiber_manual_record_24.xml new file mode 100644 index 0000000..13890d5 --- /dev/null +++ b/androidApp/src/main/res/drawable/ic_baseline_fiber_manual_record_24.xml @@ -0,0 +1,5 @@ +<vector android:height="14dp" android:tint="?attr/colorControlNormal" + android:viewportHeight="24" android:viewportWidth="24" + android:width="14dp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,12m-8,0a8,8 0,1 1,16 0a8,8 0,1 1,-16 0"/> +</vector> diff --git a/androidApp/src/main/res/drawable/ic_baseline_list_24.xml b/androidApp/src/main/res/drawable/ic_baseline_list_24.xml new file mode 100644 index 0000000..b0e68e0 --- /dev/null +++ b/androidApp/src/main/res/drawable/ic_baseline_list_24.xml @@ -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="@android:color/white" + android:pathData="M3,13h2v-2L3,11v2zM3,17h2v-2L3,15v2zM3,9h2L5,7L3,7v2zM7,13h14v-2L7,11v2zM7,17h14v-2L7,15v2zM7,7v2h14L21,7L7,7z"/> +</vector> diff --git a/androidApp/src/main/res/drawable/ic_baseline_location_on_24.xml b/androidApp/src/main/res/drawable/ic_baseline_location_on_24.xml new file mode 100644 index 0000000..71ef7bc --- /dev/null +++ b/androidApp/src/main/res/drawable/ic_baseline_location_on_24.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="14sp" + android:height="14sp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="@android:color/white" + android:pathData="M12,2C8.13,2 5,5.13 5,9c0,5.25 7,13 7,13s7,-7.75 7,-13c0,-3.87 -3.13,-7 -7,-7zM12,11.5c-1.38,0 -2.5,-1.12 -2.5,-2.5s1.12,-2.5 2.5,-2.5 2.5,1.12 2.5,2.5 -1.12,2.5 -2.5,2.5z"/> +</vector> diff --git a/androidApp/src/main/res/drawable/ic_baseline_lock_24.xml b/androidApp/src/main/res/drawable/ic_baseline_lock_24.xml new file mode 100644 index 0000000..ed352bf --- /dev/null +++ b/androidApp/src/main/res/drawable/ic_baseline_lock_24.xml @@ -0,0 +1,5 @@ +<vector android:height="14sp" android:tint="#B71C1C" + android:viewportHeight="24" android:viewportWidth="24" + android:width="14sp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM15.1,8L8.9,8L8.9,6c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2z"/> +</vector> diff --git a/androidApp/src/main/res/drawable/ic_baseline_lock_open_24.xml b/androidApp/src/main/res/drawable/ic_baseline_lock_open_24.xml new file mode 100644 index 0000000..1fe62c8 --- /dev/null +++ b/androidApp/src/main/res/drawable/ic_baseline_lock_open_24.xml @@ -0,0 +1,5 @@ +<vector android:height="14sp" android:tint="#1B5E20" + android:viewportHeight="24" android:viewportWidth="24" + android:width="14sp" xmlns:android="http://schemas.android.com/apk/res/android"> + <path android:fillColor="@android:color/white" android:pathData="M12,17c1.1,0 2,-0.9 2,-2s-0.9,-2 -2,-2 -2,0.9 -2,2 0.9,2 2,2zM18,8h-1L17,6c0,-2.76 -2.24,-5 -5,-5S7,3.24 7,6h1.9c0,-1.71 1.39,-3.1 3.1,-3.1 1.71,0 3.1,1.39 3.1,3.1v2L6,8c-1.1,0 -2,0.9 -2,2v10c0,1.1 0.9,2 2,2h12c1.1,0 2,-0.9 2,-2L20,10c0,-1.1 -0.9,-2 -2,-2zM18,20L6,20L6,10h12v10z"/> +</vector> diff --git a/androidApp/src/main/res/drawable/ic_baseline_map_24.xml b/androidApp/src/main/res/drawable/ic_baseline_map_24.xml new file mode 100644 index 0000000..d1274d8 --- /dev/null +++ b/androidApp/src/main/res/drawable/ic_baseline_map_24.xml @@ -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="@android:color/white" + android:pathData="M20.5,3l-0.16,0.03L15,5.1 9,3 3.36,4.9c-0.21,0.07 -0.36,0.25 -0.36,0.48V20.5c0,0.28 0.22,0.5 0.5,0.5l0.16,-0.03L9,18.9l6,2.1 5.64,-1.9c0.21,-0.07 0.36,-0.25 0.36,-0.48V3.5c0,-0.28 -0.22,-0.5 -0.5,-0.5zM15,19l-6,-2.11V5l6,2.11V19z"/> +</vector> diff --git a/androidApp/src/main/res/drawable/ic_baseline_person_24.xml b/androidApp/src/main/res/drawable/ic_baseline_person_24.xml new file mode 100644 index 0000000..0faf05d --- /dev/null +++ b/androidApp/src/main/res/drawable/ic_baseline_person_24.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="14sp" + android:height="14sp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="@android:color/white" + android:pathData="M12,12c2.21,0 4,-1.79 4,-4s-1.79,-4 -4,-4 -4,1.79 -4,4 1.79,4 4,4zM12,14c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4z"/> +</vector> diff --git a/androidApp/src/main/res/drawable/ic_baseline_speed_24.xml b/androidApp/src/main/res/drawable/ic_baseline_speed_24.xml new file mode 100644 index 0000000..febd057 --- /dev/null +++ b/androidApp/src/main/res/drawable/ic_baseline_speed_24.xml @@ -0,0 +1,10 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="14sp" + android:height="14sp" + android:viewportWidth="24" + android:viewportHeight="24" + android:tint="?attr/colorControlNormal"> + <path + android:fillColor="@android:color/white" + android:pathData="M20.38,8.57l-1.23,1.85a8,8 0,0 1,-0.22 7.58L5.07,18A8,8 0,0 1,15.58 6.85l1.85,-1.23A10,10 0,0 0,3.35 19a2,2 0,0 0,1.72 1h13.85a2,2 0,0 0,1.74 -1,10 10,0 0,0 -0.27,-10.44zM10.59,15.41a2,2 0,0 0,2.83 0l5.66,-8.49 -8.49,5.66a2,2 0,0 0,0 2.83z"/> +</vector> diff --git a/androidApp/src/main/res/layout/details_activity.xml b/androidApp/src/main/res/layout/details_activity.xml new file mode 100644 index 0000000..00ebdbf --- /dev/null +++ b/androidApp/src/main/res/layout/details_activity.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto"> + + <com.google.android.material.tabs.TabLayout + android:id="@+id/detailsTabs" + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintEnd_toEndOf="parent"/> + + <androidx.viewpager2.widget.ViewPager2 + android:id="@+id/detailsPager" + android:layout_width="match_parent" + android:layout_height="0dp" + app:layout_constraintTop_toBottomOf="@id/detailsTabs" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent"/> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/androidApp/src/main/res/layout/unit_details_commands.xml b/androidApp/src/main/res/layout/unit_details_commands.xml new file mode 100644 index 0000000..dfd6516 --- /dev/null +++ b/androidApp/src/main/res/layout/unit_details_commands.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> + + <TextView + android:id="@+id/unitCommandsText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + tools:text="COMMANDS"/> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/androidApp/src/main/res/layout/unit_details_information.xml b/androidApp/src/main/res/layout/unit_details_information.xml new file mode 100644 index 0000000..f4b6fae --- /dev/null +++ b/androidApp/src/main/res/layout/unit_details_information.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:scrollbars="vertical"> + + <com.google.android.material.card.MaterialCardView + android:layout_width="match_parent" + android:layout_height="wrap_content" + app:cardCornerRadius="@dimen/card_border_radius" + app:cardElevation="@dimen/card_elevation" + app:cardUseCompatPadding="true" + app:contentPadding="@dimen/card_padding"> + + <LinearLayout + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical"> + + <TextView + android:id="@+id/nameDetail" + style="@style/TextAppearance.AppCompat.Headline" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:textColor="@color/colorPrimaryDark" + tools:text="1AAUTO" /> + + <TableLayout + android:id="@+id/informationTable" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:stretchColumns="*"> + <TableRow + android:background="@color/colorPrimary"> + <TextView + android:text="@string/key" + android:textColor="@color/background" + android:paddingHorizontal="@dimen/padding"/> + + <TextView + android:text="@string/value" + android:textColor="@color/background" + android:paddingHorizontal="@dimen/padding"/> + </TableRow> + </TableLayout> + + </LinearLayout> + + </com.google.android.material.card.MaterialCardView> + +</LinearLayout>
\ No newline at end of file diff --git a/androidApp/src/main/res/layout/unit_details_reports.xml b/androidApp/src/main/res/layout/unit_details_reports.xml new file mode 100644 index 0000000..f1b52e3 --- /dev/null +++ b/androidApp/src/main/res/layout/unit_details_reports.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools"> + + <TextView + android:id="@+id/unitReportsText" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintBottom_toBottomOf="parent" + tools:text="REPORTS"/> + +</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file diff --git a/androidApp/src/main/res/layout/unit_item.xml b/androidApp/src/main/res/layout/unit_item.xml index cdf0610..0c4b34d 100644 --- a/androidApp/src/main/res/layout/unit_item.xml +++ b/androidApp/src/main/res/layout/unit_item.xml @@ -9,56 +9,134 @@ app:cardCornerRadius="@dimen/card_border_radius" app:cardElevation="0dp" app:cardUseCompatPadding="true" - app:contentPadding="16dp"> + app:contentPadding="@dimen/card_padding"> - <LinearLayout + <RelativeLayout android:layout_width="match_parent" android:layout_height="wrap_content" - android:orientation="vertical" android:animateLayoutChanges="true"> - <TextView - android:id="@+id/unitName" - android:layout_width="match_parent" + <ImageView + android:id="@+id/statusIcon" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="26dp" - tools:text="1AAUTO" /> + android:layout_marginEnd="5dp" + android:src="@drawable/ic_baseline_fiber_manual_record_24" + app:tint="?android:textColorPrimary" /> - <TextView - android:id="@+id/driverName" - android:layout_width="match_parent" + <ImageView + android:id="@+id/engineStopIcon" + android:layout_width="wrap_content" android:layout_height="wrap_content" - android:textSize="18dp" - tools:text="Javier Zavala" /> + android:layout_toEndOf="@id/statusIcon" + android:visibility="gone" + android:layout_marginEnd="5dp" + android:src="@drawable/ic_baseline_lock_24" /> <TextView - android:id="@+id/unitSpeed" + android:id="@+id/unitName" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textSize="18dp" - tools:text="0 Km/h - Stopped" /> + android:layout_toEndOf="@id/engineStopIcon" + style="@style/TextAppearance.AppCompat.Body2" + tools:text="1AAUTO" /> - <TextView - android:id="@+id/lastAddress" + <GridLayout + android:id="@+id/gridLayout" android:layout_width="match_parent" android:layout_height="wrap_content" - android:textSize="18dp" - tools:text="404 Av. Arboledas, Celaya, Gto." /> + android:layout_below="@id/unitName"> - <TextView - android:id="@+id/lastDate" - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:textSize="18dp" - tools:text="4 de Diciembre de 2021, 7:00 PM" /> + <ImageView + android:id="@+id/driverNameIcon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_marginEnd="6dp" + android:layout_column="0" + android:layout_row="1" + android:contentDescription="@string/unit_driver_name" + android:src="@drawable/ic_baseline_person_24" + app:tint="?android:textColorSecondary" /> + + <TextView + android:id="@+id/driverName" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_column="1" + android:layout_row="1" + style="@style/TextAppearance.AppCompat.Caption" + tools:text="Javier Zavala" /> + + <ImageView + android:id="@+id/unitSpeedIcon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_column="0" + android:layout_row="2" + style="@style/TextAppearance.MaterialComponents.Caption" + android:contentDescription="@string/unit_speed" + android:src="@drawable/ic_baseline_speed_24" + app:tint="?android:textColorSecondary" /> + + <TextView + android:id="@+id/unitSpeed" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_column="1" + android:layout_row="2" + style="@style/TextAppearance.AppCompat.Caption" + tools:text="0 Km/h - Stopped" /> + + <ImageView + android:id="@+id/lastAddressIcon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_column="0" + android:layout_row="3" + android:contentDescription="@string/unit_last_address" + android:src="@drawable/ic_baseline_location_on_24" + app:tint="?android:textColorSecondary" /> + + <TextView + android:id="@+id/lastAddress" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_column="1" + android:layout_row="3" + style="@style/TextAppearance.AppCompat.Caption" + tools:text="404 Av. Arboledas, Celaya, Gto." /> + + <ImageView + android:id="@+id/lastDateIcon" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_column="0" + android:layout_row="4" + android:contentDescription="@string/unit_last_date" + android:src="@drawable/ic_baseline_calendar_today_24" + app:tint="?android:textColorSecondary" /> + + + <TextView + android:id="@+id/lastDate" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_column="1" + android:layout_row="4" + style="@style/TextAppearance.AppCompat.Caption" + tools:text="4 de Diciembre de 2021, 7:00 PM" /> + + </GridLayout> <LinearLayout android:id="@+id/itemOptions" android:layout_width="match_parent" android:layout_height="wrap_content" + android:layout_below="@id/gridLayout" + android:layout_marginTop="@dimen/card_padding" android:gravity="center" android:orientation="horizontal" - android:visibility="gone"> + android:visibility="visible"> <com.google.android.material.button.MaterialButton android:id="@+id/detailsButton" @@ -66,8 +144,8 @@ android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/unit_details" - android:textColor="@color/colorPrimaryDark" - app:backgroundTint="@color/darkBackground" /> + android:textColor="@color/colorAccent" + style="?borderlessButtonStyle" /> <com.google.android.material.button.MaterialButton android:id="@+id/reportsButton" @@ -76,8 +154,8 @@ android:layout_marginHorizontal="8dp" android:layout_weight="1" android:text="@string/unit_reports" - android:textColor="@color/colorPrimaryDark" - app:backgroundTint="@color/darkBackground" /> + android:textColor="@color/colorAccent" + style="?borderlessButtonStyle" /> <com.google.android.material.button.MaterialButton android:id="@+id/commandsButton" @@ -85,11 +163,11 @@ android:layout_height="wrap_content" android:layout_weight="1" android:text="@string/unit_commands" - android:textColor="@color/colorPrimaryDark" - app:backgroundTint="@color/darkBackground" /> + android:textColor="@color/colorAccent" + style="?borderlessButtonStyle" /> </LinearLayout> - </LinearLayout> + </RelativeLayout> </com.google.android.material.card.MaterialCardView>
\ No newline at end of file diff --git a/androidApp/src/main/res/layout/units_activity.xml b/androidApp/src/main/res/layout/units_activity.xml index 4f4ee77..f0d80ab 100644 --- a/androidApp/src/main/res/layout/units_activity.xml +++ b/androidApp/src/main/res/layout/units_activity.xml @@ -37,7 +37,7 @@ app:layout_constraintBottom_toBottomOf="@id/displayModeToggle" android:layout_marginVertical="@dimen/search_vertical_margin" android:layout_marginHorizontal="@dimen/search_horizontal_margin" - app:cardCornerRadius="25dp" + app:cardCornerRadius="@dimen/card_border_radius" app:cardElevation="@dimen/card_elevation"> <com.google.android.material.textfield.TextInputEditText diff --git a/androidApp/src/main/res/values-es-rMX/strings.xml b/androidApp/src/main/res/values-es-rMX/strings.xml new file mode 100644 index 0000000..0da9947 --- /dev/null +++ b/androidApp/src/main/res/values-es-rMX/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <string name="app_name">TrackerMap</string> + + <!-- LoginActivity --> + <string name="login_username">Nombre de usuario</string> + <string name="login_password">Contraseña</string> + <string name="login_login">Iniciar sesión</string> + + <!-- Unit Item --> + <string name="unit_status_on">Estatus encendido</string> + <string name="unit_status_off">Estatus apagado</string> + <string name="unit_lock_on">Paro de motor encendido</string> + <string name="unit_lock_off">Paro de motor apagado</string> + <string name="unit_driver_name">Nombre del conductor</string> + <string name="unit_speed">Velocidad</string> + <string name="unit_last_address">Dirección de la última posición</string> + <string name="unit_last_date">Fecha y hora de la última posición</string> + + <string name="unit_speed_format">%1$d km/h</string> + + <string name="unit_details">Detalles</string> + <string name="unit_reports">Reportes</string> + <string name="unit_commands">Comandos</string> + <string name="units_search">Escribe para buscar</string> +</resources>
\ No newline at end of file diff --git a/androidApp/src/main/res/values/dimen.xml b/androidApp/src/main/res/values/dimen.xml index cd4d970..6ce7887 100644 --- a/androidApp/src/main/res/values/dimen.xml +++ b/androidApp/src/main/res/values/dimen.xml @@ -1,5 +1,7 @@ <?xml version="1.0" encoding="utf-8"?> <resources> + <dimen name="padding">8dp</dimen> + <!-- CardView --> <dimen name="card_border_radius">20dp</dimen> <dimen name="card_elevation">8dp</dimen> diff --git a/androidApp/src/main/res/values/strings.xml b/androidApp/src/main/res/values/strings.xml index 0a42223..5692688 100644 --- a/androidApp/src/main/res/values/strings.xml +++ b/androidApp/src/main/res/values/strings.xml @@ -8,8 +8,21 @@ <string name="login_login">Login</string> <!-- Unit Item --> + <string name="unit_status_on">Status on</string> + <string name="unit_status_off">Status off</string> + <string name="unit_lock_on">Engine stop on</string> + <string name="unit_lock_off">Engine stop off</string> + <string name="unit_driver_name">Driver name</string> + <string name="unit_speed">Speed</string> + <string name="unit_last_address">Last position address</string> + <string name="unit_last_date">Last position datetime</string> + + <string name="unit_speed_format">%1$d km/h</string> + <string name="unit_details">Details</string> <string name="unit_reports">Reports</string> <string name="unit_commands">Commands</string> <string name="units_search">Type to search</string> + <string name="key">Key</string> + <string name="value">Value</string> </resources>
\ No newline at end of file |