Commit ccad05f0 authored by Nikolay Kazakov's avatar Nikolay Kazakov
Browse files

Переработал дизайн приложения, добавил много интересных фишек, кастомный...

Переработал дизайн приложения, добавил много интересных фишек, кастомный диалог фильтров, расчет дистанции на кнопку Маршрут
parent 72eb7528
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AideConfiguration">
<option name="idTask" value="1513" />
<option name="idTask" value="1518" />
<option name="password" value="eb5u2dLN19" />
<option name="url" value="http://logjob1.h1n.ru/" />
<option name="username" value="admin" />
......
......@@ -43,6 +43,7 @@
<activity
android:name="ru.bingosoft.teploInspector.ui.mainactivity.MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
......@@ -53,6 +54,7 @@
<activity
android:name="ru.bingosoft.teploInspector.ui.login.LoginActivity"
android:label="@string/title_activity_login"
android:screenOrientation="portrait"
android:theme="@style/AppTheme.NoActionBar" />
<uses-library
......
......@@ -36,6 +36,7 @@ class App : Application(), HasAndroidInjector {
//https://stackoverflow.com/questions/52631581/rxjava2-undeliverableexception-when-orientation-change-is-happening-while-fetchi
RxJavaPlugins.setErrorHandler { throwable: Throwable? -> }
}
override fun androidInjector(): AndroidInjector<Any> = androidInjector
......
......@@ -20,18 +20,24 @@ data class Orders (
@SerializedName("name")
var name: String? = null,
@SerializedName("adress")
var adress: String? = null,
var address: String? = null,
@SerializedName("contactFio")
var contactFio: String? = null,
@SerializedName("phone")
var phone: String? = null,
@SerializedName("state")
var state: String? = null,
var state: String = "В работе",
@SerializedName("comment")
var comment: String? = null,
@SerializedName("dateCreate")
var dateCreate: Date? = null,
@SerializedName("typeOrder")
var typeOrder: String? = "Тип заявки",
@SerializedName("typeTransportation")
var typeTransportation: String? = "Транспортировка выполняется заказчиком",
@SerializedName("lat")
var lat: Double = 0.0,
@SerializedName("lon")
......
......@@ -10,6 +10,7 @@ import ru.bingosoft.teploInspector.ui.mainactivity.MainActivity
import ru.bingosoft.teploInspector.ui.map.MapFragment
import ru.bingosoft.teploInspector.ui.map_bottom.MapBottomSheet
import ru.bingosoft.teploInspector.ui.order.OrderFragment
import ru.bingosoft.teploInspector.ui.route_detail.RouteDetailFragment
@Module
abstract class ActivityBuilder {
......@@ -37,4 +38,7 @@ abstract class ActivityBuilder {
@ContributesAndroidInjector(modules = [PresentersModule::class])
abstract fun bindMapBottomSheet(): MapBottomSheet
@ContributesAndroidInjector(modules = [PresentersModule::class])
abstract fun bindRouteDetailFragment(): RouteDetailFragment
}
\ No newline at end of file
......@@ -3,9 +3,7 @@ package ru.bingosoft.teploInspector.di
import dagger.Module
import dagger.Provides
import ru.bingosoft.teploInspector.App
import ru.bingosoft.teploInspector.util.PhotoHelper
import ru.bingosoft.teploInspector.util.SharedPrefSaver
import ru.bingosoft.teploInspector.util.Toaster
import ru.bingosoft.teploInspector.util.*
import javax.inject.Singleton
@Module
......@@ -27,4 +25,16 @@ class UtilModule {
fun providePhotoHelper(): PhotoHelper {
return PhotoHelper()
}
@Provides
@Singleton
fun provideOtherUtil(): OtherUtil {
return OtherUtil()
}
@Provides
@Singleton
fun provideUserLocationNative(): UserLocationNative {
return UserLocationNative()
}
}
\ No newline at end of file
package ru.bingosoft.teploInspector.models
import android.widget.TextView
import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName
import ru.bingosoft.teploInspector.db.Checkup.Checkup
......@@ -90,6 +91,11 @@ class Models {
@SerializedName("lon") var lon: Double? = 0.0
)*/
class CustomMarker(
val order: Orders,
val markerView: TextView
)
class MapPoint(
@SerializedName("lat") var lat: Double? = 0.0,
@SerializedName("lon") var lon: Double? = 0.0
......
......@@ -33,6 +33,7 @@ class CheckupPresenter @Inject constructor(val db: AppDatabase) {
Timber.d(it.toString())
view?.dataIsLoaded(it)
disposable.dispose()
}
Timber.d("ОК")
......
......@@ -8,4 +8,6 @@ interface FragmentsContractActivity {
fun setCheckup(checkup: Checkup)
fun setChecupListOrder(order: Orders)
fun setCoordinates(point: Point, controlId: Int)
//fun setDataForRouteDetail(order: Orders, mapFragment: MapFragment)
fun setOrder(order: Orders)
}
\ No newline at end of file
......@@ -8,17 +8,14 @@ import android.content.DialogInterface
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.location.Location
import android.location.LocationManager
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.TextView
import android.view.*
import android.widget.*
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.Toolbar
import androidx.core.content.ContextCompat
......@@ -46,6 +43,7 @@ import ru.bingosoft.teploInspector.models.Models
import ru.bingosoft.teploInspector.ui.checkup.CheckupFragment
import ru.bingosoft.teploInspector.ui.checkuplist.CheckupListFragment
import ru.bingosoft.teploInspector.ui.login.LoginActivity
import ru.bingosoft.teploInspector.ui.map.MapFragment
import ru.bingosoft.teploInspector.util.*
import ru.bingosoft.teploInspector.util.Const.MessageCode.REFUSED_PERMISSION
import ru.bingosoft.teploInspector.util.Const.MessageCode.REPEATEDLY_REFUSED
......@@ -56,7 +54,7 @@ import javax.inject.Inject
class MainActivity : AppCompatActivity(), FragmentsContractActivity,
NavigationView.OnNavigationItemSelectedListener, MainActivityContractView {
NavigationView.OnNavigationItemSelectedListener, MainActivityContractView, View.OnClickListener {
@Inject
lateinit var mainPresenter: MainActivityPresenter
......@@ -80,6 +78,8 @@ class MainActivity : AppCompatActivity(), FragmentsContractActivity,
var photoStep: Models.TemplateControl?=null
lateinit var currentOrder: Orders
private lateinit var locationManager: LocationManager
lateinit var dialogView: View
lateinit var filterView: RelativeLayout
override fun onCreate(savedInstanceState: Bundle?) {
Timber.d("MainActivity_onCreate")
......@@ -90,6 +90,7 @@ class MainActivity : AppCompatActivity(), FragmentsContractActivity,
val toolbar: Toolbar = findViewById(R.id.toolbar)
setSupportActionBar(toolbar)
mainPresenter.attachView(this)
// Запросим разрешение на геолокацию, нужны для сервиса
......@@ -171,6 +172,14 @@ class MainActivity : AppCompatActivity(), FragmentsContractActivity,
navView.setNavigationItemSelectedListener(this)
//navView.setupWithNavController(navController) // Переключалка фрагментов по-умолчанию
val header=navView.getHeaderView(0)
val imgButtonAuth=header.findViewById<ImageButton>(R.id.imgbAuth)
imgButtonAuth.setOnClickListener {
Timber.d("Auth")
// Запустим активити с настройками
val intent = Intent(this, LoginActivity::class.java)
startActivityForResult(intent, Const.RequestCodes.AUTH)
}
}
private fun buildAlertMessageNoGps() {
......@@ -239,10 +248,22 @@ class MainActivity : AppCompatActivity(), FragmentsContractActivity,
}
override fun onCreateOptionsMenu(menu: Menu): Boolean {
// Inflate the menu; this adds items to the action bar if it is present.
menuInflater.inflate(R.menu.main, menu)
return true
val item = menu.findItem(R.id.menu_buttons)
item.setActionView(R.layout.filter_count)
filterView=item.actionView as RelativeLayout
val btnFilter=filterView.findViewById<Button>(R.id.btnFilter)
btnFilter.setOnClickListener(this)
val searchView=item.actionView as RelativeLayout
val btnSearch=searchView.findViewById<Button>(R.id.btnSearch)
btnSearch.setOnClickListener(this)
return super.onCreateOptionsMenu(menu)
}
override fun onSupportNavigateUp(): Boolean {
......@@ -304,6 +325,9 @@ class MainActivity : AppCompatActivity(), FragmentsContractActivity,
if (supportFragmentManager.backStackEntryCount==0) {
supportActionBar?.setTitle(R.string.menu_orders)
// Выделим кнопку Список
findViewById<Button>(R.id.btnList).isEnabled=false
findViewById<Button>(R.id.btnMap).isEnabled=true
}
val fragment=supportFragmentManager.findFragmentByTag("checkup_fragment_tag")
......@@ -346,6 +370,12 @@ class MainActivity : AppCompatActivity(), FragmentsContractActivity,
this.controlMapId=controlId
}
override fun setOrder(order: Orders) {
Timber.d("setOrderForRouteDetail from Activity")
val mf=this.supportFragmentManager.findFragmentByTag("map_fragment_from_orders_tag") as? MapFragment
mf?.showRouteDialog(order)
}
private fun setPhotoResult() {
var photoLocation:Location?=Location(LocationManager.GPS_PROVIDER)
try {
......@@ -379,10 +409,6 @@ class MainActivity : AppCompatActivity(), FragmentsContractActivity,
navController.navigate(R.id.nav_home)
return true
}
R.id.nav_gallery -> {
navController.navigate(R.id.nav_gallery)
return true
}
R.id.nav_slideshow -> {
navController.navigate(R.id.nav_slideshow)
return true
......@@ -393,29 +419,6 @@ class MainActivity : AppCompatActivity(), FragmentsContractActivity,
//mainPresenter.isCheckupWithResult()
return true
}
R.id.nav_auth -> {
// Запустим активити с настройками
val intent = Intent(this, LoginActivity::class.java)
startActivityForResult(intent, Const.RequestCodes.AUTH)
return true
}
R.id.nav_qr_scan -> {
// Запустим сканер QR
return try {
val intent = Intent("com.google.zxing.client.android.SCAN")
intent.putExtra("SCAN_MODE", "QR_CODE_MODE")
startActivityForResult(intent, QR_SCAN)
true
} catch (e: Exception) {
val marketUri = Uri.parse("market://details?id=com.google.zxing.client.android")
val marketIntent = Intent(Intent.ACTION_VIEW,marketUri)
startActivity(marketIntent)
false
}
}
else -> {
return false
}
......@@ -474,4 +477,70 @@ class MainActivity : AppCompatActivity(), FragmentsContractActivity,
}
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.btnFilter -> {
Timber.d("Открываем окно с фильтром")
Timber.d("dialogFilterOrder")
lateinit var dialogFilterOrder: AlertDialog
val layoutInflater = LayoutInflater.from(this)
dialogView =
layoutInflater.inflate(R.layout.alert_filter_order, null, false)
val builder = AlertDialog.Builder(this)
builder.setView(dialogView)
builder.setCancelable(true)
dialogFilterOrder=builder.create()
dialogFilterOrder.window?.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
//Меняем позицию диалога
dialogFilterOrder.window?.setGravity(Gravity.TOP or Gravity.RIGHT)
dialogFilterOrder.setOnCancelListener(dialogCancelListener)
dialogFilterOrder.show()
// Установим ширину диалогового окна
val width=resources.getDimension(R.dimen.dialog_filter_width).toInt()
dialogFilterOrder.window?.setLayout(width, LinearLayout.LayoutParams.WRAP_CONTENT)
// Отступы диалога от границ экрана
val wlp=dialogFilterOrder.window?.attributes
wlp?.y=50
wlp?.x=50
dialogFilterOrder.window?.attributes=wlp
}
R.id.btnSearch -> {
Timber.d("Открываем окно с поиском")
}
}
}
val dialogCancelListener=object: DialogInterface.OnCancelListener{
override fun onCancel(dialog: DialogInterface?) {
Timber.d("setOnCancelListener")
// Считаем сколько фильтров поставили
val cb1=dialogView.findViewById<CheckBox>(R.id.cbType1)
val cb2=dialogView.findViewById<CheckBox>(R.id.cbType2)
val cb3=dialogView.findViewById<CheckBox>(R.id.cbType3)
val cb4=dialogView.findViewById<CheckBox>(R.id.cbType4)
var filterCount=0
if (cb1.isChecked) { filterCount+=1 }
if (cb2.isChecked) { filterCount+=1 }
if (cb3.isChecked) { filterCount+=1 }
if (cb4.isChecked) { filterCount+=1 }
Timber.d("filterCount=$filterCount")
filterView.findViewById<TextView>(R.id.badge_count).text=filterCount.toString()
// Фильтруем заявки
Timber.d("Фильтруем заявки")
}
}
}
......@@ -25,14 +25,15 @@ class UserLocationReceiver @Inject constructor(
lateinit var lastKnownLocation: Location
override fun onReceive(context: Context?, intent: Intent?) {
Timber.d("onReceive")
val lat=intent?.getDoubleExtra("lat",0.0)
val lon=intent?.getDoubleExtra("lon",0.0)
val provider=intent?.getStringExtra("provider")
/*lastKnownLocation=Location(provider)
lastKnownLocation=Location(provider)
if (lat!=null && lon!=null) {
lastKnownLocation.longitude=lon
lastKnownLocation.latitude=lat
}*/
}
val status=intent?.getStringExtra("status")
if (status==PROVIDER_DISABLED) {
......
......@@ -11,6 +11,7 @@ import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
......@@ -22,10 +23,7 @@ import com.yandex.mapkit.directions.Directions
import com.yandex.mapkit.directions.DirectionsFactory
import com.yandex.mapkit.geometry.Point
import com.yandex.mapkit.layers.ObjectEvent
import com.yandex.mapkit.location.FilteringMode
import com.yandex.mapkit.location.Location
import com.yandex.mapkit.location.LocationListener
import com.yandex.mapkit.location.LocationStatus
import com.yandex.mapkit.location.*
import com.yandex.mapkit.map.*
import com.yandex.mapkit.map.Map
import com.yandex.mapkit.mapview.MapView
......@@ -40,9 +38,12 @@ import dagger.android.support.AndroidSupportInjection
import ru.bingosoft.teploInspector.BuildConfig
import ru.bingosoft.teploInspector.R
import ru.bingosoft.teploInspector.db.Orders.Orders
import ru.bingosoft.teploInspector.models.Models
import ru.bingosoft.teploInspector.ui.checkup.CheckupFragment
import ru.bingosoft.teploInspector.ui.mainactivity.FragmentsContractActivity
import ru.bingosoft.teploInspector.ui.map_bottom.MapBottomSheet
import ru.bingosoft.teploInspector.ui.order.OrderFragment
import ru.bingosoft.teploInspector.ui.route_detail.RouteDetailFragment
import ru.bingosoft.teploInspector.util.Const.Location.DESIRED_ACCURACY
import ru.bingosoft.teploInspector.util.Const.Location.MINIMAL_DISTANCE
import ru.bingosoft.teploInspector.util.Const.Location.MINIMAL_TIME
......@@ -55,13 +56,13 @@ import timber.log.Timber
import javax.inject.Inject
class MapFragment : Fragment(), MapContractView, IOnBackPressed {
class MapFragment : Fragment(), MapContractView, IOnBackPressed, View.OnClickListener {
val fragment=this
lateinit var mapView: MapView
lateinit var map: Map
lateinit var userLocationLayer: UserLocationLayer
lateinit var locationManager:LocationManager
@Inject
lateinit var mapPresenter: MapPresenter
......@@ -76,6 +77,9 @@ class MapFragment : Fragment(), MapContractView, IOnBackPressed {
lateinit var directions: Directions
lateinit var transports: Transport
var lastCarRouter=mutableListOf<PolylineMapObject>()
var prevMapObjectMarker: MapObject?=null
lateinit var order: Orders
private val mapLoadedListener=object:MapLoadedListener{
override fun onMapLoaded(p0: MapLoadStatistics) {
......@@ -99,6 +103,11 @@ class MapFragment : Fragment(), MapContractView, IOnBackPressed {
}
}
fun showRouteDialog(order: Orders) {
val routeDetailFragment = RouteDetailFragment(order, this)
routeDetailFragment.show(fragment.requireActivity().supportFragmentManager,"BOTTOM_SHEET_ROUTE_DETAIL")
}
private val inputListener=object:InputListener {
override fun onMapLongTap(p0: Map, p1: Point) {
Timber.d("onMapLongTap")
......@@ -134,6 +143,14 @@ class MapFragment : Fragment(), MapContractView, IOnBackPressed {
if (lastCarRouter.isNotEmpty()) {
removeRouter(lastCarRouter)
}
if (prevMapObjectMarker!=null) {
// выключим предыдущий маркер
val prevTvMarker=(prevMapObjectMarker!!.userData as Models.CustomMarker).markerView
prevTvMarker.isEnabled=!prevTvMarker.isEnabled
(prevMapObjectMarker as PlacemarkMapObject).setView(ViewProvider(prevTvMarker))
prevMapObjectMarker=null
}
}
}
......@@ -216,13 +233,34 @@ class MapFragment : Fragment(), MapContractView, IOnBackPressed {
}
}
private val mapObjectTapListener=object:MapObjectTapListener{
val mapObjectTapListener=object:MapObjectTapListener{
override fun onMapObjectTap(mapObject: MapObject, p1: Point): Boolean {
Timber.d("onMapObjectTap")
val order=(mapObject.userData as Models.CustomMarker).order
val tvMarker=(mapObject.userData as Models.CustomMarker).markerView
if (prevMapObjectMarker!=null) {
// выключим предыдущий маркер
val prevTvMarker=(prevMapObjectMarker!!.userData as Models.CustomMarker).markerView
prevTvMarker.isEnabled=!prevTvMarker.isEnabled
(prevMapObjectMarker as PlacemarkMapObject).setView(ViewProvider(prevTvMarker))
}
tvMarker.isEnabled=!tvMarker.isEnabled
(mapObject as PlacemarkMapObject).setView(ViewProvider(tvMarker))
prevMapObjectMarker=mapObject
val order=(mapObject.userData as Orders)
if (locationListener.lastLocation!=null) {
val mapBottomSheet = MapBottomSheet(order, locationListener.lastLocation!!.position,fragment)
mapBottomSheet.show(fragment.requireActivity().supportFragmentManager,"BOTTOM_SHEET")
} else {
Timber.d("locationListener.lastLocation==null")
locationManager.requestSingleUpdate(locationListener)
if (locationListener.lastLocation!=null) {
val mapBottomSheet = MapBottomSheet(order, locationListener.lastLocation!!.position,fragment)
mapBottomSheet.show(fragment.requireActivity().supportFragmentManager,"BOTTOM_SHEET")
}
}
return true
......@@ -237,34 +275,44 @@ class MapFragment : Fragment(), MapContractView, IOnBackPressed {
): View? {
AndroidSupportInjection.inject(this)
MapKitFactory.setApiKey(BuildConfig.yandex_mapkit_api)
MapKitFactory.setLocale("ru_RU")
MapKitFactory.initialize(this.context)
DirectionsFactory.initialize(this.context)
TransportFactory.initialize(this.context)
directions=DirectionsFactory.getInstance()
transports=TransportFactory.getInstance()
val locationManager=MapKitFactory.getInstance().createLocationManager()
locationManager=MapKitFactory.getInstance().createLocationManager()
val root = inflater.inflate(R.layout.fragment_map, container, false)
(this.requireActivity() as AppCompatActivity).supportActionBar?.setTitle(R.string.menu_map)
(this.requireActivity() as AppCompatActivity).supportActionBar?.setTitle(R.string.menu_orders)
mapView=root.findViewById(R.id.mapView)
mapView.map.move(CameraPosition(TARGET_POINT,ZOOM_LEVEL,0.0f,0.0f), Animation(Animation.Type.SMOOTH,0.0f),null)
mapView.map.move(CameraPosition(TARGET_POINT,ZOOM_LEVEL,0.0f,0.0f), Animation(Animation.Type.SMOOTH,0.0f), null)
locationManager.subscribeForLocationUpdates(DESIRED_ACCURACY, MINIMAL_TIME, MINIMAL_DISTANCE, USE_IN_BACKGROUND,FilteringMode.ON,locationListener)
map=mapView.map
map.setMapLoadedListener(mapLoadedListener) // Обработчик когда карта загружена
map.setMapLoadedListener(mapLoadedListener) // Обработчик, когда карта загружена
map.addInputListener(inputListener) // Обработчик клика на карте
val btnList=root.findViewById<Button>(R.id.btnList)
btnList.setOnClickListener(this)
val btnMap=root.findViewById<Button>(R.id.btnMap)
btnMap.setOnClickListener(this)
return root
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
Timber.d("MapFragment_onCreate")
MapKitFactory.setApiKey(BuildConfig.yandex_mapkit_api)
MapKitFactory.setLocale("ru_RU")
MapKitFactory.initialize(this.context)
DirectionsFactory.initialize(this.context)
TransportFactory.initialize(this.context)
directions=DirectionsFactory.getInstance()
transports=TransportFactory.getInstance()
}
override fun onStart() {
super.onStart()
......@@ -290,10 +338,14 @@ class MapFragment : Fragment(), MapContractView, IOnBackPressed {
private fun importOrdersOnMap(order: Orders) {
Timber.d("importOrdersOnMap=$order")
val view=layoutInflater.inflate(R.layout.template_marker,null)
view.findViewById<TextView>(R.id.markerText).text=order.number
val tvMarker=view.findViewById<TextView>(R.id.tvMarker)
tvMarker.text=order.number
val customMarker=Models.CustomMarker(order=order,markerView = tvMarker)
val placemarkMapObject=map.mapObjects.addPlacemark(Point(order.lat,order.lon),ViewProvider(view))
placemarkMapObject.userData=order
placemarkMapObject.userData=customMarker
placemarkMapObject.addTapListener(mapObjectTapListener)
}
......@@ -310,13 +362,13 @@ class MapFragment : Fragment(), MapContractView, IOnBackPressed {
)
} else {
getUserLocation()
initUserLocationLayer()
}
}
private fun getUserLocation() {
Timber.d("getUserLocation")
private fun initUserLocationLayer() {
Timber.d("initUserLocationLayer")
val mapKit=MapKitFactory.getInstance()
userLocationLayer=mapKit.createUserLocationLayer(mapView.mapWindow)
userLocationLayer.isVisible=true
......@@ -374,7 +426,37 @@ class MapFragment : Fragment(), MapContractView, IOnBackPressed {
return bitmap
}
override fun onClick(v: View?) {
if (v != null) {
when (v.id) {
R.id.btnList -> {
v.isEnabled=false
(v.parent as View).findViewById<Button>(R.id.btnMap).isEnabled=true
val fragmentOrder= OrderFragment()
//fragmentMap.arguments=bundle
val fragmentManager=this.requireActivity().supportFragmentManager
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment, fragmentOrder, "")
.addToBackStack(null)
.commit()
fragmentManager.executePendingTransactions()
//(this.requireActivity() as FragmentsContractActivity).setChecupListOrder(currentOrder)
}
R.id.btnMap -> {
v.isEnabled=false
(v.parent as View).findViewById<Button>(R.id.btnList).isEnabled=true
}
}
}
}
}
\ No newline at end of file
package ru.bingosoft.teploInspector.ui.map_bottom
import android.app.Dialog
import android.graphics.Color
import android.content.Context
import android.content.Intent
import android.location.LocationManager
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.widget.Button
import android.widget.TextView
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.core.content.ContextCompat
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.yandex.mapkit.RequestPoint
import com.yandex.mapkit.RequestPointType
import com.yandex.mapkit.directions.driving.DrivingOptions
import com.yandex.mapkit.directions.driving.DrivingRoute
import com.yandex.mapkit.directions.driving.DrivingRouter
import com.yandex.mapkit.directions.driving.DrivingSession
import com.yandex.mapkit.geometry.Point
import com.yandex.mapkit.geometry.Polyline
import com.yandex.mapkit.geometry.SubpolylineHelper
import com.yandex.mapkit.transport.masstransit.*
import com.yandex.runtime.Error
import com.yandex.runtime.network.NetworkError
import com.yandex.runtime.network.RemoteError
import dagger.android.support.AndroidSupportInjection
import ru.bingosoft.teploInspector.R
import ru.bingosoft.teploInspector.db.Orders.Orders
import ru.bingosoft.teploInspector.ui.map.MapFragment
import ru.bingosoft.teploInspector.util.OtherUtil
import ru.bingosoft.teploInspector.util.Toaster
import ru.bingosoft.teploInspector.util.UserLocationNative
import timber.log.Timber
import java.text.SimpleDateFormat
import java.util.*
import javax.inject.Inject
class MapBottomSheet(val order: Orders, private val userLocation: Point, val parentFragment: MapFragment): BottomSheetDialogFragment(), MapBottomSheetContractView, View.OnClickListener {
private lateinit var carRouter: DrivingRouter
private lateinit var busRouter: MasstransitRouter
class MapBottomSheet(val order: Orders, private val userLocation: Point, private val parentFragment: MapFragment): BottomSheetDialogFragment(), MapBottomSheetContractView, View.OnClickListener {
private lateinit var rootView: View
......@@ -45,192 +37,83 @@ class MapBottomSheet(val order: Orders, private val userLocation: Point, val par
@Inject
lateinit var toaster: Toaster
private var drivingSession: DrivingSession? = null
private val requestPoints: ArrayList<RequestPoint> = ArrayList()
lateinit var foundingRoutes: MutableList<Route>
@Inject
lateinit var otherUtil: OtherUtil
private val routerRVClickListeners=object:RouterRVClickListeners{
override fun routerRVListClicked(v: View?, position: Int) {
Timber.d("routerRVListClicked")
// Строим маршрут
val route=foundingRoutes[position]
val sections= route.sections
Timber.d("sections=${sections.size}")
sections.forEach{
Timber.d("section=${it.metadata.data.transports?.get(0)?.line?.name}")
drawSection(
it.metadata.data,
SubpolylineHelper.subpolyline(
route.geometry, it.geometry
))
}
@Inject
lateinit var userLocationNative: UserLocationNative
hideBottomSheet()
}
override fun onCreate(savedInstanceState: Bundle?) {
AndroidSupportInjection.inject(this)
super.onCreate(savedInstanceState)
val locationManager=this.requireContext().getSystemService(Context.LOCATION_SERVICE) as LocationManager
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 10f, userLocationNative.locationListener)
}
override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style)
fun drawSection(data: SectionMetadata.SectionData, geometry: Polyline) {
val polylineMapObject = parentFragment.mapView.map.mapObjects.addPolyline(geometry)
parentFragment.lastCarRouter.add(polylineMapObject) // Сохраним маршрут, чтоб потом можно было его удалить
if (data.transports != null) {
val transports=data.transports
transports!!.forEach {
if (it.line.style != null) {
polylineMapObject.strokeColor = it.line.style!!.color!!
return
}
}
Timber.d("MapBottomSheet_setupDialog")
val knownVehicleTypes = HashSet<String>()
knownVehicleTypes.add("bus")
knownVehicleTypes.add("tramway")
val view=
LayoutInflater.from(context).inflate(R.layout.map_bottom_sheet,null)
this.rootView=view
dialog.setContentView(view)
transports.forEach {
val sectionVehicleType = getVehicleType(it, knownVehicleTypes)
if (sectionVehicleType.equals("bus")) {
polylineMapObject.strokeColor = Color.GREEN
return
} else if (sectionVehicleType.equals("tramway")) {
polylineMapObject.strokeColor = Color.RED
return
}
}
polylineMapObject.strokeColor = Color.BLUE
view.findViewById<TextView>(R.id.number).text=order.number
view.findViewById<TextView>(R.id.order_type).text=order.typeOrder
if (order.typeOrder.isNullOrEmpty()){
view.findViewById<TextView>(R.id.order_type).text="Нет данных"
} else {
polylineMapObject.strokeColor = Color.BLACK
view.findViewById<TextView>(R.id.order_type).text=order.typeOrder
}
}
//https://github.com/yandex/mapkit-android-demo/blob/master/src/main/java/com/yandex/mapkitdemo/MasstransitRoutingActivity.java
private val routeListener=object:Session.RouteListener{
override fun onMasstransitRoutesError(error: Error) {
var errorMessage = getString(R.string.unknown_error_message)
if (error is RemoteError) {
errorMessage = getString(R.string.remote_error_message)
} else if (error is NetworkError) {
errorMessage = getString(R.string.network_error_message)
}
toaster.showToast(errorMessage)
when (order.state) {
"1" -> view.findViewById<TextView>(R.id.order_state).text="В работе"
}
override fun onMasstransitRoutes(routes: MutableList<Route>) {
showRoutersList(routes)
if (routes.isNotEmpty()) {
foundingRoutes=routes
}
/*if (routes.isNotEmpty()) {
val sections= routes[0].sections
Timber.d("sections=${sections.size}")
sections.forEach{
Timber.d("section=${it.metadata.data.transports?.get(0)?.line?.name}")
drawSection(
it.metadata.data,
SubpolylineHelper.subpolyline(
routes[0].geometry, it.geometry
))
}
}*/
}
fun showRoutersList(routes: MutableList<Route>) {
val routes_recycler_view = rootView.findViewById(R.id.routers_recycler_view) as RecyclerView
val params=routes_recycler_view.layoutParams
params.height=330
routes_recycler_view.layoutParams=params
routes_recycler_view.layoutManager = LinearLayoutManager(rootView.context)
val adapter = RouterListAdapter(routes,routerRVClickListeners)
routes_recycler_view.adapter = adapter
view.findViewById<TextView>(R.id.date).text=SimpleDateFormat("dd.MM.yyyy HH:mm", Locale("ru","RU")).format(order.dateCreate)
view.findViewById<TextView>(R.id.name).text=order.name
view.findViewById<TextView>(R.id.adress).text=order.address
view.findViewById<TextView>(R.id.fio).text=order.contactFio
if (order.typeTransportation.isNullOrEmpty()) {
view.findViewById<TextView>(R.id.type_transportation).text="Нет данных"
} else {
view.findViewById<TextView>(R.id.type_transportation).text=order.typeTransportation
}
}
fun getVehicleType(transport: Transport, knownVehicleTypes:HashSet<String>):String? {
val type=transport.line.vehicleTypes
Timber.d("transport=${transport.line.name}_${transport.line.vehicleTypes}")
type.forEach{
if (knownVehicleTypes.contains(it)) {
return it
}
val btnPhone=view.findViewById<Button>(R.id.btnPhone)
if (order.phone.isNullOrEmpty()) {
btnPhone.text=btnPhone.context.getString(R.string.no_contact)
btnPhone.isEnabled=false
btnPhone.setTextColor(R.color.enabledText)
} else {
btnPhone.text=order.phone
}
return null
}
private val drivingRouteListener=object:DrivingSession.DrivingRouteListener {
override fun onDrivingRoutesError(error: Error) {
var errorMessage = getString(R.string.unknown_error_message)
if (error is RemoteError) {
errorMessage = getString(R.string.remote_error_message)
} else if (error is NetworkError) {
errorMessage = getString(R.string.network_error_message)
}
val btnRoute=view.findViewById<Button>(R.id.btnRoute)
//btnRoute.text="Маршрут 3.2 км"
toaster.showToast(errorMessage)
}
override fun onDrivingRoutes(routes: MutableList<DrivingRoute>) {
if (routes.isNotEmpty()) {
routes.forEach {
Timber.d("saveRoute")
val polylineMapObject=parentFragment.mapView.map.mapObjects.addPolyline(it.geometry)
parentFragment.lastCarRouter.add(polylineMapObject) // Сохраним маршрут, чтоб потом можно было его удалить
}
val distance=otherUtil.getDistance(userLocationNative.userLocation, order)
btnRoute.text=requireContext().getString(R.string.distance, distance.toString())//"Маршрут 3.2 км"
Timber.d("lastCarRouter?.size=${parentFragment.lastCarRouter.size}")
btnPhone.setOnClickListener { _ ->
val intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:${order.phone}"))
if (intent.resolveActivity(btnPhone.context.packageManager) != null) {
ContextCompat.startActivity(btnPhone.context, intent, null)
}
}
}
override fun setupDialog(dialog: Dialog, style: Int) {
AndroidSupportInjection.inject(this)
super.setupDialog(dialog, style)
btnRoute.setOnClickListener { _ ->
Timber.d("btnRoute.setOnClickListener")
Timber.d("MapBottomSheet_setupDialog")
val view=
LayoutInflater.from(context).inflate(R.layout.map_bottom_sheet,null)
this.rootView=view
dialog.setContentView(view)
val btnCar = view.findViewById(R.id.btnCar) as Button
btnCar.setOnClickListener(this)
//Включаем фрагмент со списком Маршрутов для конкретной заявки
parentFragment.showRouteDialog(order)
hideBottomSheet()
val btnBus = view.findViewById(R.id.btnBus) as Button
btnBus.setOnClickListener(this)
}
mbsPresenter.attachView(this)
// Заполним текстовые поля
val tvNumber=rootView.findViewById<TextView>(R.id.symbolNumber)
tvNumber?.text=order.number
val tvName=rootView.findViewById<TextView>(R.id.symbolName)
tvName?.text=order.name
//Сохраним маршрут с точками
requestPoints.add(
RequestPoint(
Point(order.lat,order.lon),
RequestPointType.WAYPOINT,
null
)
)
requestPoints.add(
RequestPoint(
Point(userLocation.latitude,userLocation.longitude),
RequestPointType.WAYPOINT,
null
)
)
}
override fun onDestroy() {
......@@ -238,34 +121,8 @@ class MapBottomSheet(val order: Orders, private val userLocation: Point, val par
mbsPresenter.onDestroy()
}
override fun onClick(v: View?) {
if (v != null) {
//Очистим предыдущий маршрут
if (parentFragment.lastCarRouter.isNotEmpty()) {
parentFragment.removeRouter(parentFragment.lastCarRouter)
}
when (v.id) {
R.id.btnCar -> {
carRouter=parentFragment.directions.createDrivingRouter()
val options = DrivingOptions()
drivingSession = carRouter.requestRoutes(requestPoints, options, drivingRouteListener)
hideBottomSheet()
}
R.id.btnBus -> {
busRouter = parentFragment.transports.createMasstransitRouter()
val options = MasstransitOptions(ArrayList<String>(), ArrayList<String>(), TimeOptions())
busRouter.requestRoutes(requestPoints, options, routeListener)
}
}
}
}
fun hideBottomSheet() {
private fun hideBottomSheet() {
// Закроем BottomSheetDialog
val params =(rootView.parent as View).layoutParams as CoordinatorLayout.LayoutParams
val behavior = params.behavior
......@@ -274,5 +131,9 @@ class MapBottomSheet(val order: Orders, private val userLocation: Point, val par
}
}
override fun onClick(v: View?) {
}
}
\ No newline at end of file
......@@ -37,11 +37,11 @@ class SectionRouteAdapter(private val sections: MutableList<Section>): RecyclerV
Timber.d(sections[position].metadata.data.transports.toString())
if (sections[position].metadata.data.transports==null) {
Timber.d(sections[position].metadata.weight.walkingDistance.text)
holder.sectionIcon.setImageResource(R.drawable.ic_directions_walk_black_24dp)
holder.sectionIcon.setImageResource(R.drawable.foot_blue)
holder.sectionText.text = sections[position].metadata.weight.walkingDistance.text
holder.sectionText.movementMethod=ScrollingMovementMethod()
} else {
holder.sectionIcon.setImageResource(R.drawable.ic_directions_bus_black_24dp)
holder.sectionIcon.setImageResource(R.drawable.bus_blue)
var transportsName=""
Timber.d("transportSize=${sections[position].metadata.data.transports?.size}")
......
......@@ -3,9 +3,12 @@ package ru.bingosoft.teploInspector.ui.order
import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.Context.LOCATION_SERVICE
import android.content.Intent
import android.location.LocationManager
import android.os.Bundle
import android.view.*
import android.widget.Button
import android.widget.ProgressBar
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
......@@ -25,16 +28,14 @@ import ru.bingosoft.teploInspector.ui.login.LoginContractView
import ru.bingosoft.teploInspector.ui.login.LoginPresenter
import ru.bingosoft.teploInspector.ui.mainactivity.FragmentsContractActivity
import ru.bingosoft.teploInspector.ui.mainactivity.MainActivity
import ru.bingosoft.teploInspector.util.Const
import ru.bingosoft.teploInspector.util.SharedPrefSaver
import ru.bingosoft.teploInspector.util.Toaster
import ru.bingosoft.teploInspector.util.UserLocationService
import ru.bingosoft.teploInspector.ui.map.MapFragment
import ru.bingosoft.teploInspector.util.*
import timber.log.Timber
import java.util.*
import javax.inject.Inject
class OrderFragment : Fragment(), LoginContractView, OrderContractView, OrdersRVClickListeners {
class OrderFragment : Fragment(), LoginContractView, OrderContractView, OrdersRVClickListeners, View.OnClickListener {
@Inject
lateinit var loginPresenter: LoginPresenter
......@@ -48,21 +49,33 @@ class OrderFragment : Fragment(), LoginContractView, OrderContractView, OrdersRV
@Inject
lateinit var sharedPref: SharedPrefSaver
@Inject
lateinit var otherUtil: OtherUtil
@Inject
lateinit var userLocationNative: UserLocationNative
private lateinit var currentOrder: Orders
private lateinit var root: View
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
AndroidSupportInjection.inject(this)
Timber.d("OrderFragment.onCreateView")
root = inflater.inflate(R.layout.fragment_order, container, false)
(this.requireActivity() as AppCompatActivity).supportActionBar?.setTitle(R.string.menu_orders)
val btnList=root.findViewById<Button>(R.id.btnList)
btnList.setOnClickListener(this)
val btnMap=root.findViewById<Button>(R.id.btnMap)
btnMap.setOnClickListener(this)
// Авторизуемся всегда иначе данные не будут уходить на сервер
/*doAuthorization()
Timber.d("sharedPref.getLogin()=${sharedPref.getLogin()}")
......@@ -98,11 +111,11 @@ class OrderFragment : Fragment(), LoginContractView, OrderContractView, OrdersRV
private fun doAuthorization() {
Timber.d("doAuthorization")
// Получим логин и пароль из настроек
val sharedpref = this.activity?.getSharedPreferences(Const.SharedPrefConst.APP_PREFERENCES, Context.MODE_PRIVATE)
if (sharedpref!!.contains(Const.SharedPrefConst.LOGIN) && sharedpref.contains(Const.SharedPrefConst.PASSWORD)) {
val sharedPref = this.activity?.getSharedPreferences(Const.SharedPrefConst.APP_PREFERENCES, Context.MODE_PRIVATE)
if (sharedPref!!.contains(Const.SharedPrefConst.LOGIN) && sharedPref.contains(Const.SharedPrefConst.PASSWORD)) {
val login = sharedPref.getLogin()
val password = sharedPref.getPassword()
val login = this.sharedPref.getLogin()
val password = this.sharedPref.getPassword()
loginPresenter.attachView(this)
loginPresenter.authorization(login, password) // Проверим есть ли авторизация
......@@ -137,6 +150,16 @@ class OrderFragment : Fragment(), LoginContractView, OrderContractView, OrdersRV
}
}
override fun onCreate(savedInstanceState: Bundle?) {
AndroidSupportInjection.inject(this)
super.onCreate(savedInstanceState)
val locationManager=this.requireContext().getSystemService(LOCATION_SERVICE) as LocationManager
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000L, 10f, userLocationNative.locationListener)
}
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
inflater.inflate(R.menu.main, menu)
super.onCreateOptionsMenu(menu, inflater)
......@@ -268,9 +291,11 @@ class OrderFragment : Fragment(), LoginContractView, OrderContractView, OrdersRV
swipeRefreshLayout.isRefreshing = false
}
Timber.d("userLocation2342342=${userLocationNative.userLocation}")
val ordersRecyclerView = root.findViewById(R.id.orders_recycler_view) as RecyclerView
ordersRecyclerView.layoutManager = LinearLayoutManager(this.activity)
val adapter = OrderListAdapter(orders,this, this.requireContext())
val adapter = OrderListAdapter(orders,this, this, userLocationNative.userLocation)
ordersRecyclerView.adapter = adapter
}
......@@ -285,24 +310,6 @@ class OrderFragment : Fragment(), LoginContractView, OrderContractView, OrdersRV
currentOrder.checked=!currentOrder.checked
/*Для Заявок пока не нужно менять цвет при клике
if (currentOrder.checked) {
val cardView = v?.findViewById<CardView>(R.id.cv)
cardView?.setCardBackgroundColor(
ContextCompat.getColor(
v.context,
R.color.colorCardSelect
)
)
} else {
val cardView = v?.findViewById<CardView>(R.id.cv)
cardView?.setCardBackgroundColor(
ContextCompat.getColor(
v.context,
R.color.colorCardItem
)
)
}*/
(activity as MainActivity).currentOrder=this.currentOrder
......@@ -324,7 +331,36 @@ class OrderFragment : Fragment(), LoginContractView, OrderContractView, OrdersRV
(this.requireActivity() as FragmentsContractActivity).setChecupListOrder(currentOrder)
}
override fun onClick(v: View?) {
if (v != null) {
when (v.id) {
R.id.btnList -> {
v.isEnabled=false
(v.parent as View).findViewById<Button>(R.id.btnMap).isEnabled=true
}
R.id.btnMap -> {
v.isEnabled=false
(v.parent as View).findViewById<Button>(R.id.btnList).isEnabled=true
val fragmentMap= MapFragment()
//fragmentMap.arguments=bundle
val fragmentManager=this.requireActivity().supportFragmentManager
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment, fragmentMap, "")
.addToBackStack(null)
.commit()
fragmentManager.executePendingTransactions()
}
}
}
}
......
package ru.bingosoft.teploInspector.ui.order
import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.location.Location
import android.net.Uri
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.Button
import android.widget.TextView
import androidx.cardview.widget.CardView
import androidx.core.content.ContextCompat
......@@ -16,12 +17,15 @@ import androidx.recyclerview.widget.RecyclerView
import kotlinx.android.synthetic.main.item_cardview_order.view.*
import ru.bingosoft.teploInspector.R
import ru.bingosoft.teploInspector.db.Orders.Orders
import ru.bingosoft.teploInspector.ui.mainactivity.FragmentsContractActivity
import ru.bingosoft.teploInspector.ui.mainactivity.MainActivity
import ru.bingosoft.teploInspector.ui.map.MapFragment
import timber.log.Timber
import java.text.SimpleDateFormat
import java.util.*
class OrderListAdapter (val orders: List<Orders>, private val itemListener: OrdersRVClickListeners, private val ctx: Context) : RecyclerView.Adapter<OrderListAdapter.OrderViewHolder>() {
class OrderListAdapter (val orders: List<Orders>, private val itemListener: OrdersRVClickListeners, private val parentFragment: OrderFragment, private val userLocation: Location) : RecyclerView.Adapter<OrderListAdapter.OrderViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): OrderViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_cardview_order, parent, false)
......@@ -36,51 +40,89 @@ class OrderListAdapter (val orders: List<Orders>, private val itemListener: Orde
return orders[position]
}
@SuppressLint("ClickableViewAccessibility")
override fun onBindViewHolder(holder: OrderViewHolder, position: Int) {
holder.orderNumber.text = orders[position].number
holder.orderDate.text = SimpleDateFormat("dd.MM.yyyy", Locale("ru","RU")).format(orders[position].dateCreate)
if (orders[position].typeOrder.isNullOrEmpty()){
holder.orderType.text="Нет данных"
} else {
holder.orderType.text=orders[position].typeOrder
}
when (orders[position].state) {
"1" -> holder.orderState.text="В работе"
}
holder.orderDate.text = SimpleDateFormat("dd.MM.yyyy HH:mm", Locale("ru","RU")).format(orders[position].dateCreate)
holder.orderName.text = orders[position].name
holder.orderadress.text = orders[position].adress
holder.orderadress.text = orders[position].address
holder.fio.text = orders[position].contactFio
holder.phone.text = orders[position].phone
holder.phone.setOnClickListener { _ ->
Timber.d("fabButton.setOnClickListener ${orders[position].phone}")
val intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:${orders[position].phone}"))
if (intent.resolveActivity(ctx.packageManager) != null) {
startActivity(ctx,intent,null)
}
if (orders[position].typeTransportation.isNullOrEmpty()) {
holder.typeTransportation.text="Нет данных"
} else {
holder.typeTransportation.text=orders[position].typeTransportation
}
if (orders[position].state.equals("1")) {
holder.targetImage.setImageResource(R.drawable.ic_state_red)
if (orders[position].phone.isNullOrEmpty()) {
holder.btnPhone.text=parentFragment.requireContext().getString(R.string.no_contact)
holder.btnPhone.isEnabled=false
holder.btnPhone.setTextColor(R.color.enabledText)
} else {
holder.targetImage.setImageResource(R.drawable.ic_state_green)
holder.btnPhone.text=orders[position].phone
}
if (userLocation.latitude!=0.0 && userLocation.longitude!=0.0) {
val distance=parentFragment.otherUtil.getDistance(userLocation, orders[position])
holder.btnRoute.text=parentFragment.requireContext().getString(R.string.distance, distance.toString())//"Маршрут 3.2 км"
} else {
holder.btnRoute.text=parentFragment.requireContext().getString(R.string.route)
}
holder.listener=itemListener
/*holder.fabButton.setOnClickListener{
holder.btnPhone.setOnClickListener { _ ->
Timber.d("fabButton.setOnClickListener ${orders[position].phone}")
val intent = Intent(Intent.ACTION_DIAL, Uri.parse("tel:${orders[position].phone}"))
if (intent.resolveActivity(ctx.packageManager) != null) {
startActivity(ctx,intent,null)
if (intent.resolveActivity(parentFragment.requireContext().packageManager) != null) {
startActivity(parentFragment.requireContext(),intent,null)
}
}*/
}
holder.btnRoute.setOnClickListener { _ ->
Timber.d("btnRoute.setOnClickListener")
//Включаем фрагмент со списком Маршрутов для конкретной заявки
val bundle = Bundle()
bundle.putBoolean("isOrderFragment",true)
val fragmentMap= MapFragment()
fragmentMap.arguments=bundle
val fragmentManager=(parentFragment.requireContext() as MainActivity).supportFragmentManager
fragmentManager.beginTransaction()
.replace(R.id.nav_host_fragment, fragmentMap, "map_fragment_from_orders_tag")
.addToBackStack(null)
.commit()
fragmentManager.executePendingTransactions()
(parentFragment.requireContext() as FragmentsContractActivity).setOrder(orders[position])
}
holder.listener=itemListener
if (orders[position].checked) {
holder.cardView.setCardBackgroundColor(
ContextCompat.getColor(
ctx,
parentFragment.requireContext(),
R.color.colorCardSelect
))
} else {
holder.cardView.setCardBackgroundColor(
ContextCompat.getColor(
ctx,
parentFragment.requireContext(),
R.color.colorCardItem
))
}
......@@ -92,13 +134,15 @@ class OrderListAdapter (val orders: List<Orders>, private val itemListener: Orde
}
var orderNumber: TextView = itemView.number
var orderType: TextView = itemView.order_type
var orderState: TextView = itemView.order_state
var orderDate: TextView = itemView.date
var orderName: TextView = itemView.name
var orderadress: TextView = itemView.adress
var fio: TextView = itemView.fio
var phone: TextView = itemView.phone
var targetImage: ImageView = itemView.targetImage as ImageView
//var fabButton: FloatingActionButton = itemView.fab2 as FloatingActionButton
var typeTransportation: TextView = itemView.type_transportation
var btnPhone: Button=itemView.btnPhone
var btnRoute: Button=itemView.btnRoute
lateinit var listener: OrdersRVClickListeners
var cardView: CardView = itemView.cv
......
......@@ -23,6 +23,7 @@ class OrderPresenter @Inject constructor(
this.view=view
}
fun loadOrders() {
Timber.d("loadOrders")
disposable=db.ordersDao().getAll()
......@@ -56,7 +57,7 @@ class OrderPresenter @Inject constructor(
number="A-001",
name = "Обследование жилого здания",
guid = "05d9365f-f176-45a7-b2df-7bf939d0c1e6",
adress = "Нижний Новгород, Россия, 603146, Михайловская улица, 24",
address = "Нижний Новгород, Россия, 603146, Михайловская улица, 24",
contactFio = "Иванов Иван Иванович",
phone = "+79503795388",
state = "1",
......@@ -70,7 +71,7 @@ class OrderPresenter @Inject constructor(
number="A-002",
name = "Обследование нежилого здания",
guid = "c4d40211-1687-4485-9b4a-aea7b5353f2b",
adress = "Нижний Новгород, Россия, 603146, улица Ванеева, 147",
address = "Нижний Новгород, Россия, 603146, улица Ванеева, 147",
contactFio = "Петров Петр Петрович",
phone = "+79503795388",
state = "1",
......
package ru.bingosoft.teploInspector.ui.route_detail
import android.app.Dialog
import android.graphics.Color
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.FrameLayout
import android.widget.TextView
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.android.material.bottomsheet.BottomSheetBehavior
import com.google.android.material.bottomsheet.BottomSheetDialog
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
import com.yandex.mapkit.MapKitFactory
import com.yandex.mapkit.RequestPoint
import com.yandex.mapkit.RequestPointType
import com.yandex.mapkit.directions.Directions
import com.yandex.mapkit.directions.DirectionsFactory
import com.yandex.mapkit.directions.driving.DrivingOptions
import com.yandex.mapkit.directions.driving.DrivingRoute
import com.yandex.mapkit.directions.driving.DrivingRouter
import com.yandex.mapkit.directions.driving.DrivingSession
import com.yandex.mapkit.geometry.Point
import com.yandex.mapkit.geometry.Polyline
import com.yandex.mapkit.geometry.SubpolylineHelper
import com.yandex.mapkit.map.*
import com.yandex.mapkit.mapview.MapView
import com.yandex.mapkit.transport.Transport
import com.yandex.mapkit.transport.TransportFactory
import com.yandex.mapkit.transport.masstransit.*
import com.yandex.runtime.Error
import com.yandex.runtime.network.NetworkError
import com.yandex.runtime.network.RemoteError
import com.yandex.runtime.ui_view.ViewProvider
import dagger.android.support.AndroidSupportInjection
import ru.bingosoft.teploInspector.BuildConfig
import ru.bingosoft.teploInspector.R
import ru.bingosoft.teploInspector.db.Orders.Orders
import ru.bingosoft.teploInspector.models.Models
import ru.bingosoft.teploInspector.ui.mainactivity.MainActivity
import ru.bingosoft.teploInspector.ui.map.MapFragment
import ru.bingosoft.teploInspector.util.Toaster
import timber.log.Timber
import javax.inject.Inject
class RouteDetailFragment(val order: Orders, val parentFragment: MapFragment): BottomSheetDialogFragment(), View.OnClickListener {
@Inject
lateinit var toaster: Toaster
private lateinit var root: View
lateinit var mapView: MapView
private lateinit var carRouter: DrivingRouter
private lateinit var busRouter: MasstransitRouter
private var isPedestrianRouter: Boolean=false
//private val userLocation: Point=Point()
private val requestPoints: ArrayList<RequestPoint> = ArrayList()
var lastLocation: com.yandex.mapkit.location.Location?=null
lateinit var foundingRoutes: MutableList<Route>
private lateinit var pedestrianRouter: PedestrianRouter
private var drivingSession: DrivingSession? = null
lateinit var directions: Directions
lateinit var transports: Transport
override fun onCreate(savedInstanceState: Bundle?) {
AndroidSupportInjection.inject(this)
super.onCreate(savedInstanceState)
MapKitFactory.setApiKey(BuildConfig.yandex_mapkit_api)
MapKitFactory.setLocale("ru_RU")
MapKitFactory.initialize(this.context)
DirectionsFactory.initialize(this.context)
TransportFactory.initialize(this.context)
directions= DirectionsFactory.getInstance()
transports= TransportFactory.getInstance()
}
override fun onClick(v: View?) {
if (v != null) {
//Очистим предыдущий маршрут
/*if (parentFragment.lastCarRouter.isNotEmpty()) {
parentFragment.removeRouter(parentFragment.lastCarRouter)
}*/
when (v.id) {
R.id.btnCar -> {
v.isEnabled=false
v.setBackgroundColor(ContextCompat.getColor(this.context!!, R.color.colorCardItem))
val btnFoot=(v.parent as View).findViewById<Button>(R.id.btnFoot)
btnFoot.setBackgroundColor(ContextCompat.getColor(this.context!!, R.color.routeButtonPanel))
btnFoot.isEnabled=true
val btnBus=(v.parent as View).findViewById<Button>(R.id.btnBus)
btnBus.setBackgroundColor(ContextCompat.getColor(this.context!!, R.color.routeButtonPanel))
btnBus.isEnabled=true
carRouter=directions.createDrivingRouter()
drivingSession = carRouter.requestRoutes(requestPoints, DrivingOptions(), drivingRouteListener)
hideBottomSheet()
}
R.id.btnBus -> {
Timber.d("bus_clicked")
(v as Button).isEnabled=false
v.setBackgroundColor(ContextCompat.getColor(this.context!!, R.color.colorCardItem))
val btnCar=(v.parent as View).findViewById<Button>(R.id.btnCar)
btnCar.setBackgroundColor(ContextCompat.getColor(this.context!!, R.color.routeButtonPanel))
btnCar.isEnabled=true
val btnFoot=(v.parent as View).findViewById<Button>(R.id.btnFoot)
btnFoot.setBackgroundColor(ContextCompat.getColor(this.context!!, R.color.routeButtonPanel))
btnFoot.isEnabled=true
busRouter = TransportFactory.getInstance().createMasstransitRouter()
Timber.d("busRouter=$busRouter")
Timber.d("requestPoints=${requestPoints[0].point.latitude} ${requestPoints[1].point.latitude}")
val options = MasstransitOptions(ArrayList<String>(), ArrayList<String>(), TimeOptions())
busRouter.requestRoutes(requestPoints, options, routeListener)
isPedestrianRouter=false
}
R.id.btnFoot -> {
(v as Button).isEnabled=false
v.setBackgroundColor(ContextCompat.getColor(this.context!!, R.color.colorCardItem))
val btnBus=(v.parent as View).findViewById<Button>(R.id.btnBus)
btnBus.setBackgroundColor(ContextCompat.getColor(this.context!!, R.color.routeButtonPanel))
btnBus.isEnabled=true
val btnCar=(v.parent as View).findViewById<Button>(R.id.btnCar)
btnCar.setBackgroundColor(ContextCompat.getColor(this.context!!, R.color.routeButtonPanel))
btnCar.isEnabled=true
pedestrianRouter=transports.createPedestrianRouter()
pedestrianRouter.requestRoutes(requestPoints,TimeOptions(),routeListener)
isPedestrianRouter=true
}
}
}
}
//https://github.com/yandex/mapkit-android-demo/blob/master/src/main/java/com/yandex/mapkitdemo/MasstransitRoutingActivity.java
private val routeListener=object: Session.RouteListener{
override fun onMasstransitRoutesError(error: Error) {
Timber.d(error.toString())
var errorMessage = getString(R.string.unknown_error_message)
if (error is RemoteError) {
errorMessage = getString(R.string.remote_error_message)
} else if (error is NetworkError) {
errorMessage = getString(R.string.network_error_message)
}
toaster.showToast(errorMessage)
}
override fun onMasstransitRoutes(routes: MutableList<Route>) {
Timber.d("onMasstransitRoutes $routes")
showRoutersList(routes)
if (routes.isNotEmpty()) {
foundingRoutes=routes
}
/*if (routes.isNotEmpty()) {
val sections= routes[0].sections
Timber.d("sections=${sections.size}")
sections.forEach{
Timber.d("section=${it.metadata.data.transports?.get(0)?.line?.name}")
drawSection(
it.metadata.data,
SubpolylineHelper.subpolyline(
routes[0].geometry, it.geometry
))
}
}*/
}
fun showRoutersList(routes: MutableList<Route>) {
Timber.d("showRoutersList=${routes.size}")
val routesRecyclerView = root.findViewById(R.id.routers_recycler_view) as RecyclerView
/*val params=routesRecyclerView.layoutParams
params.height=330
routesRecyclerView.layoutParams=params*/
routesRecyclerView.layoutManager = LinearLayoutManager(root.context)
val adapter = RouterListAdapter(routes,routerRVClickListeners, isPedestrianRouter)
routesRecyclerView.adapter = adapter
}
}
private val drivingRouteListener=object: DrivingSession.DrivingRouteListener {
override fun onDrivingRoutesError(error: Error) {
var errorMessage = getString(R.string.unknown_error_message)
if (error is RemoteError) {
errorMessage = getString(R.string.remote_error_message)
} else if (error is NetworkError) {
errorMessage = getString(R.string.network_error_message)
}
toaster.showToast(errorMessage)
}
override fun onDrivingRoutes(routes: MutableList<DrivingRoute>) {
if (routes.isNotEmpty()) {
routes.forEach {
Timber.d("saveRoute")
val polylineMapObject=parentFragment.mapView.map.mapObjects.addPolyline(it.geometry)
parentFragment.lastCarRouter.add(polylineMapObject) // Сохраним маршрут, чтоб потом можно было его удалить
}
}
}
}
private val routerRVClickListeners=object: RouterRVClickListeners {
override fun routerRVListClicked(v: View?, position: Int) {
Timber.d("routerRVListClicked")
// Строим маршрут
val route=foundingRoutes[position]
val sections= route.sections
Timber.d("sections=${sections.size}")
sections.forEach{
Timber.d("section=${it.metadata.data.transports?.get(0)?.line?.name}")
drawSection(
it.metadata.data,
SubpolylineHelper.subpolyline(
route.geometry, it.geometry
))
}
hideBottomSheet()
parentFragment.map.mapObjects.traverse(visitor)
}
}
val visitor=object: MapObjectVisitor {
override fun onPolygonVisited(p0: PolygonMapObject) {
//TODO("Not yet implemented")
}
override fun onCircleVisited(p0: CircleMapObject) {
//TODO("Not yet implemented")
}
override fun onPolylineVisited(p0: PolylineMapObject) {
//TODO("Not yet implemented")
}
override fun onColoredPolylineVisited(p0: ColoredPolylineMapObject) {
//TODO("Not yet implemented")
}
override fun onPlacemarkVisited(p0: PlacemarkMapObject) {
val o=(p0.userData as Models.CustomMarker).order
val tvMarker=(p0.userData as Models.CustomMarker).markerView
if (o==order) {
if (parentFragment.prevMapObjectMarker!=null) {
// выключим предыдущий маркер
val prevTvMarker=(parentFragment.prevMapObjectMarker!!.userData as Models.CustomMarker).markerView
prevTvMarker.isEnabled=!prevTvMarker.isEnabled
(parentFragment.prevMapObjectMarker as PlacemarkMapObject).setView(ViewProvider(prevTvMarker))
}
tvMarker.isEnabled=!tvMarker.isEnabled
p0.setView(ViewProvider(tvMarker))
parentFragment.prevMapObjectMarker=p0
}
}
override fun onCollectionVisitEnd(p0: MapObjectCollection) {
//TODO("Not yet implemented")
}
override fun onCollectionVisitStart(p0: MapObjectCollection): Boolean {
//TODO("Not yet implemented")
return true
}
}
fun drawSection(data: SectionMetadata.SectionData, geometry: Polyline) {
val polylineMapObject = parentFragment.mapView.map.mapObjects.addPolyline(geometry)
parentFragment.lastCarRouter.add(polylineMapObject) // Сохраним маршрут, чтоб потом можно было его удалить
if (data.transports != null) {
val transports=data.transports
transports!!.forEach {
if (it.line.style != null) {
polylineMapObject.strokeColor = it.line.style!!.color!!
return
}
}
val knownVehicleTypes = HashSet<String>()
knownVehicleTypes.add("bus")
knownVehicleTypes.add("tramway")
transports.forEach {
val sectionVehicleType = getVehicleType(it, knownVehicleTypes)
if (sectionVehicleType.equals("bus")) {
polylineMapObject.strokeColor = Color.GREEN
return
} else if (sectionVehicleType.equals("tramway")) {
polylineMapObject.strokeColor = Color.RED
return
}
}
polylineMapObject.strokeColor = Color.BLUE
} else {
polylineMapObject.strokeColor = Color.BLACK
}
}
private fun getVehicleType(transport: com.yandex.mapkit.transport.masstransit.Transport, knownVehicleTypes:HashSet<String>):String? {
val type=transport.line.vehicleTypes
Timber.d("transport=${transport.line.name}_${transport.line.vehicleTypes}")
type.forEach{
if (knownVehicleTypes.contains(it)) {
return it
}
}
return null
}
override fun onStart() {
super.onStart()
//mapView.onStart()
MapKitFactory.getInstance().onStart()
}
override fun setupDialog(dialog: Dialog, style: Int) {
super.setupDialog(dialog, style)
Timber.d("MapBottomSheet_setupDialog")
val view=
LayoutInflater.from(context).inflate(R.layout.fragment_route_detail,null)
this.root=view
dialog.setContentView(view)
//(this.requireActivity() as AppCompatActivity).supportActionBar?.setTitle("")
val btnCar = root.findViewById(R.id.btnCar) as Button
btnCar.setOnClickListener(this)
val btnBus = root.findViewById(R.id.btnBus) as Button
btnBus.setOnClickListener(this)
val btnFoot = root.findViewById(R.id.btnFoot) as Button
btnFoot.setOnClickListener(this)
root.findViewById<TextView>(R.id.symbolNumber).text=order.number
root.findViewById<TextView>(R.id.address).text=order.address
//Сохраним маршрут с точками
requestPoints.add(
RequestPoint(
Point(order.lat,order.lon),
RequestPointType.WAYPOINT,
null
)
)
val userLocation=(this.activity as MainActivity).userLocationReceiver.lastKnownLocation
Timber.d("userLocation=${userLocation.latitude} =${userLocation.longitude}")
requestPoints.add(
RequestPoint(
Point(userLocation.latitude, userLocation.longitude),
RequestPointType.WAYPOINT,
null
)
)
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
val dialog= super.onCreateDialog(savedInstanceState)
dialog.setOnShowListener { bottomDialog ->
val bottomSheetDialog = bottomDialog as BottomSheetDialog
//setupFullHeight(bottomSheetDialog)
}
return dialog
}
private fun setupFullHeight(bottomSheetDialog: BottomSheetDialog) {
val bottomSheet: FrameLayout? =
bottomSheetDialog.findViewById(R.id.design_bottom_sheet) as FrameLayout?
val behavior: BottomSheetBehavior<*> =
BottomSheetBehavior.from(bottomSheet!!)
val layoutParams: ViewGroup.LayoutParams = bottomSheet.layoutParams
layoutParams.height = getWindowHeight()
bottomSheet.layoutParams = layoutParams
behavior.state = BottomSheetBehavior.STATE_EXPANDED
}
private fun getWindowHeight(): Int {
val displayMetrics = DisplayMetrics()
this.activity?.windowManager?.defaultDisplay?.getMetrics(displayMetrics)
return displayMetrics.heightPixels
}
override fun onStop() {
super.onStop()
//mapView.onStop()
MapKitFactory.getInstance().onStop()
}
fun hideBottomSheet() {
// Закроем BottomSheetDialog
val params =(root.parent as View).layoutParams as CoordinatorLayout.LayoutParams
val behavior = params.behavior
if (behavior!=null && behavior is BottomSheetBehavior) {
behavior.state= BottomSheetBehavior.STATE_HIDDEN
}
}
}
\ No newline at end of file
package ru.bingosoft.teploInspector.ui.map_bottom
package ru.bingosoft.teploInspector.ui.route_detail
import android.content.Context
import android.view.LayoutInflater
......@@ -14,8 +14,10 @@ import com.yandex.mapkit.transport.masstransit.Route
import com.yandex.mapkit.transport.masstransit.Section
import kotlinx.android.synthetic.main.item_cardview_map_bottom_sheet.view.*
import ru.bingosoft.teploInspector.R
import ru.bingosoft.teploInspector.ui.map_bottom.SectionRouteAdapter
import timber.log.Timber
class RouterListAdapter(private val routes: MutableList<Route>, private val itemListener: RouterRVClickListeners): RecyclerView.Adapter<RouterListAdapter.RouterViewHolder>() {
class RouterListAdapter(private val routes: MutableList<Route>, private val itemListener: RouterRVClickListeners, private val isPedestrianRouter: Boolean): RecyclerView.Adapter<RouterListAdapter.RouterViewHolder>() {
private lateinit var ctx: Context
......@@ -25,7 +27,9 @@ class RouterListAdapter(private val routes: MutableList<Route>, private val item
): RouterViewHolder {
val view = LayoutInflater.from(parent.context).inflate(R.layout.item_cardview_map_bottom_sheet, parent, false)
ctx=parent.context
return RouterViewHolder(view)
return RouterViewHolder(
view
)
}
override fun getItemCount(): Int {
......@@ -35,9 +39,17 @@ class RouterListAdapter(private val routes: MutableList<Route>, private val item
override fun onBindViewHolder(holder: RouterViewHolder, position: Int) {
holder.routerName.text = ctx.getString(R.string.routeName,(position+1).toString())
holder.time.text = routes[position].metadata.weight.time.text
holder.transfersCount.text =ctx.getString(R.string.transfersCount,routes[position].metadata.weight.transfersCount.toString())
if (isPedestrianRouter==true) {
Timber.d("isPedestrianRouter==true")
holder.transfersCount.text =""
} else {
holder.transfersCount.text =ctx.getString(R.string.transfersCount,routes[position].metadata.weight.transfersCount.toString())
}
holder.walkingDistance.text = ctx.getString(R.string.walkingDistance, routes[position].metadata.weight.walkingDistance.text)
// Уберем нулевые секции
val sectionList= mutableListOf<Section>()
routes[position].sections.forEach {
......@@ -52,7 +64,10 @@ class RouterListAdapter(private val routes: MutableList<Route>, private val item
flexboxLayoutManager.flexWrap=FlexWrap.WRAP
flexboxLayoutManager.alignItems=AlignItems.FLEX_START
holder.sectionsRoute.layoutManager=flexboxLayoutManager
val adapter = SectionRouteAdapter(sectionList)
val adapter =
SectionRouteAdapter(
sectionList
)
holder.sectionsRoute.adapter = adapter
......
package ru.bingosoft.teploInspector.ui.map_bottom
package ru.bingosoft.teploInspector.ui.route_detail
import android.view.View
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment