Merge branch 'dev_robotaxi-d_231031_6.2.0_routing_verify' into dev_robotaxi-d_231129_6.2.2_routing_verify

# Conflicts:
#	OCH/taxi/unmanned-driver/src/main/java/com/mogo/och/taxi/ui/base/BaseTaxiTabFragment.kt
#	gradle.properties
This commit is contained in:
aibingbing
2023-11-29 16:02:49 +08:00
71 changed files with 3634 additions and 52 deletions

View File

@@ -1,5 +1,9 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mogo.och.taxi">
/
<application>
<activity android:name=".ui.routing.TaxiRoutingChooseLineActivity"
android:theme="@style/RoutingChooseLineDialogStyle"
android:launchMode="singleTask"
android:screenOrientation="landscape" />
</application>
</manifest>

View File

@@ -0,0 +1,61 @@
package com.mogo.och.taxi.bean
import com.mogo.eagle.core.data.BaseData
data class GrayLineBean(
var lineId: Long?, //线路id
var lineName: String?, //线路名称
var contrailId: Long?, //轨迹id
var carVerificationCount: Int?, //本次今日已验证次数
var lineSuccessCount: Int?, //线路累计反馈可用次数
var lineFailCount: Int?, //线路累计反馈不可用次数
var isChoosed: Boolean = false, //当前是否选中
var startSite: RoutingSite?,
var endSite: RoutingSite?
)
data class RoutingSite(
var siteId: Long,
var siteName: String,
var gcjLat: Double,
var gcjLon: Double,
var wgs84Lon: Double,
var wgs84Lat: Double
)
data class ContrailBean(
var lineId: Long = -1L,
var lineName: String = "",
var contrailId: Long = -1L,
var csvFileUrl: String = "",
var csvFileMd5: String = "",
var txtFileUrl: String = "",
var txtFileMd5: String = "",
var contrailSaveTime: Long = -1L,
var csvFileUrlDPQP: String = "",
var csvFileMd5DPQP: String = "",
var txtFileUrlDPQP: String = "",
var txtFileMd5DPQP: String = "",
var contrailSaveTimeDPQP: Long = -1L,
var version: Long = -1L
)
data class QueryGrayContrailListRsp(var data: MutableList<GrayLineBean>?) : BaseData()
data class StartGrayContrailTaskReq(var sn: String, var contrailId: Long)
data class StartGrayContrailTaskRsp(var data: Long?) : BaseData()
data class QueryRoutingContrailByIdRsp(var data: ContrailBean?) : BaseData()
data class SubmitGrayLineIssueLocationReq(var grayId: Long, var gcjLon: Double, var gcjLat: Double)
data class EndGrayContrailTaskReq(var grayId: Long, var feedback: Int) //feedback 1:成功 2:失败
data class StartGrayAndQueryContrailRsp(
var taskId: Long?,
var contrail: ContrailBean?,
var grayLineBean: GrayLineBean
) : BaseData()
enum class EndGrayTaskFeedbackType(var type: Int) {
USABLE_YES(1),
USABLE_NO(2)
}

View File

@@ -0,0 +1,15 @@
package com.mogo.och.taxi.callback
import com.mogo.och.taxi.bean.GrayLineBean
import com.mogo.och.taxi.bean.StartGrayAndQueryContrailRsp
interface ITaxiRoutingCallback {
fun onQueryRoutingGrayLineListSuccess(data: MutableList<GrayLineBean>)
fun onQueryRoutingGrayLineListFailed(errorStr: String)
fun onStartGrayTaskAndQueryContrailSuccess(data: StartGrayAndQueryContrailRsp)
fun onStartGrayTaskAndQueryContrailFailed(errorStr: String)
fun onSubmitGrayLineIssueLocationSuccess()
fun onSubmitGrayLineIssueLocationFailed(errorStr: String)
fun onSubmitEndTaskSuccess()
fun onSubmitEndTaskFailed(errorStr: String)
}

View File

@@ -13,4 +13,8 @@ public interface TaxiDriverEventConst {
String EVENT_TYPE_SHOW_RED_POINT = "event_type_tab_fragment_show_red_point";
String EVENT_TYPE_TASK_WITH_ORDER_CHANGED = "event_type_tab_fragment_task_with_order_changed";
}
interface RoutingActivityEvent {
String EVENT_TYPE_GET_CHOSEN_LINE_TASK = "event_type_get_chosen_line_task";
}
}

View File

@@ -0,0 +1,75 @@
package com.mogo.och.taxi.network
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.BaseData
import com.mogo.och.taxi.bean.EndGrayContrailTaskReq
import com.mogo.och.taxi.bean.QueryGrayContrailListRsp
import com.mogo.och.taxi.bean.QueryRoutingContrailByIdRsp
import com.mogo.och.taxi.bean.StartGrayContrailTaskReq
import com.mogo.och.taxi.bean.StartGrayContrailTaskRsp
import com.mogo.och.taxi.bean.SubmitGrayLineIssueLocationReq
import io.reactivex.Observable
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Headers
import retrofit2.http.POST
import retrofit2.http.Query
interface TaxiRoutingServiceApi {
/**
* 查询灰度线路列表
*/
@Headers("Content-type:application/json;charset=UTF-8")
@GET("/och-taxi-cabin/api/business/v1/queryGrayContrailList")
fun queryRoutingGrayLineList(
@Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
@Header("ticket") ticket: String = MoGoAiCloudClientConfig.getInstance().token,
@Query("sn") sn: String?
): Observable<QueryGrayContrailListRsp>
/**
* 开始一个路线的灰度任务
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/och-taxi-cabin/api/business/v1/startGray")
fun startGrayTask(
@Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
@Header("ticket") ticket: String = MoGoAiCloudClientConfig.getInstance().token,
@Body data: StartGrayContrailTaskReq
): Observable<StartGrayContrailTaskRsp>
/**
* 根据id查询灰度轨迹详情
*/
@Headers("Content-type:application/json;charset=UTF-8")
@GET("/och-taxi-cabin/api/business/v1/gray/contrail")
fun queryRoutingContrailById(
@Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
@Header("ticket") ticket: String = MoGoAiCloudClientConfig.getInstance().token,
@Query("id") contrailId: Long
): Observable<QueryRoutingContrailByIdRsp>
/**
* 上报路线打点
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/och-taxi-cabin/api/business/v1/saveDotDetail")
fun submitGrayLineIssueLocation(
@Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
@Header("ticket") ticket: String = MoGoAiCloudClientConfig.getInstance().token,
@Body data: SubmitGrayLineIssueLocationReq
): Observable<BaseData>
/**
* 结束一个路线的灰度任务
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/och-taxi-cabin/api/business/v1/endGray")
fun endGrayTask(
@Header("appId") appId: String = MoGoAiCloudClientConfig.getInstance().serviceAppId,
@Header("ticket") ticket: String = MoGoAiCloudClientConfig.getInstance().token,
@Body data: EndGrayContrailTaskReq
): Observable<BaseData>
}

View File

@@ -0,0 +1,134 @@
package com.mogo.och.taxi.network
import android.content.Context
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.eagle.core.data.BaseData
import com.mogo.eagle.core.network.MoGoRetrofitFactory
import com.mogo.och.common.module.biz.constant.OchCommonConst
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
import com.mogo.och.common.module.biz.network.OchCommonSubscribeImpl
import com.mogo.och.common.module.biz.network.interceptor.transformTry
import com.mogo.och.taxi.bean.EndGrayContrailTaskReq
import com.mogo.och.taxi.bean.GrayLineBean
import com.mogo.och.taxi.bean.QueryGrayContrailListRsp
import com.mogo.och.taxi.bean.QueryRoutingContrailByIdRsp
import com.mogo.och.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.taxi.bean.StartGrayContrailTaskReq
import com.mogo.och.taxi.bean.StartGrayContrailTaskRsp
import com.mogo.och.taxi.bean.SubmitGrayLineIssueLocationReq
import io.reactivex.Observable
object TaxiRoutingServiceManager {
private var mRoutingServiceApi: TaxiRoutingServiceApi =
MoGoRetrofitFactory.getInstance(OchCommonConst.getBaseUrl()).create(
TaxiRoutingServiceApi::class.java
)
/**
* 查询灰度路线列表
*/
fun queryRoutingGrayLineList(
context: Context,
callback: OchCommonServiceCallback<QueryGrayContrailListRsp>
) {
mRoutingServiceApi.queryRoutingGrayLineList(
sn = MoGoAiCloudClientConfig.getInstance().sn
)
.transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryRoutingGrayLineList"))
}
/**
* 开始一个灰度任务
*/
fun startGrayTask(
context: Context,
data: StartGrayContrailTaskReq,
callback: OchCommonServiceCallback<StartGrayContrailTaskRsp>
) {
mRoutingServiceApi.startGrayTask(data = data).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "startGrayTask"))
}
/**
* 通过id查询轨迹详情
*/
fun queryRoutingContrailById(
context: Context,
contrailId: Long,
callback: OchCommonServiceCallback<QueryRoutingContrailByIdRsp>
) {
mRoutingServiceApi.queryRoutingContrailById(contrailId = contrailId).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "queryRoutingContrailById"))
}
/**
* 上报线路打点
*/
fun submitGrayLineIssueLocation(
context: Context,
data: SubmitGrayLineIssueLocationReq,
callback: OchCommonServiceCallback<BaseData>
) {
mRoutingServiceApi.submitGrayLineIssueLocation(data = data).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "submitGrayLineIssueLocation"))
}
/**
* 结束一个灰度任务
*/
fun endGrayTask(
context: Context,
data: EndGrayContrailTaskReq,
callback: OchCommonServiceCallback<BaseData>
) {
mRoutingServiceApi.endGrayTask(data = data).transformTry()
.subscribe(OchCommonSubscribeImpl(context, callback, "endGrayTask"))
}
fun startGrayTaskAndQueryRoutingContrail(
context: Context,
sn: String,
contrailId: Long,
grayLineBean: GrayLineBean,
callback: OchCommonServiceCallback<StartGrayAndQueryContrailRsp>
) {
val data = StartGrayContrailTaskReq(sn = sn, contrailId = contrailId)
var taskId: Long
mRoutingServiceApi.startGrayTask(data = data)
.flatMap { startGrayRsp ->
if (startGrayRsp.data == null) {
taskId = -1L
val result = StartGrayAndQueryContrailRsp(
taskId = taskId,
contrail = null,
grayLineBean = grayLineBean
)
result.code = startGrayRsp.code
result.msg = startGrayRsp.msg
return@flatMap Observable.just(result)
}
taskId = startGrayRsp.data!!
return@flatMap mRoutingServiceApi.queryRoutingContrailById(contrailId = contrailId)
.map { queryRoutingContrailRsp ->
val result = StartGrayAndQueryContrailRsp(
taskId = taskId,
contrail = queryRoutingContrailRsp.data,
grayLineBean = grayLineBean
)
result.code = queryRoutingContrailRsp.code
result.msg = queryRoutingContrailRsp.msg
result
}
}
.transformTry()
.subscribe(
OchCommonSubscribeImpl(
context,
callback,
"startGrayTaskAndQueryRoutingContrail"
)
)
}
}

View File

@@ -11,6 +11,7 @@ import android.view.animation.LinearInterpolator
import androidx.fragment.app.FragmentTransaction
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.commons.mvp.IView
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.mvp.Presenter
@@ -26,6 +27,7 @@ import com.mogo.eagle.core.function.hmi.ui.widget.ParallelDriveView
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.map.listener.IMogoMapListener
import com.mogo.map.uicontroller.VisualAngleMode
@@ -197,6 +199,10 @@ abstract class BaseTaxiTabFragment<V : IView, P : Presenter<V>> : MvpFragment<V,
module_mogo_och_operation_status.setOnClickListener(object : OnPreventFastClickListener() {
override fun onClickImpl(v: View?) {
if (MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingVerifyMode) {
ToastUtils.showLong("请先切换到Taxi无人化流程模式后使用")
return
}
onChangeOperationStatus()
}
})

View File

@@ -8,11 +8,13 @@ import android.view.ViewGroup
import androidx.fragment.app.FragmentTransaction
import com.alibaba.android.arouter.launcher.ARouter
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.commons.module.status.StatusDescriptor
import com.mogo.eagle.core.data.temp.EventLogout
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.e
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.biz.constant.OchCommonConst
import com.mogo.och.common.module.biz.provider.LoginService
import com.mogo.och.common.module.utils.FlowBus
@@ -21,6 +23,7 @@ import com.mogo.och.taxi.constant.TaxiDriverEventConst
import com.mogo.och.taxi.constant.TaxiOrderStatusEnum
import com.mogo.och.taxi.network.TaxiDriverLoginImpl
import com.mogo.och.taxi.ui.operational.TaxiOperationalDialogFragment
import com.mogo.och.taxi.ui.routing.TaxiRoutingFragment
import com.mogo.och.taxi.ui.task.TaxiTaskModel
import com.mogo.och.taxi.ui.task.TaxiTaskTabFragment
import com.mogo.och.taxi.utils.TPRouteDataTestUtils
@@ -45,6 +48,7 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
private var taskTabFragment: WeakReference<TaxiTaskTabFragment>? = null
private var personalDialogFragment: WeakReference<TaxiOperationalDialogFragment>? = null
private var routingVerifyFragment: WeakReference<TaxiRoutingFragment>? = null
private var loginService: LoginService? = null
@Subscribe(threadMode = ThreadMode.MAIN)
@@ -151,15 +155,56 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
}
private fun initFragment() {
taskTabFragment = WeakReference(TaxiTaskTabFragment.newInstance())
showTaskFragment()
MogoStatusManager.getInstance()
.registerStatusChangedListener(
TAG, StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE
) { descriptor, isTrue ->
if (StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE == descriptor) {
UiThreadHandler.post {
if (isTrue) {
showRoutingFragment()
} else {
showTaskFragment()
}
updateOperationBtnStatusOnModeChange(isTrue)
}
}
}
}
private fun showTaskFragment() {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
//默认显示OCHTaxiServerOrdersFragment
taskTabFragment?.get()?.let {
transaction.add(R.id.fragment_container, it).show(
it
)
if (routingVerifyFragment?.get()?.isVisible == true) {
routingVerifyFragment?.get()?.also {
transaction.remove(it)
routingVerifyFragment = null
}
}
if (taskTabFragment?.get() == null) {
taskTabFragment = WeakReference(TaxiTaskTabFragment.newInstance())
}
taskTabFragment?.get()?.also {
transaction.replace(R.id.fragment_container, it).show(it)
transaction.commitAllowingStateLoss()
}
}
private fun showRoutingFragment() {
val transaction: FragmentTransaction = childFragmentManager.beginTransaction()
if (taskTabFragment?.get()?.isVisible == true) {
taskTabFragment?.get()?.also {
transaction.remove(it)
taskTabFragment = null
}
}
if (routingVerifyFragment?.get() == null) {
routingVerifyFragment = WeakReference(TaxiRoutingFragment.newInstance())
}
routingVerifyFragment?.get()?.also {
transaction.replace(R.id.fragment_container, it).show(it)
transaction.commitAllowingStateLoss()
}
transaction.commitAllowingStateLoss()
}
override fun createPresenter(): TaxiPresenter {
@@ -220,6 +265,31 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
null
)
}
updateOperationBtnStatusOnModeChange(MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingVerifyMode)
MogoStatusManager.getInstance().setTaxiUnmanedDriverTakingOrders(TAG, inOperation)
}
private fun updateOperationBtnStatusOnModeChange(isRoutingVerifyMode: Boolean) {
if (MogoStatusManager.getInstance().isTaxiUnmanedDriverTakingOrders) {
return
}
module_mogo_och_operation_status.isEnabled = !isRoutingVerifyMode
val isBtnEnable = module_mogo_och_operation_status.isEnabled
if (isBtnEnable) {
module_mogo_och_operation_status.setCompoundDrawablesWithIntrinsicBounds(
resources.getDrawable(R.drawable.shape_size_operation_out),
null,
null,
null
)
} else {
module_mogo_och_operation_status.setCompoundDrawablesWithIntrinsicBounds(
resources.getDrawable(R.drawable.shape_size_operation_out_disable),
null,
null,
null
)
}
}
override fun onMapLoaded() {}
@@ -230,8 +300,12 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
fun onNaviToEnd(isAmap: Boolean, isShow: Boolean) {
if (isAmap) {
if (null == taskTabFragment || taskTabFragment!!.get() == null) return
taskTabFragment!!.get()!!.onNaviToEndStationByAMap(isShow)
if (MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingVerifyMode) {
showAmapNaviToStationFragment(isShow)
} else {
if (null == taskTabFragment || taskTabFragment!!.get() == null) return
taskTabFragment!!.get()!!.onNaviToEndStationByAMap(isShow)
}
} else if (isShow) { //使用routing数据
showRoutingToStationFragment(true)
} else {
@@ -262,8 +336,8 @@ class TaxiFragment : BaseTaxiTabFragment<TaxiFragment, TaxiPresenter>(),
if (it.order != null && it.order!!.orderStatus >= TaxiOrderStatusEnum.ArriveAtStart.code)
it.order!!.orderLine
else
it.lineId
,true)
it.lineId, true
)
}
}

View File

@@ -6,6 +6,7 @@ import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.commons.module.status.MogoStatusManager;
import com.mogo.commons.mvp.Presenter;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
@@ -20,6 +21,7 @@ import com.mogo.och.taxi.callback.ITaxiOrderStatusCallback;
import com.mogo.och.taxi.constant.TaxiCarServingStatusManager;
import com.mogo.och.taxi.constant.TaxiDriverRoleEnum;
import com.mogo.och.taxi.constant.TaxiUnmannedConst;
import com.mogo.och.taxi.ui.routing.TaxiRoutingModel;
import com.mogo.och.taxi.ui.task.TaxiTaskModel;
/**
@@ -51,6 +53,8 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
TaxiTaskModel.INSTANCE.setADASStatusCallback(this);
TaxiTaskModel.INSTANCE.setControllerStatusCallback(this);
TaxiTaskModel.INSTANCE.setOrderStatusCallback(this);
TaxiRoutingModel.INSTANCE.setControllerStatusCallback(this);
TaxiRoutingModel.INSTANCE.setOrderStatusCallback(this);
}
private void releaseListeners() {
@@ -76,7 +80,11 @@ public class TaxiPresenter extends Presenter<TaxiFragment> implements ITaxiADASS
* 开启自动驾驶 自驾模式
*/
public void startAutoPilot() {
TaxiTaskModel.INSTANCE.startAutopilotByClick();
if (MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingVerifyMode()) {
TaxiRoutingModel.INSTANCE.startAutoPilotByClick();
} else {
TaxiTaskModel.INSTANCE.startAutopilotByClick();
}
}
// 登出

View File

@@ -16,10 +16,14 @@ import android.widget.TextView
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.localbroadcastmanager.content.LocalBroadcastManager
import com.mogo.commons.module.status.IMogoStatusChangedListener
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.commons.module.status.StatusDescriptor
import com.mogo.commons.utils.MogoAnalyticUtils
import com.mogo.eagle.core.function.main.MainMoGoApplication
import com.mogo.eagle.core.network.utils.GsonUtil
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.util.AppUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.taxi.R
@@ -30,6 +34,8 @@ import com.mogo.och.taxi.constant.TaskStatusEnum
import com.mogo.och.taxi.constant.TaskTypeEnum
import com.mogo.och.taxi.constant.TaxiOrderStatusEnum
import com.mogo.och.taxi.ui.task.TaxiTaskModel
import kotlinx.android.synthetic.main.taxi_debug_order.view.btnContainer
import kotlinx.android.synthetic.main.taxi_debug_order.view.currentBusinessModeTextView
import kotlinx.android.synthetic.main.taxi_debug_order.view.currentCarStatus
import kotlinx.android.synthetic.main.taxi_debug_order.view.currentDataTimestamps
import kotlinx.android.synthetic.main.taxi_debug_order.view.currentLineId
@@ -39,6 +45,7 @@ import kotlinx.android.synthetic.main.taxi_debug_order.view.currentOrderTrajecto
import kotlinx.android.synthetic.main.taxi_debug_order.view.currentStatus
import kotlinx.android.synthetic.main.taxi_debug_order.view.currentTaskType
import kotlinx.android.synthetic.main.taxi_debug_order.view.debugLogHistoryTextView
import kotlinx.android.synthetic.main.taxi_debug_order.view.debugLogTitleTextView
import kotlinx.android.synthetic.main.taxi_debug_order.view.orderEndSiteInfo
import kotlinx.android.synthetic.main.taxi_debug_order.view.orderNo
import kotlinx.android.synthetic.main.taxi_debug_order.view.orderPreLoadLines
@@ -46,13 +53,15 @@ import kotlinx.android.synthetic.main.taxi_debug_order.view.orderStartSiteInfo
import kotlinx.android.synthetic.main.taxi_debug_order.view.orderStatus
import kotlinx.android.synthetic.main.taxi_debug_order.view.taskEndSite
import kotlinx.android.synthetic.main.taxi_debug_order.view.taskStartSite
import kotlinx.android.synthetic.main.taxi_debug_order.view.unmanedTaskOrderContainer
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
public class DebugView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0, defStyleRes: Int = 0
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes), ITaxiTaskWithOrderCallback {
) : LinearLayout(context, attrs, defStyleAttr, defStyleRes), ITaxiTaskWithOrderCallback,
IMogoStatusChangedListener {
companion object {
const val TAG = "DebugView"
private const val ANALYTICS_EVENT_TYPE_DRIVER_UNMANNED_OPERATION_PROCESS_KEY_NODE_LOG =
@@ -104,7 +113,10 @@ public class DebugView @JvmOverloads constructor(
val map: MutableMap<String, Any> = HashMap()
map["level"] = level
map["msg"] = msg
MogoAnalyticUtils.track(ANALYTICS_EVENT_TYPE_DRIVER_UNMANNED_OPERATION_PROCESS_KEY_NODE_LOG, map)
MogoAnalyticUtils.track(
ANALYTICS_EVENT_TYPE_DRIVER_UNMANNED_OPERATION_PROCESS_KEY_NODE_LOG,
map
)
}
}
@@ -128,9 +140,11 @@ public class DebugView @JvmOverloads constructor(
init {
initBroadcastReceiver()
LayoutInflater.from(context).inflate(R.layout.taxi_debug_order, this, true)
debugLogHistoryTextView.setMovementMethod(ScrollingMovementMethod.getInstance())
debugLogHistoryTextView.movementMethod = ScrollingMovementMethod.getInstance()
visibility = GONE
logHistoryTextView = debugLogHistoryTextView
initView()
}
private fun initBroadcastReceiver() {
@@ -142,8 +156,7 @@ public class DebugView @JvmOverloads constructor(
fun toggleOrderDebugView() {
visibility = if (visibility == View.VISIBLE) View.GONE
else View.VISIBLE
val data = TaxiTaskModel.getCurrentTaskWithOrder()
initViewByData(data)
initView()
}
private fun initTaskWithOrderDataListener() {
@@ -154,17 +167,49 @@ public class DebugView @JvmOverloads constructor(
TaxiTaskModel.removeTaskWithOrderListener(TAG)
}
private fun initCurrentBusinessModeListener() {
MogoStatusManager.getInstance()
.registerStatusChangedListener(
TAG, StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE, this
)
}
private fun removeCurrentBusinessModeListener() {
MogoStatusManager.getInstance().unregisterStatusChangedListener(
TAG,
StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE,
this
)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
initTaskWithOrderDataListener()
initCurrentBusinessModeListener()
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
removeTaskWithOrderDataListener()
removeCurrentBusinessModeListener()
}
private fun initViewByData(data: QueryCurrentTaskRespBean.Result?) {
private fun initView() {
initCurrentBusinessMode()
initViewByTaskData(TaxiTaskModel.getCurrentTaskWithOrder())
initDebugLogTextViewTitle()
}
private fun initCurrentBusinessMode() {
val isRoutingVerifyMode =
MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingVerifyMode
currentBusinessModeTextView.text =
"当前业务模式:${if (isRoutingVerifyMode) "自主算路验证模式" else "无人化运营流程模式"}"
}
private fun initViewByTaskData(data: QueryCurrentTaskRespBean.Result?) {
//release包下隐藏Mock按钮避免司机误操作
btnContainer.visibility = if (AppUtils.isAppDebug()) View.INVISIBLE else View.VISIBLE
val curContrail = TaxiTaskModel.getCurrentTaskTrajectory()
currentDataTimestamps.text = "【当前数据返回时间】${currentDateTimeString()}"
currentCarStatus.text =
@@ -194,9 +239,16 @@ public class DebugView @JvmOverloads constructor(
"【当前任务Stop信息】StopMd5=${curContrail?.txtFileMd5}, StopDPQPMd5=${curContrail?.txtFileMd5DPQP}"
}
private fun initDebugLogTextViewTitle() {
val isRoutingVerifyMode =
MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingVerifyMode
debugLogTitleTextView.text =
if (isRoutingVerifyMode) "自主算路验证模式关键节点日志(司机端)" else "无人化运营流程关键节点日志(司机端)"
}
override fun onTaskWithOrderDataChanged(taskWithOrder: QueryCurrentTaskRespBean.Result?) {
d(TAG, "onTaskWithOrderDataChanged")
initViewByData(taskWithOrder)
initViewByTaskData(taskWithOrder)
}
override fun onTaskCompleted(result: QueryCurrentTaskRespBean.Result?) {
@@ -234,4 +286,16 @@ public class DebugView @JvmOverloads constructor(
override fun onTaskTripInfoLocalCalculateChanged(meters: Long, timeInSecond: Long) {
}
override fun onStatusChanged(descriptor: StatusDescriptor?, isTrue: Boolean) {
if (StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE == descriptor) {
UiThreadHandler.post {
initCurrentBusinessMode()
initDebugLogTextViewTitle()
unmanedTaskOrderContainer.visibility = if (isTrue) View.GONE else View.VISIBLE
debugLogHistoryTextView.maxLines = if (isTrue) 30 else 15
}
printInfoMsg("[当前业务模式变化] afterValue=${if (isTrue) "自主算路验证模式" else "无人化运营流程模式"}")
}
}
}

View File

@@ -0,0 +1,170 @@
package com.mogo.och.taxi.ui.routing
import android.graphics.Point
import android.os.Bundle
import android.view.Gravity
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.view.SpacesItemDecoration
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.utils.FlowBus
import com.mogo.och.taxi.R
import com.mogo.och.taxi.bean.GrayLineBean
import com.mogo.och.taxi.constant.TaxiDriverEventConst
import com.mogo.och.taxi.ui.debug.DebugView
import kotlinx.android.synthetic.main.routing_choose_task_activity.btnChooseLineSubmit
import kotlinx.android.synthetic.main.routing_choose_task_activity.btnClose
import kotlinx.android.synthetic.main.routing_choose_task_activity.chooseLineListView
import kotlinx.android.synthetic.main.routing_no_data_common_view.noDataContainer
import kotlinx.coroutines.flow.map
class TaxiRoutingChooseLineActivity : AppCompatActivity() {
companion object {
const val TAG = "TaxiRoutingChooseLineActivity"
}
private val mViewModel: TaxiRoutingChooseLineViewModel by lazy {
ViewModelProvider(
this,
ViewModelProvider.NewInstanceFactory()
)[TaxiRoutingChooseLineViewModel::class.java]
}
private val mLoadingDialog: TaxiRoutingLoadingDialog by lazy {
TaxiRoutingLoadingDialog(
this
)
}
private lateinit var mChooseLineListAdapter: TaxiRoutingChooseLineAdapter
private lateinit var mLinearLayoutManager: LinearLayoutManager
private val mRoutingLineList: MutableList<GrayLineBean> = ArrayList()
private var mCurrentChosenPosition: Int = -1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.routing_choose_task_activity)
initWindowParams()
initView()
initViewListener()
initViewModelObserver()
loadData()
}
private fun initWindowParams() {
val window = window
val params = window.attributes
val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
val point = Point()
windowManager.defaultDisplay.getSize(point) //用于获取屏幕高度
params.width = (point.x * 0.375).toInt()
params.height = ViewGroup.LayoutParams.MATCH_PARENT
window.attributes = params
window.setGravity(Gravity.START or Gravity.BOTTOM)
}
private fun initView() {
mLinearLayoutManager = LinearLayoutManager(this)
chooseLineListView.layoutManager = mLinearLayoutManager
chooseLineListView.itemAnimator =
TaxiRoutingChooseLineItemOpenAnimator()
mChooseLineListAdapter = TaxiRoutingChooseLineAdapter(applicationContext, mRoutingLineList)
chooseLineListView.addItemDecoration(SpacesItemDecoration(4))
chooseLineListView.adapter = mChooseLineListAdapter
//设置item 点击事件
mChooseLineListAdapter.setOnLineItemClickListener(object :
TaxiRoutingChooseLineAdapter.OnChooseLineItemClickListener {
override fun onItemClick(position: Int, close: Boolean) {
mCurrentChosenPosition = position
}
})
}
private fun initViewListener() {
btnClose.setOnClickListener {
finish()
}
btnChooseLineSubmit.setOnClickListener {
if (mCurrentChosenPosition == -1) {
ToastUtils.showLong("请先选择任务")
return@setOnClickListener
}
DebugView.printInfoMsg("[选择灰度任务] 当前选择 mCurrentChosenPosition=$mCurrentChosenPosition, ")
mLoadingDialog.showLoading()
val chosenItem = mRoutingLineList[mCurrentChosenPosition]
mViewModel.sendUiIntent(
TaxiRoutingUiIntent.StartTaskAndQueryContrail(chosenItem)
)
}
}
private fun initViewModelObserver() {
lifecycleScope.launchWhenStarted {
mViewModel.uiStateFlow.map { it.routingUiState }.collect { routingUiState ->
CallerLogger.d(
TAG,
"uiStateFlow-initViewModelObserver: $routingUiState"
)
when (routingUiState) {
is RoutingUIState.Init -> {
showEmptyView()
}
is RoutingUIState.ShowGrayLineList -> {
onRoutingGrayLineListChanged(routingUiState.data)
}
is RoutingUIState.HideChooseLineLoading -> {
mLoadingDialog.hideLoading()
if (routingUiState.isCosePage) {
mChooseLineListAdapter.setOnLineItemClickListener(null)
finish()
}
}
is RoutingUIState.PostRoutingTaskResult -> {
FlowBus.with<RoutingUIState.RoutingTask>(TaxiDriverEventConst.RoutingActivityEvent.EVENT_TYPE_GET_CHOSEN_LINE_TASK)
.post(this, RoutingUIState.RoutingTask(
grayLineBean = routingUiState.grayLineBean,
contrailBean = routingUiState.contrailBean,
grayId = routingUiState.grayId
))
}
}
}
}
}
private fun showEmptyView() {
chooseLineListView.visibility = View.GONE
btnChooseLineSubmit.visibility = View.GONE
noDataContainer.visibility = View.VISIBLE
}
private fun showRecyclerView() {
chooseLineListView.visibility = View.VISIBLE
btnChooseLineSubmit.visibility = View.VISIBLE
noDataContainer.visibility = View.GONE
}
private fun loadData() {
mViewModel.sendUiIntent(TaxiRoutingUiIntent.QueryRoutingGrayLineList(System.currentTimeMillis()))
}
private fun onRoutingGrayLineListChanged(data: MutableList<GrayLineBean>) {
if (data.isNotEmpty()) {
showRecyclerView()
mRoutingLineList.clear()
mRoutingLineList.addAll(data)
mChooseLineListAdapter.notifyDataSetChanged()
} else {
showEmptyView()
}
}
}

View File

@@ -0,0 +1,87 @@
package com.mogo.och.taxi.ui.routing
import android.content.Context
import android.graphics.Color
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatTextView
import androidx.recyclerview.widget.RecyclerView
import com.mogo.och.taxi.R
import com.mogo.och.taxi.bean.GrayLineBean
class TaxiRoutingChooseLineAdapter(
private val mContext: Context,
private val mData: List<GrayLineBean>
) : RecyclerView.Adapter<TaxiRoutingChooseLineAdapter.SwitchLineViewHolder>() {
companion object {
const val TAG = "TaxiRoutingChooseLineAdapter"
}
private var mItemClickListener: OnChooseLineItemClickListener? = null
private var mLastChoosedLineIndex = -1
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SwitchLineViewHolder {
val view = LayoutInflater.from(mContext).inflate(
R.layout.routing_choose_line_list_item, parent, false
)
return SwitchLineViewHolder(view)
}
override fun onBindViewHolder(holder: SwitchLineViewHolder, position: Int) {
val currentPosition = holder.bindingAdapterPosition
val data = mData[currentPosition]
holder.lineNameTextView.text = data.lineName
holder.todayVerifyNumTextView.text = "本车今日已验证:${data.carVerificationCount}"
holder.historyVerifyNumTextView.text =
"路线累计反馈${data.lineSuccessCount}可用,${data.lineFailCount}不可用"
if (data.isChoosed) {
holder.itemView.setBackgroundResource(R.drawable.routing_choose_line_shape_select_line_item_bg_selected)
} else {
holder.itemView.setBackgroundColor(Color.parseColor("#162761"))
}
//设置item点击事件
holder.itemView.setOnClickListener {
mData.forEachIndexed { index, result ->
if (result.isChoosed && index != currentPosition) {
result.isChoosed = false
notifyItemChanged(index)
}
}
val isCurrentItemSelected = !mData[currentPosition].isChoosed
mData[currentPosition].isChoosed = isCurrentItemSelected
notifyItemChanged(currentPosition)
mItemClickListener?.onItemClick(
currentPosition,
isCurrentItemSelected
)
mLastChoosedLineIndex = currentPosition
}
}
override fun getItemCount(): Int {
return mData.size
}
fun setOnLineItemClickListener(itemClickListener: OnChooseLineItemClickListener?) {
mItemClickListener = itemClickListener
}
interface OnChooseLineItemClickListener {
fun onItemClick(position: Int, isChoosed: Boolean)
}
class SwitchLineViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val lineNameTextView: AppCompatTextView//线路名称
val todayVerifyNumTextView: AppCompatTextView //本车今天验证次数
val historyVerifyNumTextView: AppCompatTextView //路线累计验证次数
init {
lineNameTextView = itemView.findViewById(R.id.switchLineNameTextView)
todayVerifyNumTextView = itemView.findViewById(R.id.todayVerifyNumTextView)
historyVerifyNumTextView = itemView.findViewById(R.id.historyVerifyNumTextView)
}
}
}

View File

@@ -0,0 +1,641 @@
package com.mogo.och.taxi.ui.routing;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.view.View;
import android.view.ViewPropertyAnimator;
import androidx.annotation.NonNull;
import androidx.core.view.ViewCompat;
import androidx.recyclerview.widget.DefaultItemAnimator;
import androidx.recyclerview.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
/**
* This implementation of {@link RecyclerView.ItemAnimator} provides basic
* animations on remove, add, and move events that happen to the items in
* a RecyclerView. RecyclerView uses a DefaultItemAnimator by default.
*
* @see RecyclerView#setItemAnimator(RecyclerView.ItemAnimator)
*/
public class TaxiRoutingChooseLineItemOpenAnimator extends DefaultItemAnimator {
private static final boolean DEBUG = false;
private static TimeInterpolator sDefaultInterpolator;
private final ArrayList<RecyclerView.ViewHolder> mPendingRemovals = new ArrayList<>();
private final ArrayList<RecyclerView.ViewHolder> mPendingAdditions = new ArrayList<>();
private final ArrayList<MoveInfo> mPendingMoves = new ArrayList<>();
private final ArrayList<ChangeInfo> mPendingChanges = new ArrayList<>();
private final ArrayList<ArrayList<RecyclerView.ViewHolder>> mAdditionsList = new ArrayList<>();
private final ArrayList<ArrayList<MoveInfo>> mMovesList = new ArrayList<>();
private final ArrayList<ArrayList<ChangeInfo>> mChangesList = new ArrayList<>();
private final ArrayList<RecyclerView.ViewHolder> mAddAnimations = new ArrayList<>();
private final ArrayList<RecyclerView.ViewHolder> mMoveAnimations = new ArrayList<>();
private final ArrayList<RecyclerView.ViewHolder> mRemoveAnimations = new ArrayList<>();
private final ArrayList<RecyclerView.ViewHolder> mChangeAnimations = new ArrayList<>();
private static class MoveInfo {
public RecyclerView.ViewHolder holder;
public int fromX, fromY, toX, toY;
MoveInfo(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
this.holder = holder;
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
}
}
private static class ChangeInfo {
public RecyclerView.ViewHolder oldHolder, newHolder;
public int fromX, fromY, toX, toY;
private ChangeInfo(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder) {
this.oldHolder = oldHolder;
this.newHolder = newHolder;
}
ChangeInfo(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder,
int fromX, int fromY, int toX, int toY) {
this(oldHolder, newHolder);
this.fromX = fromX;
this.fromY = fromY;
this.toX = toX;
this.toY = toY;
}
@Override
public String toString() {
return "ChangeInfo{"
+ "oldHolder=" + oldHolder
+ ", newHolder=" + newHolder
+ ", fromX=" + fromX
+ ", fromY=" + fromY
+ ", toX=" + toX
+ ", toY=" + toY
+ '}';
}
}
@Override
public void runPendingAnimations() {
boolean removalsPending = !mPendingRemovals.isEmpty();
boolean movesPending = !mPendingMoves.isEmpty();
boolean changesPending = !mPendingChanges.isEmpty();
boolean additionsPending = !mPendingAdditions.isEmpty();
if (!removalsPending && !movesPending && !additionsPending && !changesPending) {
// nothing to animate
return;
}
// First, remove stuff
for (RecyclerView.ViewHolder holder : mPendingRemovals) {
animateRemoveImpl(holder);
}
mPendingRemovals.clear();
// Next, move stuff
if (movesPending) {
final ArrayList<MoveInfo> moves = new ArrayList<>(mPendingMoves);
mMovesList.add(moves);
mPendingMoves.clear();
Runnable mover = () -> {
for (MoveInfo moveInfo : moves) {
animateMoveImpl(moveInfo.holder, moveInfo.fromX, moveInfo.fromY,
moveInfo.toX, moveInfo.toY);
}
moves.clear();
mMovesList.remove(moves);
};
if (removalsPending) {
View view = moves.get(0).holder.itemView;
ViewCompat.postOnAnimationDelayed(view, mover, getRemoveDuration());
} else {
mover.run();
}
}
// Next, change stuff, to run in parallel with move animations
if (changesPending) {
final ArrayList<ChangeInfo> changes = new ArrayList<>(mPendingChanges);
mChangesList.add(changes);
mPendingChanges.clear();
Runnable changer = () -> {
for (ChangeInfo change : changes) {
animateChangeImpl(change);
}
changes.clear();
mChangesList.remove(changes);
};
if (removalsPending) {
RecyclerView.ViewHolder holder = changes.get(0).oldHolder;
ViewCompat.postOnAnimationDelayed(holder.itemView, changer, getRemoveDuration());
} else {
changer.run();
}
}
// Next, add stuff
if (additionsPending) {
final ArrayList<RecyclerView.ViewHolder> additions = new ArrayList<>(mPendingAdditions);
mAdditionsList.add(additions);
mPendingAdditions.clear();
Runnable adder = () -> {
for (RecyclerView.ViewHolder holder : additions) {
animateAddImpl(holder);
}
additions.clear();
mAdditionsList.remove(additions);
};
if (removalsPending || movesPending || changesPending) {
long removeDuration = removalsPending ? getRemoveDuration() : 0;
long moveDuration = movesPending ? getMoveDuration() : 0;
long changeDuration = changesPending ? getChangeDuration() : 0;
long totalDelay = removeDuration + Math.max(moveDuration, changeDuration);
View view = additions.get(0).itemView;
ViewCompat.postOnAnimationDelayed(view, adder, totalDelay);
} else {
adder.run();
}
}
}
@Override
public boolean animateRemove(final RecyclerView.ViewHolder holder) {
resetAnimation(holder);
mPendingRemovals.add(holder);
return true;
}
private void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
final View view = holder.itemView;
final ViewPropertyAnimator animation = view.animate();
mRemoveAnimations.add(holder);
animation.setDuration(getRemoveDuration()).alpha(0).setListener(
new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchRemoveStarting(holder);
}
@Override
public void onAnimationEnd(Animator animator) {
animation.setListener(null);
view.setAlpha(1);
dispatchRemoveFinished(holder);
mRemoveAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
@Override
public boolean animateAdd(final RecyclerView.ViewHolder holder) {
resetAnimation(holder);
holder.itemView.setAlpha(0);
mPendingAdditions.add(holder);
return true;
}
void animateAddImpl(final RecyclerView.ViewHolder holder) {
final View view = holder.itemView;
final ViewPropertyAnimator animation = view.animate();
mAddAnimations.add(holder);
animation.alpha(1).setDuration(getAddDuration())
.setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchAddStarting(holder);
}
@Override
public void onAnimationCancel(Animator animator) {
view.setAlpha(1);
}
@Override
public void onAnimationEnd(Animator animator) {
animation.setListener(null);
dispatchAddFinished(holder);
mAddAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
@Override
public boolean animateMove(final RecyclerView.ViewHolder holder, int fromX, int fromY,
int toX, int toY) {
final View view = holder.itemView;
fromX += (int) holder.itemView.getTranslationX();
fromY += (int) holder.itemView.getTranslationY();
resetAnimation(holder);
int deltaX = toX - fromX;
int deltaY = toY - fromY;
if (deltaX == 0 && deltaY == 0) {
dispatchMoveFinished(holder);
return false;
}
if (deltaX != 0) {
view.setTranslationX(-deltaX);
}
if (deltaY != 0) {
view.setTranslationY(-deltaY);
}
mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
return true;
}
void animateMoveImpl(final RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
final View view = holder.itemView;
final int deltaX = toX - fromX;
final int deltaY = toY - fromY;
if (deltaX != 0) {
view.animate().translationX(0);
}
if (deltaY != 0) {
view.animate().translationY(0);
}
// TODO: make EndActions end listeners instead, since end actions aren't called when
// vpas are canceled (and can't end them. why?)
// need listener functionality in VPACompat for this. Ick.
final ViewPropertyAnimator animation = view.animate();
mMoveAnimations.add(holder);
animation.setDuration(getMoveDuration()).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchMoveStarting(holder);
}
@Override
public void onAnimationCancel(Animator animator) {
if (deltaX != 0) {
view.setTranslationX(0);
}
if (deltaY != 0) {
view.setTranslationY(0);
}
}
@Override
public void onAnimationEnd(Animator animator) {
animation.setListener(null);
dispatchMoveFinished(holder);
mMoveAnimations.remove(holder);
dispatchFinishedWhenDone();
}
}).start();
}
@Override
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder,
int fromX, int fromY, int toX, int toY) {
if (oldHolder == newHolder) {
// Don't know how to run change animations when the same view holder is re-used.
// run a move animation to handle position changes.
return animateMove(oldHolder, fromX, fromY, toX, toY);
}
final float prevTranslationX = oldHolder.itemView.getTranslationX();
final float prevTranslationY = oldHolder.itemView.getTranslationY();
final float prevAlpha = oldHolder.itemView.getAlpha();
resetAnimation(oldHolder);
int deltaX = (int) (toX - fromX - prevTranslationX);
int deltaY = (int) (toY - fromY - prevTranslationY);
// recover prev translation state after ending animation
oldHolder.itemView.setTranslationX(prevTranslationX);
oldHolder.itemView.setTranslationY(prevTranslationY);
oldHolder.itemView.setAlpha(prevAlpha);
if (newHolder != null) {
// carry over translation values
resetAnimation(newHolder);
newHolder.itemView.setTranslationX(-deltaX);
newHolder.itemView.setTranslationY(-deltaY);
newHolder.itemView.setAlpha(0);
}
mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY));
return true;
}
void animateChangeImpl(final ChangeInfo changeInfo) {
final RecyclerView.ViewHolder holder = changeInfo.oldHolder;
final View view = holder == null ? null : holder.itemView;
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;
final View newView = newHolder != null ? newHolder.itemView : null;
if (view != null) {
final ViewPropertyAnimator oldViewAnim = view.animate().setDuration(
getChangeDuration());
mChangeAnimations.add(changeInfo.oldHolder);
oldViewAnim.translationX((float) (changeInfo.toX - changeInfo.fromX));
oldViewAnim.translationY((float) (changeInfo.toY - changeInfo.fromY));
oldViewAnim.alpha(0).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchChangeStarting(changeInfo.oldHolder, true);
}
@Override
public void onAnimationEnd(Animator animator) {
oldViewAnim.setListener(null);
view.setAlpha(1);
view.setTranslationX(0);
view.setTranslationY(0);
dispatchChangeFinished(changeInfo.oldHolder, true);
mChangeAnimations.remove(changeInfo.oldHolder);
dispatchFinishedWhenDone();
}
}).start();
}
if (newView != null) {
final ViewPropertyAnimator newViewAnimation = newView.animate();
mChangeAnimations.add(changeInfo.newHolder);
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration())
.alpha(1).setListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationStart(Animator animator) {
dispatchChangeStarting(changeInfo.newHolder, false);
}
@Override
public void onAnimationEnd(Animator animator) {
newViewAnimation.setListener(null);
newView.setAlpha(1);
newView.setTranslationX(0);
newView.setTranslationY(0);
dispatchChangeFinished(changeInfo.newHolder, false);
mChangeAnimations.remove(changeInfo.newHolder);
dispatchFinishedWhenDone();
}
}).start();
}
}
private void endChangeAnimation(List<ChangeInfo> infoList, RecyclerView.ViewHolder item) {
for (int i = infoList.size() - 1; i >= 0; i--) {
ChangeInfo changeInfo = infoList.get(i);
if (endChangeAnimationIfNecessary(changeInfo, item)) {
if (changeInfo.oldHolder == null && changeInfo.newHolder == null) {
infoList.remove(changeInfo);
}
}
}
}
private void endChangeAnimationIfNecessary(ChangeInfo changeInfo) {
if (changeInfo.oldHolder != null) {
endChangeAnimationIfNecessary(changeInfo, changeInfo.oldHolder);
}
if (changeInfo.newHolder != null) {
endChangeAnimationIfNecessary(changeInfo, changeInfo.newHolder);
}
}
private boolean endChangeAnimationIfNecessary(ChangeInfo changeInfo, RecyclerView.ViewHolder item) {
boolean oldItem = false;
if (changeInfo.newHolder == item) {
changeInfo.newHolder = null;
} else if (changeInfo.oldHolder == item) {
changeInfo.oldHolder = null;
oldItem = true;
} else {
return false;
}
item.itemView.setAlpha(1);
item.itemView.setTranslationX(0);
item.itemView.setTranslationY(0);
dispatchChangeFinished(item, oldItem);
return true;
}
@Override
public void endAnimation(RecyclerView.ViewHolder item) {
final View view = item.itemView;
// this will trigger end callback which should set properties to their target values.
view.animate().cancel();
// TODO if some other animations are chained to end, how do we cancel them as well?
for (int i = mPendingMoves.size() - 1; i >= 0; i--) {
MoveInfo moveInfo = mPendingMoves.get(i);
if (moveInfo.holder == item) {
view.setTranslationY(0);
view.setTranslationX(0);
dispatchMoveFinished(item);
mPendingMoves.remove(i);
}
}
endChangeAnimation(mPendingChanges, item);
if (mPendingRemovals.remove(item)) {
view.setAlpha(1);
dispatchRemoveFinished(item);
}
if (mPendingAdditions.remove(item)) {
view.setAlpha(1);
dispatchAddFinished(item);
}
for (int i = mChangesList.size() - 1; i >= 0; i--) {
ArrayList<ChangeInfo> changes = mChangesList.get(i);
endChangeAnimation(changes, item);
if (changes.isEmpty()) {
mChangesList.remove(i);
}
}
for (int i = mMovesList.size() - 1; i >= 0; i--) {
ArrayList<MoveInfo> moves = mMovesList.get(i);
for (int j = moves.size() - 1; j >= 0; j--) {
MoveInfo moveInfo = moves.get(j);
if (moveInfo.holder == item) {
view.setTranslationY(0);
view.setTranslationX(0);
dispatchMoveFinished(item);
moves.remove(j);
if (moves.isEmpty()) {
mMovesList.remove(i);
}
break;
}
}
}
for (int i = mAdditionsList.size() - 1; i >= 0; i--) {
ArrayList<RecyclerView.ViewHolder> additions = mAdditionsList.get(i);
if (additions.remove(item)) {
view.setAlpha(1);
dispatchAddFinished(item);
if (additions.isEmpty()) {
mAdditionsList.remove(i);
}
}
}
// animations should be ended by the cancel above.
//noinspection Pointless BooleanExpression,ConstantConditions
if (mRemoveAnimations.remove(item) && DEBUG) {
throw new IllegalStateException("after animation is cancelled, item should not be in "
+ "mRemoveAnimations list");
}
//noinspection Pointless BooleanExpression,ConstantConditions
if (mAddAnimations.remove(item) && DEBUG) {
throw new IllegalStateException("after animation is cancelled, item should not be in "
+ "mAddAnimations list");
}
//noinspection Pointless BooleanExpression,ConstantConditions
if (mChangeAnimations.remove(item) && DEBUG) {
throw new IllegalStateException("after animation is cancelled, item should not be in "
+ "mChangeAnimations list");
}
//noinspection Pointless BooleanExpression,ConstantConditions
if (mMoveAnimations.remove(item) && DEBUG) {
throw new IllegalStateException("after animation is cancelled, item should not be in "
+ "mMoveAnimations list");
}
dispatchFinishedWhenDone();
}
private void resetAnimation(RecyclerView.ViewHolder holder) {
if (sDefaultInterpolator == null) {
sDefaultInterpolator = new ValueAnimator().getInterpolator();
}
holder.itemView.animate().setInterpolator(sDefaultInterpolator);
endAnimation(holder);
}
@Override
public boolean isRunning() {
return (!mPendingAdditions.isEmpty()
|| !mPendingChanges.isEmpty()
|| !mPendingMoves.isEmpty()
|| !mPendingRemovals.isEmpty()
|| !mMoveAnimations.isEmpty()
|| !mRemoveAnimations.isEmpty()
|| !mAddAnimations.isEmpty()
|| !mChangeAnimations.isEmpty()
|| !mMovesList.isEmpty()
|| !mAdditionsList.isEmpty()
|| !mChangesList.isEmpty());
}
/**
* Check the state of currently pending and running animations. If there are none
* pending/running, call {@link #dispatchAnimationsFinished()} to notify any
* listeners.
*/
void dispatchFinishedWhenDone() {
if (!isRunning()) {
dispatchAnimationsFinished();
}
}
@Override
public void endAnimations() {
int count = mPendingMoves.size();
for (int i = count - 1; i >= 0; i--) {
MoveInfo item = mPendingMoves.get(i);
View view = item.holder.itemView;
view.setTranslationY(0);
view.setTranslationX(0);
dispatchMoveFinished(item.holder);
mPendingMoves.remove(i);
}
count = mPendingRemovals.size();
for (int i = count - 1; i >= 0; i--) {
RecyclerView.ViewHolder item = mPendingRemovals.get(i);
dispatchRemoveFinished(item);
mPendingRemovals.remove(i);
}
count = mPendingAdditions.size();
for (int i = count - 1; i >= 0; i--) {
RecyclerView.ViewHolder item = mPendingAdditions.get(i);
item.itemView.setAlpha(1);
dispatchAddFinished(item);
mPendingAdditions.remove(i);
}
count = mPendingChanges.size();
for (int i = count - 1; i >= 0; i--) {
endChangeAnimationIfNecessary(mPendingChanges.get(i));
}
mPendingChanges.clear();
if (!isRunning()) {
return;
}
int listCount = mMovesList.size();
for (int i = listCount - 1; i >= 0; i--) {
ArrayList<MoveInfo> moves = mMovesList.get(i);
count = moves.size();
for (int j = count - 1; j >= 0; j--) {
MoveInfo moveInfo = moves.get(j);
RecyclerView.ViewHolder item = moveInfo.holder;
View view = item.itemView;
view.setTranslationY(0);
view.setTranslationX(0);
dispatchMoveFinished(moveInfo.holder);
moves.remove(j);
if (moves.isEmpty()) {
mMovesList.remove(moves);
}
}
}
listCount = mAdditionsList.size();
for (int i = listCount - 1; i >= 0; i--) {
ArrayList<RecyclerView.ViewHolder> additions = mAdditionsList.get(i);
count = additions.size();
for (int j = count - 1; j >= 0; j--) {
RecyclerView.ViewHolder item = additions.get(j);
View view = item.itemView;
view.setAlpha(1);
dispatchAddFinished(item);
additions.remove(j);
if (additions.isEmpty()) {
mAdditionsList.remove(additions);
}
}
}
listCount = mChangesList.size();
for (int i = listCount - 1; i >= 0; i--) {
ArrayList<ChangeInfo> changes = mChangesList.get(i);
count = changes.size();
for (int j = count - 1; j >= 0; j--) {
endChangeAnimationIfNecessary(changes.get(j));
if (changes.isEmpty()) {
mChangesList.remove(changes);
}
}
}
cancelAll(mRemoveAnimations);
cancelAll(mMoveAnimations);
cancelAll(mAddAnimations);
cancelAll(mChangeAnimations);
dispatchAnimationsFinished();
}
void cancelAll(List<RecyclerView.ViewHolder> viewHolders) {
for (int i = viewHolders.size() - 1; i >= 0; i--) {
viewHolders.get(i).itemView.animate().cancel();
}
}
/**
* {@inheritDoc}
* <p>
* If the payload list is not empty, DefaultItemAnimator returns <code>true</code>.
* When this is the case:
* <ul>
* <li>If you override {@link #animateChange(RecyclerView.ViewHolder, RecyclerView.ViewHolder, int, int, int, int)}, both
* ViewHolder arguments will be the same instance.
* </li>
* <li>
* If you are not overriding {@link #animateChange(RecyclerView.ViewHolder, RecyclerView.ViewHolder, int, int, int, int)},
* then DefaultItemAnimator will call {@link #animateMove(RecyclerView.ViewHolder, int, int, int, int)} and
* run a move animation instead.
* </li>
* </ul>
*/
@Override
public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder,
@NonNull List<Object> payloads) {
return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder, payloads);
}
}

View File

@@ -0,0 +1,111 @@
package com.mogo.och.taxi.ui.routing
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.taxi.base.BaseViewModel
import com.mogo.och.taxi.base.IUiIntent
import com.mogo.och.taxi.bean.GrayLineBean
import com.mogo.och.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.taxi.callback.ITaxiRoutingCallback
import com.mogo.och.taxi.ui.debug.DebugView
class TaxiRoutingChooseLineViewModel : BaseViewModel<TaxiRoutingUiState, TaxiRoutingUiIntent>(),
ITaxiRoutingCallback {
private val TAG = SceneConstant.M_TAXI + "TaxiRoutingChooseLineViewModel"
init {
TaxiRoutingModel.addTaxiRoutingListener(TAG, this)
}
override fun initUiState(): TaxiRoutingUiState {
return TaxiRoutingUiState(RoutingUIState.Init)
}
override fun handleIntent(intent: IUiIntent) {
when (intent) {
is TaxiRoutingUiIntent.QueryRoutingGrayLineList -> {
TaxiRoutingModel.queryRoutingGrayLineList()
}
is TaxiRoutingUiIntent.StartTaskAndQueryContrail -> {
val contrailId = intent.grayLineBean.contrailId
TaxiRoutingModel.startGrayTaskAndQueryRoutingContrail(
contrailId ?: -1L,
intent.grayLineBean
)
}
}
}
override fun onQueryRoutingGrayLineListSuccess(data: MutableList<GrayLineBean>) {
sendUiState {
copy(
routingUiState = RoutingUIState.ShowGrayLineList(data)
)
}
}
override fun onQueryRoutingGrayLineListFailed(errorStr: String) {
ToastUtils.showShort(errorStr)
DebugView.printErrorMsg("[查询灰度任务] 失败, error=$errorStr")
sendUiState {
copy(
routingUiState = RoutingUIState.Init
)
}
}
override fun onStartGrayTaskAndQueryContrailSuccess(data: StartGrayAndQueryContrailRsp) {
if (data.taskId == -1L) {
onStartGrayTaskAndQueryContrailFailed("开始任务失败, 请稍后重试")
DebugView.printErrorMsg("[开始灰度任务] 开始任务失败, 请稍后重试")
return
}
sendUiState {
copy(
routingUiState = RoutingUIState.PostRoutingTaskResult(
grayLineBean = data.grayLineBean,
contrailBean = data.contrail,
grayId = data.taskId
)
)
}
sendUiState {
copy(
routingUiState = RoutingUIState.HideChooseLineLoading(
isCosePage = true
)
)
}
}
override fun onStartGrayTaskAndQueryContrailFailed(errorStr: String) {
ToastUtils.showShort(errorStr)
DebugView.printErrorMsg("[开始灰度任务&查询轨迹详情] 操作失败, 请稍后重试")
sendUiState {
copy(
routingUiState = RoutingUIState.HideChooseLineLoading(
isCosePage = false
)
)
}
}
override fun onSubmitGrayLineIssueLocationSuccess() {
}
override fun onSubmitGrayLineIssueLocationFailed(errorStr: String) {
}
override fun onSubmitEndTaskSuccess() {
}
override fun onSubmitEndTaskFailed(errorStr: String) {
}
override fun onCleared() {
super.onCleared()
TaxiRoutingModel.removeTaxiRoutingListener(TAG)
}
}

View File

@@ -0,0 +1,98 @@
package com.mogo.och.taxi.ui.routing
import android.content.Context
import android.widget.ImageView
import android.widget.TextView
import androidx.lifecycle.LifecycleObserver
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
import com.mogo.och.taxi.R
class TaxiRoutingFeedbackDialog : BaseFloatDialog, LifecycleObserver {
private var commonConfirm: TextView? = null
private var commonCancel: TextView? = null
private var commonTips: TextView? = null
private var commonCloseIcon: ImageView? = null
private var clickListener: TaxiRoutingFeedBackDialogClickListener? = null
constructor(builder: Builder, context: Context) : super(context) {
commonTips?.text = builder.tipsStr
commonCancel?.text = builder.cancelStr
commonConfirm?.text = builder.confirmStr
clickListener = builder.clickListener
}
init {
setContentView(R.layout.dialog_routing_feedback_result)
setCanceledOnTouchOutside(true)
commonConfirm = findViewById(R.id.routing_common_confirm)
commonCancel = findViewById(R.id.routing_common_cancel)
commonTips = findViewById(R.id.routing_common_tips)
commonCloseIcon = findViewById(R.id.closeDialogIcon)
commonCloseIcon?.setOnClickListener {
dismiss()
}
commonConfirm?.setOnClickListener {
clickListener?.confirm()
dismiss()
}
commonCancel?.setOnClickListener {
clickListener?.cancel()
dismiss()
}
}
fun showDialog() {
if (isShowing) {
return
}
show()
}
fun hideDialog() {
if (isShowing) {
dismiss()
}
}
interface TaxiRoutingFeedBackDialogClickListener {
fun confirm()
fun cancel()
}
class Builder {
var tipsStr: String = ""
var confirmStr: String = ""
var cancelStr: String = ""
var clickListener: TaxiRoutingFeedBackDialogClickListener? = null
fun tips(tips: String): Builder {
this.tipsStr = tips
return this
}
fun confirmStr(commit: String): Builder {
this.confirmStr = commit
return this
}
fun cancelStr(cancel: String): Builder {
this.cancelStr = cancel
return this
}
fun clickListener(listener: TaxiRoutingFeedBackDialogClickListener): Builder {
this.clickListener = listener
return this
}
fun build(context: Context): TaxiRoutingFeedbackDialog? {
return TaxiRoutingFeedbackDialog(this, context)
}
}
}

View File

@@ -0,0 +1,326 @@
package com.mogo.och.taxi.ui.routing
import android.os.Bundle
import android.view.View
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope
import com.amap.api.navi.model.NaviLatLng
import com.mogo.commons.mvp.BaseFragment
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.function.main.MainMoGoApplication
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.map.AmapNaviToDestinationModel
import com.mogo.och.common.module.map.ICommonNaviChangedCallback
import com.mogo.och.common.module.utils.FlowBus
import com.mogo.och.taxi.R
import com.mogo.och.taxi.bean.EndGrayTaskFeedbackType
import com.mogo.och.taxi.constant.TaxiDriverEventConst
import com.mogo.och.taxi.utils.TaskUtils
import kotlinx.android.synthetic.main.routing_fragment.btnChooseTask
import kotlinx.android.synthetic.main.routing_fragment.btnFinishTask
import kotlinx.android.synthetic.main.routing_fragment.btnStartTask
import kotlinx.android.synthetic.main.routing_fragment.btnSummitIssue
import kotlinx.android.synthetic.main.routing_fragment.endPoint
import kotlinx.android.synthetic.main.routing_fragment.endStationName
import kotlinx.android.synthetic.main.routing_fragment.finishSubmitIssueGroup
import kotlinx.android.synthetic.main.routing_fragment.headerTitleContainer
import kotlinx.android.synthetic.main.routing_fragment.mCurrentTaskLayout
import kotlinx.android.synthetic.main.routing_fragment.naviToEnd
import kotlinx.android.synthetic.main.routing_fragment.naviToStart
import kotlinx.android.synthetic.main.routing_fragment.noDataContainer
import kotlinx.android.synthetic.main.routing_fragment.startPoint
import kotlinx.android.synthetic.main.routing_fragment.startStationName
import kotlinx.android.synthetic.main.routing_fragment.taskTitleTv
import kotlinx.android.synthetic.main.routing_fragment.taskTripInfo
import kotlinx.coroutines.flow.map
class TaxiRoutingFragment : BaseFragment(), ICommonNaviChangedCallback {
companion object {
const val TAG = SceneConstant.M_TAXI + "TaxiRoutingFragment"
fun newInstance(): TaxiRoutingFragment {
val args = Bundle()
val fragment = TaxiRoutingFragment()
fragment.arguments = args
return fragment
}
}
private var mFeedbackDialog: TaxiRoutingFeedbackDialog? = null
private val mViewModel: TaxiRoutingFragmentViewModel by lazy {
ViewModelProvider(
this,
ViewModelProvider.NewInstanceFactory()
)[TaxiRoutingFragmentViewModel::class.java]
}
override fun getLayoutId(): Int {
return R.layout.routing_fragment
}
override fun getTagName(): String {
return "TaxiRoutingFragment"
}
override fun initViews() {
initEventBus()
initViewListener()
initViewModelObserver()
}
private fun initEventBus() {
FlowBus.with<RoutingUIState.RoutingTask>(TaxiDriverEventConst.RoutingActivityEvent.EVENT_TYPE_GET_CHOSEN_LINE_TASK)
.register(this) { task ->
mViewModel.sendUiIntent(TaxiRoutingUiIntent.ShowRoutingTask(task))
}
}
private fun initViewListener() {
btnChooseTask.setOnClickListener {
mViewModel.sendUiIntent(TaxiRoutingUiIntent.StartChooseLineAction(System.currentTimeMillis()))
}
}
private fun initViewModelObserver() {
lifecycleScope.launchWhenStarted {
mViewModel.uiStateFlow.map { it.routingUiState }.collect { routingUiState ->
CallerLogger.d(
TAG,
"uiStateFlow-initViewModelObserver: $routingUiState"
)
when (routingUiState) {
is RoutingUIState.Init -> {
showChooseTaskView()
AmapNaviToDestinationModel.getInstance(context).destroyAmaNavi()
}
is RoutingUIState.RoutingTask -> {
showCurrentLineTaskContentView(routingUiState)
}
is RoutingUIState.ShowFinishTaskButton -> {
showFinishTaskView(routingUiState.routingTask)
}
is RoutingUIState.ShowFeedbackDialog -> {
showFeedbackDialog(routingUiState.grayId)
}
is RoutingUIState.DismissFeedbackDialog -> {
hideFeedbackDialog()
}
}
}
}
}
private fun showChooseTaskView() {
noDataContainer.visibility = View.VISIBLE
mCurrentTaskLayout.visibility = View.GONE
headerTitleContainer.visibility = View.GONE
btnChooseTask.visibility = View.VISIBLE
btnStartTask.visibility = View.GONE
finishSubmitIssueGroup.visibility = View.GONE
}
private fun showCurrentLineTaskContentView(data: RoutingUIState.RoutingTask) {
noDataContainer.visibility = View.GONE
mCurrentTaskLayout.visibility = View.VISIBLE
headerTitleContainer.visibility = View.VISIBLE
taskTitleTv.text = data.grayLineBean?.lineName
btnChooseTask.visibility = View.GONE
btnStartTask.visibility = View.VISIBLE
btnStartTask.setOnClickListener {
mViewModel.sendUiIntent(TaxiRoutingUiIntent.StartTaskAction(data))
}
finishSubmitIssueGroup.visibility = View.GONE
naviToStart.visibility = View.VISIBLE
naviToEnd.visibility = View.INVISIBLE
updateStartAndEndStationPointByStatus(false)
updateCurrentTaskTripInfo(0,0)
data.grayLineBean?.startSite?.also {
initStartNaviToStationParam(
false,
it.gcjLat,
it.gcjLon
)
naviToStart.setOnClickListener {
showNaviToEndStationFragment(true)
}
}
startStationName.text = data.grayLineBean?.startSite?.siteName
endStationName.text = data.grayLineBean?.endSite?.siteName
}
private fun showFinishTaskView(routingTask: RoutingUIState.RoutingTask) {
btnChooseTask.visibility = View.GONE
btnStartTask.visibility = View.GONE
finishSubmitIssueGroup.visibility = View.VISIBLE
btnFinishTask.setOnClickListener {
mViewModel.sendUiIntent(
TaxiRoutingUiIntent.ShowFeedbackDialog(
routingTask.grayId ?: -1
)
)
}
btnSummitIssue.setOnClickListener {
mViewModel.sendUiIntent(
TaxiRoutingUiIntent.SubmitGrayLineIssueLocation(
routingTask.grayId ?: -1L
)
)
}
naviToStart.visibility = View.INVISIBLE
naviToEnd.visibility = View.VISIBLE
updateStartAndEndStationPointByStatus(true)
updateCurrentTaskTripInfo(0,0)
routingTask.grayLineBean?.endSite?.also {
initStartNaviToStationParam(
false,
it.gcjLat,
it.gcjLon
)
naviToEnd.setOnClickListener {
showNaviToEndStationFragment(true)
}
}
}
private fun updateStartAndEndStationPointByStatus(isGoingToStation: Boolean) {
if (isGoingToStation) {// 即将到达的站点
startPoint.setImageResource(R.drawable.taxi_driver_circle_blue_big)
endPoint.setImageResource(R.drawable.taxi_driver_circle_green_big)
} else {// 到达站点 或 已经经过的站点
startPoint.setImageResource(R.drawable.taxi_driver_circle_green_big)
endPoint.setImageResource(R.drawable.taxi_driver_circle_blue_big)
}
}
private fun showFeedbackDialog(grayId: Long) {
if (mFeedbackDialog == null) {
val builder: TaxiRoutingFeedbackDialog.Builder = TaxiRoutingFeedbackDialog.Builder()
builder.cancelStr(
MainMoGoApplication.getApp()
.getString(R.string.routing_feedback_result_btn_not_sure)
).confirmStr(
MainMoGoApplication.getApp()
.getString(R.string.routing_feedback_result_btn_sure)
).tips(MainMoGoApplication.getApp().getString(R.string.routing_feedback_result_hint))
.clickListener(object :
TaxiRoutingFeedbackDialog.TaxiRoutingFeedBackDialogClickListener {
override fun confirm() {
mViewModel.sendUiIntent(
TaxiRoutingUiIntent.SubmitEndTask(
grayId,
EndGrayTaskFeedbackType.USABLE_YES
)
)
}
override fun cancel() {
mViewModel.sendUiIntent(
TaxiRoutingUiIntent.SubmitEndTask(
grayId,
EndGrayTaskFeedbackType.USABLE_NO
)
)
}
})
activity?.also {
mFeedbackDialog = builder.build(it)
mFeedbackDialog?.showDialog()
}
} else {
activity?.also {
mFeedbackDialog?.showDialog()
}
}
}
private fun hideFeedbackDialog() {
mFeedbackDialog?.hideDialog()
}
/**
* 显示/隐藏 前往任务目的地的导航
*
* @param isShow
*/
private fun showNaviToEndStationFragment(isShow: Boolean) {
// FlowBus.with<Boolean>(TaxiDriverEventConst.TaxiFragmentEvent.EVENT_TYPE_START_NAVI_TO_END_STATION)
// .post(this.lifecycleScope, isShow)
TaxiRoutingModel.startNaviToEndStationByAMap(isShow)
}
private fun initStartNaviToStationParam(
isVoicePlay: Boolean,
stationLat: Double,
stationLng: Double
) {
AmapNaviToDestinationModel.getInstance(context).destroyAmaNavi()
val mCurLatitude =
CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02().latitude
val mCurLongitude =
CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02().longitude
CallerLogger.d(
TAG,
"currentLocation, lat=$mCurLatitude, lon=$mCurLongitude"
)
val startNaviLatLng = NaviLatLng(mCurLatitude, mCurLongitude)
val endNaviLatLng = NaviLatLng(stationLat, stationLng)
AmapNaviToDestinationModel.getInstance(context).initAMapNavi(startNaviLatLng, endNaviLatLng)
AmapNaviToDestinationModel.getInstance(context).setVoiceIsMute(isVoicePlay)
AmapNaviToDestinationModel.getInstance(context).setTaxiNaviChangedCallback(this)
}
override fun onCurrentNaviDistAndTimeChanged(meters: Int, timeInSecond: Long) {
updateCurrentTaskTripInfo(meters.toLong(), timeInSecond)
}
override fun reInitNaviAmap(isPlay: Boolean, isRestart: Boolean) {
CallerLogger.d(TAG, "isPlay = $isPlay, isRestart=$isRestart")
if (!isRestart) {
// FlowBus.with<Boolean>(TaxiDriverEventConst.TaxiFragmentEvent.EVENT_TYPE_SHOW_AMAP_NAVI_TO_STATION_FRAGMENT)
// .post(this.lifecycleScope, false)
TaxiRoutingModel.startNaviToEndStationByAMap(false)
return
}
}
/**
* 剩余里程和剩余时间
* @param meters 米
* @param timeInSecond 秒
*/
private fun updateCurrentTaskTripInfo(meters: Long, timeInSecond: Long) {
UiThreadHandler.post {
CallerLogger.d(
TAG,
"updateCurrentTaskTripInfo, taskUtil, ${
TaskUtils.getCurrentTaskTripHtml(
meters,
timeInSecond
)
}"
)
taskTripInfo.text = TaskUtils.getCurrentTaskTripHtml(meters, timeInSecond)
}
}
override fun onDestroyView() {
AmapNaviToDestinationModel.getInstance(context).destroyAmaNavi()
super.onDestroyView()
}
}

View File

@@ -0,0 +1,154 @@
package com.mogo.och.taxi.ui.routing
import android.content.Context
import android.content.Intent
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.taxi.base.BaseViewModel
import com.mogo.och.taxi.base.IUiIntent
import com.mogo.och.taxi.bean.GrayLineBean
import com.mogo.och.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.taxi.callback.ITaxiRoutingCallback
import com.mogo.och.taxi.ui.debug.DebugView
class TaxiRoutingFragmentViewModel : BaseViewModel<TaxiRoutingUiState, TaxiRoutingUiIntent>(),
ITaxiRoutingCallback {
companion object {
const val TAG = SceneConstant.M_TAXI + "TaxiRoutingFragmentViewModel"
}
init {
TaxiRoutingModel.addTaxiRoutingListener(TAG, this)
}
private val mContext: Context
get() = AbsMogoApplication.getApp().applicationContext
override fun initUiState(): TaxiRoutingUiState {
return TaxiRoutingUiState(RoutingUIState.Init)
}
override fun handleIntent(intent: IUiIntent) {
when (intent) {
is TaxiRoutingUiIntent.StartChooseLineAction -> {
DebugView.printInfoMsg("[选择任务] 跳转到选择任务列表")
val intent = Intent(mContext, TaxiRoutingChooseLineActivity::class.java)
mContext?.startActivity(intent)
}
is TaxiRoutingUiIntent.ShowRoutingTask -> {
DebugView.printInfoMsg("[选择任务] 展示当前选择任务刷新UI")
val task = intent.routingTask
sendUiState {
copy(
routingUiState = RoutingUIState.RoutingTask(
task.grayLineBean,
task.contrailBean,
task.grayId
)
)
}
// 设置灰度路线任务执行状态,切换模式时判断使用
MogoStatusManager.getInstance().setTaxiUnmanedDriverLineRoutingPerformTask(TAG, true)
}
is TaxiRoutingUiIntent.StartTaskAction -> {
DebugView.printInfoMsg("[开始任务] 准备开始任务")
val grayLineBean = intent.routingTask.grayLineBean
val contrailBean = intent.routingTask.contrailBean
if (grayLineBean == null || contrailBean == null) {
ToastUtils.showShort("灰度线路或轨迹信息异常,请稍后再试")
DebugView.printErrorMsg("[开始任务] 灰度线路或轨迹信息异常,请稍后再试")
return
}
DebugView.printInfoMsg("[启自驾] 准备启动自驾")
TaxiRoutingModel.updateCurrentGrayLineAndContrail(grayLineBean, contrailBean)
TaxiRoutingModel.startAutoPilot(grayLineBean!!, contrailBean!!)
sendUiState {
copy(
routingUiState = RoutingUIState.ShowFinishTaskButton(intent.routingTask)
)
}
}
is TaxiRoutingUiIntent.SubmitGrayLineIssueLocation -> {
DebugView.printInfoMsg("[上报打点] 准备上报打点")
val grayId = intent.grayId
val currentLocation =
CallerChassisLocationGCJ02ListenerManager.getChassisLocationGCJ02()
TaxiRoutingModel.submitGrayLineIssueLocation(
grayId,
currentLocation.longitude,
currentLocation.latitude
)
}
is TaxiRoutingUiIntent.ShowFeedbackDialog -> {
DebugView.printInfoMsg("[结束任务] 展示结束任务弹框")
sendUiState {
copy(
routingUiState = RoutingUIState.ShowFeedbackDialog(
intent.grayId,
System.currentTimeMillis()
)
)
}
}
is TaxiRoutingUiIntent.SubmitEndTask -> {
DebugView.printInfoMsg("[结束任务] 准备结束任务grayId=${intent.grayId}, type=${intent.type.name}")
TaxiRoutingModel.endGrayTask(intent.grayId, intent.type)
}
}
}
override fun onQueryRoutingGrayLineListSuccess(data: MutableList<GrayLineBean>) {
}
override fun onQueryRoutingGrayLineListFailed(errorStr: String) {
}
override fun onStartGrayTaskAndQueryContrailSuccess(data: StartGrayAndQueryContrailRsp) {
}
override fun onStartGrayTaskAndQueryContrailFailed(errorStr: String) {
}
override fun onSubmitGrayLineIssueLocationSuccess() {
ToastUtils.showShort("问题记录成功")
}
override fun onSubmitGrayLineIssueLocationFailed(errorStr: String) {
ToastUtils.showShort("问题记录失败:$errorStr")
}
override fun onSubmitEndTaskSuccess() {
ToastUtils.showLong("结束任务成功")
sendUiState {
copy(
routingUiState = RoutingUIState.Init
)
}
TaxiRoutingModel.updateCurrentGrayLineAndContrail(null, null)
// 设置灰度路线任务执行状态,切换模式时判断使用
MogoStatusManager.getInstance().setTaxiUnmanedDriverLineRoutingPerformTask(TAG, false)
}
override fun onSubmitEndTaskFailed(errorStr: String) {
ToastUtils.showLong("结束任务失败")
sendUiState {
copy(
routingUiState = RoutingUIState.DismissFeedbackDialog
)
}
}
override fun onCleared() {
TaxiRoutingModel.removeTaxiRoutingListener(TAG)
super.onCleared()
}
}

View File

@@ -0,0 +1,73 @@
package com.mogo.och.taxi.ui.routing
import android.animation.ObjectAnimator
import android.content.Context
import android.view.animation.LinearInterpolator
import androidx.lifecycle.LifecycleObserver
import com.mogo.eagle.core.function.hmi.dialog.BaseFloatDialog
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.taxi.R
import kotlinx.android.synthetic.main.dialog_routing_loading.dialog_loading_text
import kotlinx.android.synthetic.main.dialog_routing_loading.dialog_loading_view
/**
* loading
*/
class TaxiRoutingLoadingDialog : BaseFloatDialog, LifecycleObserver {
private var objectAnimator: ObjectAnimator? = null
private val mLoadingView by lazy { dialog_loading_view }
private val mLoadingText by lazy { dialog_loading_text }
private var mRunnable:Runnable= Runnable {
ToastUtils.showLong("超时未响应,请求失败")
hideLoading()
}
constructor(context: Context) : super(context)
init {
setContentView(R.layout.dialog_routing_loading)
setCanceledOnTouchOutside(false)
}
/**
* 开始旋转
*/
private fun startRotation() {
objectAnimator = ObjectAnimator.ofFloat(mLoadingView, "rotation", -720f, 0f)
objectAnimator?.let {
it.duration = 3000
it.repeatCount = -1
it.interpolator = LinearInterpolator()
it.start()
}
}
/**
* 停止旋转
*/
private fun stopRotation() {
objectAnimator?.let {
if (it.isRunning) {
it.end()
objectAnimator = null
}
}
}
/**
* 显示dialog
*/
fun showLoading() {
mLoadingText.text = "请求中,请稍后..."
startRotation()
show()
}
/**
* 隐藏dialog
*/
fun hideLoading() {
stopRotation()
dismiss()
}
}

View File

@@ -0,0 +1,409 @@
package com.mogo.och.taxi.ui.routing
import android.content.Context
import android.text.TextUtils
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.data.BaseData
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
import com.mogo.eagle.core.network.utils.GsonUtil
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.biz.network.OchCommonServiceCallback
import com.mogo.och.common.module.manager.autopilotmanager.OCHAdasAbilityManager
import com.mogo.och.taxi.bean.ContrailBean
import com.mogo.och.taxi.bean.EndGrayContrailTaskReq
import com.mogo.och.taxi.bean.EndGrayTaskFeedbackType
import com.mogo.och.taxi.bean.GrayLineBean
import com.mogo.och.taxi.bean.QueryGrayContrailListRsp
import com.mogo.och.taxi.bean.StartGrayAndQueryContrailRsp
import com.mogo.och.taxi.bean.SubmitGrayLineIssueLocationReq
import com.mogo.och.taxi.callback.ITaxiControllerStatusCallback
import com.mogo.och.taxi.callback.ITaxiOrderStatusCallback
import com.mogo.och.taxi.callback.ITaxiRoutingCallback
import com.mogo.och.taxi.constant.TaxiUnmannedConst
import com.mogo.och.taxi.network.TaxiRoutingServiceManager
import com.mogo.och.taxi.ui.debug.DebugView
import java.util.concurrent.ConcurrentHashMap
object TaxiRoutingModel {
private val TAG = SceneConstant.M_TAXI + TaxiRoutingModel::class.java.simpleName
private val mContext: Context
get() = AbsMogoApplication.getApp().applicationContext
private var currentGrayLineBean: GrayLineBean? = null
private var currentContrailBean: ContrailBean? = null
private val mTaxiRoutingCallbackMap: ConcurrentHashMap<String, ITaxiRoutingCallback> =
ConcurrentHashMap()
fun addTaxiRoutingListener(tag: String, listener: ITaxiRoutingCallback) {
if (mTaxiRoutingCallbackMap.containsKey(tag)) {
return
}
mTaxiRoutingCallbackMap[tag] = listener
}
fun removeTaxiRoutingListener(tag: String) {
if (!mTaxiRoutingCallbackMap.containsKey(tag)) {
return
}
mTaxiRoutingCallbackMap.remove(tag)
}
private var mControllerStatusCallback: ITaxiControllerStatusCallback? = null
fun setControllerStatusCallback(callback: ITaxiControllerStatusCallback?) {
mControllerStatusCallback = callback
}
private var mOrderStatusCallback: ITaxiOrderStatusCallback? = null
fun setOrderStatusCallback(callback: ITaxiOrderStatusCallback?) {
mOrderStatusCallback = callback
}
fun queryRoutingGrayLineList() {
DebugView.printInfoMsg("[查询灰度路线] 准备发送请求sn=${MoGoAiCloudClientConfig.getInstance().sn}")
TaxiRoutingServiceManager.queryRoutingGrayLineList(mContext,
object : OchCommonServiceCallback<QueryGrayContrailListRsp> {
override fun onSuccess(data: QueryGrayContrailListRsp) {
CallerLogger.d(
TAG,
"queryRoutingGrayLineList onSuccess: data=${GsonUtils.toJson(data)}"
)
DebugView.printInfoMsg("[查询灰度路线] 请求successdataSize=${data?.data?.size}")
val result = mutableListOf<GrayLineBean>()
data.data?.also {
result.addAll(it)
}
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onQueryRoutingGrayLineListSuccess(result)
}
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"queryRoutingGrayLineList onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[查询灰度路线] 请求fail, code=$code, msg=$msg, sn=${MoGoAiCloudClientConfig.getInstance().sn}")
ToastUtils.showShort("查询灰度线路列表异常, 请稍后重试, code=$code")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onQueryRoutingGrayLineListFailed(
msg ?: "查询灰度线路列表异常, 请稍后重试"
)
}
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(mContext)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "查询灰度线路列表异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"queryRoutingGrayLineList onError, msg=$hintStr, sn=${MoGoAiCloudClientConfig.getInstance().sn}"
)
DebugView.printErrorMsg("[查询灰度路线] 请求error, msg=$hintStr")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onQueryRoutingGrayLineListFailed(hintStr)
}
}
})
}
fun startGrayTaskAndQueryRoutingContrail(contrailId: Long, grayLineBean: GrayLineBean) {
DebugView.printInfoMsg("[开始灰度任务&查询轨迹详情] 准备发送请求contrailId=${contrailId}, lineId=${grayLineBean.lineId}")
TaxiRoutingServiceManager.startGrayTaskAndQueryRoutingContrail(
mContext,
sn = MoGoAiCloudClientConfig.getInstance().sn,
contrailId = contrailId,
grayLineBean = grayLineBean,
object : OchCommonServiceCallback<StartGrayAndQueryContrailRsp> {
override fun onSuccess(data: StartGrayAndQueryContrailRsp) {
CallerLogger.d(
TAG,
"startGrayTaskAndQueryRoutingContrail onSuccess: data=${
GsonUtils.toJson(
data
)
}"
)
DebugView.printInfoMsg("[开始灰度任务&查询轨迹详情] 请求successtaskId=${data.taskId}, contrailId=${contrailId}, lineId=${grayLineBean.lineId}")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onStartGrayTaskAndQueryContrailSuccess(data)
}
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"startGrayTaskAndQueryRoutingContrail onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[开始灰度任务&查询轨迹详情] 请求fail, code=$code, msg=$msg, contrailId=${contrailId}, lineId=${grayLineBean.lineId}")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onStartGrayTaskAndQueryContrailFailed(
msg ?: "startGrayTaskAndQueryRoutingContrail onFail"
)
}
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(mContext)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "开始任务并查询轨迹详情异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"startGrayTaskAndQueryRoutingContrail onError, msg=$hintStr, contrailId=${contrailId}, lineId=${grayLineBean.lineId}"
)
DebugView.printErrorMsg("[开始灰度任务&查询轨迹详情] 请求error, msg=$hintStr")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onStartGrayTaskAndQueryContrailFailed(hintStr)
}
}
}
)
}
fun submitGrayLineIssueLocation(grayId: Long, gcjLon: Double, gcjLat: Double) {
DebugView.printInfoMsg("[上报打点] 准备发送请求grayId=$grayId, gcjLon=$gcjLon, gcjLat=$gcjLat")
val submit = SubmitGrayLineIssueLocationReq(grayId, gcjLon, gcjLat)
TaxiRoutingServiceManager.submitGrayLineIssueLocation(
mContext,
submit,
object : OchCommonServiceCallback<BaseData> {
override fun onSuccess(data: BaseData?) {
CallerLogger.d(
TAG,
"submitGrayLineIssueLocation onSuccess: data=${
GsonUtils.toJson(
data
)
}"
)
DebugView.printInfoMsg("[上报打点] 准备successgrayId=$grayId, gcjLon=$gcjLon, gcjLat=$gcjLat")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitGrayLineIssueLocationSuccess()
}
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"submitGrayLineIssueLocation onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[上报打点] 请求fail, code=$code, msg=$msg, grayId=$grayId")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitGrayLineIssueLocationFailed(
msg ?: "submitGrayLineIssueLocation onFail"
)
}
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(mContext)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "上报问题打点异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"submitGrayLineIssueLocation onError, msg=$hintStr"
)
DebugView.printErrorMsg("[上报打点] 请求error, msg=$hintStr, grayId=$grayId")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitGrayLineIssueLocationFailed(hintStr)
}
}
}
)
}
fun endGrayTask(grayId: Long, type: EndGrayTaskFeedbackType) {
DebugView.printInfoMsg("[结束灰度任务] 准备发送请求grayId=$grayId type=${type.type}, typeName=${type.name}")
val submit = EndGrayContrailTaskReq(grayId, type.type)
TaxiRoutingServiceManager.endGrayTask(
mContext,
submit,
object : OchCommonServiceCallback<BaseData> {
override fun onSuccess(data: BaseData?) {
CallerLogger.d(
TAG,
"endGrayTask onSuccess: data=${
GsonUtils.toJson(
data
)
}"
)
DebugView.printInfoMsg("[结束灰度任务] 请求successgrayId=$grayId type=${type.type}, typeName=${type.name}")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitEndTaskSuccess()
}
}
override fun onFail(code: Int, msg: String?) {
CallerLogger.d(
TAG,
"endGrayTask onFail: code=$code, msg=$msg"
)
DebugView.printErrorMsg("[结束灰度任务] 请求fail, code=$code, msg=$msg, grayId=$grayId type=${type.type}, typeName=${type.name}")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitEndTaskFailed(
msg ?: "endGrayTask onFail"
)
}
}
override fun onError() {
super.onError()
var hintStr = ""
if (!NetworkUtils.isConnected(mContext)) {
hintStr = "网络出现异常,请稍后重试"
} else {
hintStr = "上报结束任务异常, 请稍后重试"
}
CallerLogger.d(
TAG,
"endGrayTask onError, msg=$hintStr"
)
DebugView.printErrorMsg("[结束灰度任务] 请求error, msg=$hintStr, grayId=$grayId type=${type.type}, typeName=${type.name}")
mTaxiRoutingCallbackMap.forEach {
val listener = it.value
listener.onSubmitEndTaskFailed(hintStr)
}
}
})
}
fun updateCurrentGrayLineAndContrail(grayLineBean: GrayLineBean?, contrailBean: ContrailBean?) {
currentGrayLineBean = grayLineBean
currentContrailBean = contrailBean
}
fun startAutoPilotByClick() {
if (currentGrayLineBean == null || currentContrailBean == null) {
CallerLogger.e(TAG, "startAutoPilotByClick 异常currentGrayLineBean == null || currentContrailBean == null")
DebugView.printErrorMsg("[启自驾] startAutoPilotByClick 异常currentGrayLineBean == null || currentContrailBean == null")
return
}
startAutoPilot(currentGrayLineBean!!, currentContrailBean!!)
}
fun startAutoPilot(grayLineBean: GrayLineBean, contrailBean: ContrailBean) {
if (grayLineBean.startSite == null || grayLineBean.endSite == null) {
CallerLogger.e(TAG, "start site or end site is null")
DebugView.printErrorMsg("[启自驾] 当前订单不存在或异常!")
ToastUtils.showShort("当前订单不存在或异常!")
return
}
//根据开关和后台是否发布轨迹启动自驾
if (FunctionBuildConfig.isPassStartAutopilotCommand && TextUtils.isEmpty(
contrailBean.csvFileUrl
)
) {
ToastUtils.showLong("无发布轨迹, 请发布后重试")
DebugView.printErrorMsg("[启自驾] 无发布轨迹, 请发布后重试")
CallerLogger.e(
TAG, "isPassStartAutopilotCommand = " +
FunctionBuildConfig.isPassStartAutopilotCommand
+ "busRoutesResult.csvFileUrl = " + contrailBean.csvFileUrl
)
return
}
if (!FunctionBuildConfig.isDemoMode && !OCHAdasAbilityManager.getInstance().autopilotAbilityStatus) {
DebugView.printErrorMsg("[启自驾] ${OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason}")
ToastUtils.showLong(
OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason +
", 请稍候重试"
)
return
}
val parameters = initAutopilotControlParameters(grayLineBean, contrailBean)
if (null == parameters) {
CallerLogger.e(TAG, "AutopilotControlParameters is empty.")
return
}
CallerAutoPilotControlManager.startAutoPilot(parameters)
DebugView.printInfoMsg("[启自驾] 调用成功")
CallerLogger.d(
TAG, "start autopilot with parameter: %s",
GsonUtil.jsonFromObject(parameters)
)
mControllerStatusCallback?.startOpenAutopilot()
}
private fun initAutopilotControlParameters(
grayLineBean: GrayLineBean,
contrailBean: ContrailBean
): AutopilotControlParameters? {
val parameters = AutopilotControlParameters()
val startWgsLon = grayLineBean.startSite!!.wgs84Lon
val startWgsLat = grayLineBean.startSite!!.wgs84Lat
val endWgsLon = grayLineBean.endSite!!.wgs84Lon
val endWgsLat = grayLineBean.endSite!!.wgs84Lat
parameters.vehicleType = TaxiUnmannedConst.BUSINESSTYPE
parameters.startName =
grayLineBean.startSite!!.siteName // 8.10 拼音首字母大写 改为直接传中文
parameters.endName =
grayLineBean.endSite!!.siteName // 8.10 拼音首字母大写 改为直接传中文
parameters.startLatLon =
AutopilotControlParameters.AutoPilotLonLat(startWgsLat, startWgsLon)
parameters.endLatLon = AutopilotControlParameters.AutoPilotLonLat(endWgsLat, endWgsLon)
if (parameters.autoPilotLine == null) {
parameters.autoPilotLine = AutopilotControlParameters.AutoPilotLine(
contrailBean.lineId,
contrailBean.lineName,
contrailBean.csvFileUrl,
contrailBean.csvFileMd5,
contrailBean.txtFileUrl,
contrailBean.txtFileMd5,
contrailBean.contrailSaveTime,
TaxiUnmannedConst.BUSINESSTYPE.toString(),
contrailBean.csvFileUrlDPQP,
contrailBean.csvFileMd5DPQP,
contrailBean.txtFileUrlDPQP,
contrailBean.txtFileMd5DPQP,
contrailBean.contrailSaveTimeDPQP
)
}
return parameters
}
/**
* 显示/隐藏 前往任务目的地的导航
*
* @param isShow
*/
fun startNaviToEndStationByAMap(isShow: Boolean) {
mOrderStatusCallback?.onNaviToEnd(true, isShow)
}
}

View File

@@ -0,0 +1,34 @@
package com.mogo.och.taxi.ui.routing
import com.mogo.och.taxi.base.IUiIntent
import com.mogo.och.taxi.bean.EndGrayTaskFeedbackType
import com.mogo.och.taxi.bean.GrayLineBean
sealed class TaxiRoutingUiIntent : IUiIntent {
//打开选择路线页面
data class StartChooseLineAction(val currentTimestamp: Long) : TaxiRoutingUiIntent()
//查询灰度线路列表
data class QueryRoutingGrayLineList(val currentTimestamp: Long) : TaxiRoutingUiIntent()
//开始一个任务并查询此任务对应的轨迹详情
data class StartTaskAndQueryContrail(val grayLineBean: GrayLineBean) : TaxiRoutingUiIntent()
//展示Routing任务信息
data class ShowRoutingTask(val routingTask: RoutingUIState.RoutingTask) :
TaxiRoutingUiIntent()
//开始任务
data class StartTaskAction(val routingTask: RoutingUIState.RoutingTask) : TaxiRoutingUiIntent()
//问题打点
data class SubmitGrayLineIssueLocation(val grayId: Long) : TaxiRoutingUiIntent()
//展示结束任务反馈弹框
data class ShowFeedbackDialog(val grayId: Long) : TaxiRoutingUiIntent()
//结束任务
data class SubmitEndTask(val grayId: Long, val type: EndGrayTaskFeedbackType) :
TaxiRoutingUiIntent()
}

View File

@@ -0,0 +1,33 @@
package com.mogo.och.taxi.ui.routing
import com.mogo.och.taxi.base.IUiState
import com.mogo.och.taxi.bean.ContrailBean
import com.mogo.och.taxi.bean.GrayLineBean
data class TaxiRoutingUiState(val routingUiState: RoutingUIState) : IUiState
sealed class RoutingUIState {
object Init : RoutingUIState()
data class ShowGrayLineList(var data: MutableList<GrayLineBean>) : RoutingUIState()
data class HideChooseLineLoading(var isCosePage: Boolean) : RoutingUIState()
data class PostRoutingTaskResult(
val grayLineBean: GrayLineBean?,
val contrailBean: ContrailBean?,
val grayId: Long?
) : RoutingUIState()
data class RoutingTask(
val grayLineBean: GrayLineBean?,
val contrailBean: ContrailBean?,
val grayId: Long?
) : RoutingUIState()
data class ShowFinishTaskButton(val routingTask: RoutingTask) : RoutingUIState()
data class ShowFeedbackDialog(val grayId: Long, val currentTimestamp: Long) : RoutingUIState()
object DismissFeedbackDialog : RoutingUIState()
}

View File

@@ -1,6 +1,7 @@
package com.mogo.och.taxi.ui.task
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.eagle.core.data.BaseData
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.map.MogoLocation
@@ -229,6 +230,12 @@ class TaxiCurrentTaskViewModel : BaseViewModel<UnmannedState, TaskUiIntent>(),
d(TAG, "onTaskWithOrderChanged = result = " + GsonUtil.jsonFromObject(result))
DebugView.printInfoMsg("[查询TaskWithOrder信息] 更新数据, 刷新UI")
updateTaskAndOrderUi(result)
// 设置task执行相关状态切换模式时判断使用
if (result == null || result.taskType == TaskTypeEnum.None.code) {
MogoStatusManager.getInstance().setTaxiUnmanedDriverPerformTask(TAG, false)
} else {
MogoStatusManager.getInstance().setTaxiUnmanedDriverPerformTask(TAG, true)
}
}
override fun onTaskStarted(result: QueryCurrentTaskRespBean.Result?) {
@@ -318,6 +325,8 @@ class TaxiCurrentTaskViewModel : BaseViewModel<UnmannedState, TaskUiIntent>(),
VoiceNotice.showNotice("已取消行程")
//取消自驾,D档位会溜车 map3.6.0 修改
TaxiTaskModel.cancelAutopilot()
// 设置task执行相关状态切换模式时判断使用
MogoStatusManager.getInstance().setTaxiUnmanedDriverPerformTask(TAG, false)
}
override fun onOrderArriveAtEnd(orderNo: String) {
@@ -339,6 +348,8 @@ class TaxiCurrentTaskViewModel : BaseViewModel<UnmannedState, TaskUiIntent>(),
TaxiTaskModel.startPrepareTaskDelay(CallerUnmannedListenerManager.getVirtualTaskPullTaskInterval() * 1000L,
it.siteId)
}
// 设置task执行相关状态切换模式时判断使用
MogoStatusManager.getInstance().setTaxiUnmanedDriverPerformTask(TAG, false)
}
override fun onStartAutopilot(postDelayTime: Long) {

View File

@@ -33,7 +33,11 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.e
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.i
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.eagle.core.utilcode.util.CoordinateUtils
import com.mogo.eagle.core.utilcode.util.DrivingDirectionUtils
import com.mogo.eagle.core.utilcode.util.NetworkUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager
import com.mogo.och.common.module.biz.common.socketmessage.data.OCHOperationalMessage
import com.mogo.och.common.module.biz.constant.LoginStatusManager
@@ -50,9 +54,22 @@ import com.mogo.och.common.module.manager.distancemamager.TrajectoryAndDistanceM
import com.mogo.och.common.module.map.AmapNaviToDestinationModel
import com.mogo.och.common.module.utils.CoordinateCalculateRouteUtil.coordinateConverterWgsToGcjLocations
import com.mogo.och.common.module.voice.VoiceNotice
import com.mogo.och.taxi.bean.*
import com.mogo.och.taxi.callback.*
import com.mogo.och.taxi.constant.*
import com.mogo.och.taxi.bean.PrepareTaskRespBean
import com.mogo.och.taxi.bean.QueryCarOrderByNoRespBean
import com.mogo.och.taxi.bean.QueryCurrentTaskRespBean
import com.mogo.och.taxi.bean.StartServiceRespBean
import com.mogo.och.taxi.bean.TrajectoryListRespBean
import com.mogo.och.taxi.callback.IOCHTaxiAutopilotPlanningCallback
import com.mogo.och.taxi.callback.ITaxiADASStatusCallback
import com.mogo.och.taxi.callback.ITaxiCarServiceCallback
import com.mogo.och.taxi.callback.ITaxiControllerStatusCallback
import com.mogo.och.taxi.callback.ITaxiOrderStatusCallback
import com.mogo.och.taxi.callback.ITaxiTaskWithOrderCallback
import com.mogo.och.taxi.constant.TaskStatusEnum
import com.mogo.och.taxi.constant.TaskTypeEnum
import com.mogo.och.taxi.constant.TaxiCarServingStatusManager
import com.mogo.och.taxi.constant.TaxiOrderStatusEnum
import com.mogo.och.taxi.constant.TaxiUnmannedConst
import com.mogo.och.taxi.constant.TaxiUnmannedConst.Companion.BUSINESSTYPE
import com.mogo.och.taxi.network.TaxiTaskWithOrderServiceManager
import com.mogo.och.taxi.ui.debug.DebugView
@@ -1424,6 +1441,10 @@ object TaxiTaskModel {
mCurrentTaskWithOrder = null
mDriveToNearestStationTask = null
DebugView.printInfoMsg("[登出] 退出登陆")
MogoStatusManager.getInstance().setTaxiUnmanedDriverPerformTask(TAG, false)
MogoStatusManager.getInstance().setTaxiUnmanedDriverTakingOrders(TAG, false)
MogoStatusManager.getInstance().setTaxiUnmanedDriverLineRoutingPerformTask(TAG, false)
MogoStatusManager.getInstance().setTaxiUnmanedDriverLineRoutingVerifyMode(TAG, false)
}
//导航去订单终点目的地

View File

@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/taxi_autopilot_text_color_normal"/>
<item android:color="@color/taxi_autopilot_text_color_normal" android:state_enabled="true"/>
<item android:color="@color/taxi_autopilot_text_color_disable" android:state_enabled="false"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#2A537F" android:endColor="#263A5B" android:angle="135"/>
</shape>

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#2A4A7A" />
<corners android:bottomLeftRadius="@dimen/dp_45" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle">
<gradient android:startColor="#20AAFF" android:endColor="#2F6EFF" android:angle="315"/>
<corners android:bottomLeftRadius="@dimen/dp_45" android:bottomRightRadius="@dimen/dp_45"/>
</shape>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:angle="180"
android:endColor="#2F6EFF"
android:startColor="#20AAFF" />
<corners android:bottomRightRadius="@dimen/dp_45" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/routing_btn_left_pressed" android:state_pressed="true" /> <!-- pressed -->
<item android:drawable="@drawable/routing_btn_left_default" /> <!-- default -->
</selector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/routing_btn_right_pressed" android:state_pressed="true" /> <!-- pressed -->
<item android:drawable="@drawable/routing_btn_right_default" /> <!-- default -->
</selector>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/routing_choose_line_btn_submit_bg_pressed" android:state_pressed="true" /> <!-- pressed -->
<item android:drawable="@drawable/routing_choose_line_btn_submit_bg_default" /> <!-- default -->
</selector>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="24dp" />
<gradient
android:angle="0"
android:endColor="#0056FF"
android:startColor="#029DFF"
android:type="linear" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="24dp" />
<gradient
android:angle="0"
android:endColor="#800056FF"
android:startColor="#80029DFF"
android:type="linear" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:endColor="#660043FF"
android:startColor="#0028345E" />
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<gradient
android:endColor="#CC0043FF"
android:startColor="#0028345E" />
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/routing_click_btn_bg_pressed" android:state_pressed="true" /> <!-- pressed -->
<item android:drawable="@drawable/routing_click_btn_bg_default" /> <!-- default -->
</selector>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="@color/routing_verify_click_btn_color" />
<corners
android:bottomLeftRadius="42dp"
android:bottomRightRadius="42dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp" />
</shape>

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid
android:color="@color/routing_verify_click_btn_pressed_color" />
<corners
android:bottomLeftRadius="42dp"
android:bottomRightRadius="42dp"
android:topLeftRadius="0dp"
android:topRightRadius="0dp" />
</shape>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@drawable/taxi_out_btn_disable"
android:width="@dimen/dp_50"
android:height="@dimen/dp_50"/>
</layer-list >

View File

@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="54dp" />
<gradient
android:startColor="#80323C6F"
android:endColor="#80323C6F"
android:angle="315"
/>
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/taxi_operation_status_bg_disabled" android:state_enabled="false" />
<item android:drawable="@drawable/taxi_operation_status_bg" android:state_enabled="true"/>
</selector>

View File

@@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<corners android:radius="42dp"/>
<gradient
android:angle="315"
android:type="linear"
android:startColor="#E6687FDC"
android:endColor="#E62C387D" /> <!-- #00344180-->
</shape>
</item>
<item
android:left="4dp"
android:top="4dp"
android:bottom="4dp"
android:right="4dp">
<shape android:shape="rectangle">
<corners android:radius="42dp"/>
<gradient
android:type="linear"
android:startColor="#80435AB2"
android:endColor="#802C387D"
android:angle="315" />
</shape>
</item>
</layer-list>

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.och.common.module.wigets.OCHRoundConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/dp_800"
android:layout_height="@dimen/dp_500"
android:background="@drawable/bg_shape_dialog_no_title"
app:roundLayoutRadius="@dimen/dp_45">
<ImageView
android:id="@+id/closeDialogIcon"
android:layout_width="@dimen/dp_80"
android:layout_height="@dimen/dp_80"
android:layout_marginTop="@dimen/dp_5"
android:layout_marginEnd="@dimen/dp_5"
android:src="@drawable/taxi_close_navi_icon"
android:visibility="visible"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/routing_common_tips"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_marginStart="@dimen/dp_80"
android:layout_marginEnd="@dimen/dp_80"
android:gravity="center"
android:text="@string/routing_feedback_result_hint"
android:textColor="#FFFFFFFF"
android:textSize="@dimen/dp_56"
app:layout_constraintBottom_toTopOf="@+id/routing_common_cancel"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/routing_common_cancel"
android:layout_width="0dp"
android:layout_height="134dp"
android:background="@drawable/bg_shape_left_bottom_round"
android:gravity="center"
android:text="@string/routing_feedback_result_btn_not_sure"
android:textColor="#FFFFFFFF"
android:textSize="@dimen/dp_50"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintWidth_percent="0.5" />
<TextView
android:id="@+id/routing_common_confirm"
android:layout_width="0dp"
android:layout_height="134dp"
android:background="@drawable/bg_shape_right_bottom_round"
android:gravity="center"
android:text="@string/routing_feedback_result_btn_sure"
android:textColor="#FFFFFFFF"
android:textSize="@dimen/dp_50"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintStart_toEndOf="@+id/routing_common_cancel"
app:layout_constraintWidth_percent="0.5" />
</com.mogo.och.common.module.wigets.OCHRoundConstraintLayout>

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="@dimen/dp_300"
android:layout_height="@dimen/dp_300"
android:orientation="vertical"
android:gravity="center"
android:layout_gravity="center">
<ImageView
android:id="@+id/dialog_loading_view"
android:layout_width="@dimen/dp_80"
android:layout_height="@dimen/dp_80"
android:src="@drawable/routing_loading_nor" />
<TextView
android:id="@+id/dialog_loading_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="请求中,请稍后..."
android:textColor="#CCFFFFFF"
android:layout_marginTop="@dimen/dp_10"/>
</LinearLayout>

View File

@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:paddingStart="@dimen/dp_78"
android:paddingEnd="@dimen/dp_78"
android:layout_marginTop="@dimen/dp_8"
android:background="@drawable/routing_choose_line_shape_select_line_item_bg_normal"
android:orientation="vertical">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/switchLineNameTextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_20"
android:layout_marginEnd="@dimen/dp_20"
android:ellipsize="end"
android:gravity="left|center_vertical"
android:maxLines="1"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_44"
tools:text="线路名称线路名称线路" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginTop="@dimen/dp_20"
android:layout_marginEnd="@dimen/dp_20">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/todayVerifyNumTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:gravity="left|center_vertical"
android:maxLines="1"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_34"
tools:text="本车今日已验证1次" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/historyVerifyNumTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_toRightOf="@+id/todayVerifyNumTextView"
android:gravity="right|center_vertical"
android:maxLines="1"
android:textColor="@color/taxi_color_ccb9c3e9"
android:textSize="@dimen/dp_30"
tools:text="路线累计反馈0可用1不可用" />
</RelativeLayout>
</LinearLayout>

View File

@@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/routing_verify_choose_line_bg"
tools:ignore="MissingDefaultResource">
<View
android:id="@+id/chooseLineHint"
android:layout_width="@dimen/dp_14"
android:layout_height="@dimen/dp_50"
android:layout_marginStart="@dimen/dp_80"
android:background="@color/routing_verify_choose_line"
app:layout_constraintBottom_toBottomOf="@+id/chooseLineHeaderTitle"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="@+id/chooseLineHeaderTitle" />
<TextView
android:id="@+id/chooseLineHeaderTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="@dimen/dp_113"
android:layout_marginTop="@dimen/dp_97"
android:text="@string/routing_verify_choose_line_title"
android:textColor="@android:color/white"
android:textSize="@dimen/taxi_routing_choose_line_title"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/btnClose"
android:layout_width="@dimen/dp_107"
android:layout_height="@dimen/dp_107"
android:layout_marginTop="@dimen/dp_67"
android:layout_marginRight="@dimen/dp_40"
android:src="@drawable/routing_choose_line_close"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/chooseLineListView"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_0"
android:layout_marginTop="@dimen/dp_50"
android:layout_marginBottom="@dimen/dp_30"
app:layout_constraintBottom_toTopOf="@+id/btnChooseLineSubmit"
app:layout_constraintLeft_toLeftOf="@+id/chooseLineHint"
app:layout_constraintTop_toBottomOf="@+id/chooseLineHint" />
<TextView
android:id="@+id/btnChooseLineSubmit"
android:layout_width="match_parent"
android:layout_height="126dp"
android:layout_marginStart="@dimen/dp_80"
android:layout_marginEnd="@dimen/dp_80"
android:layout_marginBottom="@dimen/taxi_choose_line_btn_margin_b"
android:background="@drawable/routing_choose_line_btn_submit_bg"
android:gravity="center"
android:text="@string/routing_verify_choose_line_btn_txt"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_42"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent" />
<include
layout="@layout/routing_no_data_common_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,277 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="@dimen/module_och_taxi_panel_width"
android:layout_height="@dimen/taxi_routing_verify_view_height"
android:background="@drawable/taxi_routing_bg"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/headerTitleContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:visibility="gone"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.mogo.och.common.module.wigets.MarqueeTextView
android:id="@+id/taskTitleTv"
android:layout_width="@dimen/dp_420"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_45"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="路线name路线name"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_46"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<View
android:id="@+id/module_och_taxi_order_status_divider"
android:layout_width="match_parent"
android:layout_height="4dp"
android:layout_marginTop="@dimen/dp_45"
android:background="@drawable/taxi_line_bg1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/taskTitleTv"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/headerTitleContainer">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/bottomBtnContainer"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/btnChooseTask"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_132"
android:background="@drawable/routing_click_btn_bg"
android:gravity="center"
android:text="@string/routing_verify_btn_choose_task"
android:textColor="#FFFFFF"
android:textSize="@dimen/dp_44"
app:layout_constraintBottom_toBottomOf="parent"
tools:visibility="gone" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/btnStartTask"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_132"
android:background="@drawable/routing_click_btn_bg"
android:gravity="center"
android:text="@string/routing_verify_btn_start_task"
android:textColor="#FFFFFF"
android:textSize="@dimen/dp_44"
app:layout_constraintBottom_toBottomOf="parent"
tools:visibility="gone" />
<TextView
android:id="@+id/btnFinishTask"
android:layout_width="0dp"
android:layout_height="@dimen/dp_116"
android:layout_weight="1"
android:background="@drawable/routing_btn_bg_finish_task"
android:gravity="center"
android:text="结束任务"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_44"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintWidth_percent="0.55" />
<TextView
android:id="@+id/btnSummitIssue"
android:layout_width="0dp"
android:layout_height="@dimen/dp_116"
android:layout_weight="1"
android:background="@drawable/routing_btn_bg_submit_issue"
android:gravity="center"
android:text="问题打点"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_44"
android:visibility="visible"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintWidth_percent="0.55" />
<androidx.constraintlayout.widget.Group
android:id="@+id/finishSubmitIssueGroup"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:constraint_referenced_ids="btnFinishTask,btnSummitIssue"
tools:visibility="visible" />
</androidx.constraintlayout.widget.ConstraintLayout>
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/mCurrentTaskLayout"
android:layout_width="@dimen/module_och_taxi_panel_width"
android:layout_height="0dp"
android:visibility="gone"
app:layout_constraintBottom_toTopOf="@+id/bottomBtnContainer"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/taskHintTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_40"
android:layout_marginTop="@dimen/dp_54"
android:text="当前任务"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_34"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/startStationTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="@dimen/dp_78"
android:layout_marginTop="@dimen/dp_30"
android:text="上车:"
android:textColor="@color/station_tag_color"
android:textSize="@dimen/dp_32"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/taskHintTextView"
app:layout_goneMarginTop="@dimen/dp_68" />
<com.mogo.och.common.module.wigets.MarqueeTextView
android:id="@+id/startStationName"
android:layout_width="@dimen/dp_366"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_12"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="始发站"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_44"
app:layout_constraintLeft_toLeftOf="@+id/startStationTag"
app:layout_constraintTop_toBottomOf="@+id/startStationTag" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/naviToStart"
android:layout_width="@dimen/dp_48"
android:layout_height="@dimen/dp_48"
android:layout_marginEnd="@dimen/dp_40"
android:src="@drawable/taxi_navi_icon"
app:layout_constraintBottom_toBottomOf="@id/startStationName"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/startStationName"
app:layout_goneMarginEnd="@dimen/dp_40" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/naviToEnd"
android:layout_width="@dimen/dp_48"
android:layout_height="@dimen/dp_48"
android:layout_marginEnd="@dimen/dp_40"
android:src="@drawable/taxi_navi_icon"
app:layout_constraintBottom_toBottomOf="@id/endStationName"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="@+id/endStationName"
app:layout_goneMarginEnd="@dimen/dp_40" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/endStationTag"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_52"
android:text="下车:"
android:textColor="@color/station_tag_color"
android:textSize="@dimen/dp_32"
app:layout_constraintStart_toStartOf="@+id/startStationTag"
app:layout_constraintTop_toBottomOf="@+id/startStationName" />
<com.mogo.och.common.module.wigets.MarqueeTextView
android:id="@+id/endStationName"
android:layout_width="@dimen/dp_366"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_12"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:singleLine="true"
android:text="终点站"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_44"
app:layout_constraintLeft_toLeftOf="@+id/startStationTag"
app:layout_constraintTop_toBottomOf="@+id/endStationTag" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/startPoint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/taxi_driver_circle_green_big"
app:layout_constraintBottom_toBottomOf="@+id/startStationName"
app:layout_constraintLeft_toLeftOf="@+id/taskHintTextView"
app:layout_constraintTop_toTopOf="@+id/startStationName" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/taper"
android:layout_width="wrap_content"
android:layout_height="0dp"
android:scaleType="fitXY"
android:src="@drawable/taxi_grab_dot_line"
app:layout_constraintBottom_toTopOf="@+id/endPoint"
app:layout_constraintLeft_toLeftOf="@+id/startPoint"
app:layout_constraintRight_toRightOf="@+id/startPoint"
app:layout_constraintTop_toBottomOf="@+id/startPoint" />
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/endPoint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/taxi_driver_circle_blue_big"
app:layout_constraintBottom_toBottomOf="@+id/endStationName"
app:layout_constraintLeft_toLeftOf="@+id/taskHintTextView"
app:layout_constraintTop_toTopOf="@+id/endStationName" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/taskTripInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_30"
android:layout_marginBottom="36dp"
android:text="距离 -- 公里, 用时 -- 分钟"
android:textColor="@color/station_tag_color"
android:textSize="@dimen/dp_30"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="@+id/endPoint"
app:layout_constraintTop_toBottomOf="@+id/endStationName" />
</androidx.constraintlayout.widget.ConstraintLayout>
<include
android:id="@+id/noDataContainer"
layout="@layout/routing_no_data_common_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:visibility="visible"
app:layout_constraintBottom_toTopOf="@+id/bottomBtnContainer"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="@+id/noDataContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@+id/bottomBtnContainer"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent">
<ImageView
android:id="@+id/no_routing_data_iv"
android:layout_width="@dimen/dp_386"
android:layout_height="@dimen/dp_350"
android:src="@drawable/no_order_data"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/noRoutingTaskDataTv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="暂无任务"
android:textColor="#91A1EA"
android:textSize="@dimen/dp_30"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/no_routing_data_iv" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -232,7 +232,7 @@
android:layout_height="102dp"
android:layout_marginLeft="48dp"
android:layout_marginBottom="@dimen/module_mogo_och_margin_bottom"
android:background="@drawable/taxi_operation_status_bg"
android:background="@drawable/taxi_operation_status_bg_selector_new"
android:drawableLeft="@drawable/shape_size_operation_out"
android:drawablePadding="10dp"
android:elevation="@dimen/dp_10"

View File

@@ -1,13 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/orderDebugContainer"
android:layout_width="wrap_content"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RelativeLayout
<TextView
android:id="@+id/currentBusinessModeTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
android:layout_height="wrap_content"
android:text="当前业务模式:"
android:textColor="@android:color/white"
android:textSize="@dimen/dp_24" />
<RelativeLayout
android:id="@+id/unmanedTaskOrderContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10">
<LinearLayout
android:id="@+id/btnContainer"
@@ -77,6 +87,7 @@
</LinearLayout>
<LinearLayout
android:id="@+id/unmanedTaskOrderInfoDetailContainer"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
@@ -199,6 +210,7 @@
</RelativeLayout>
<TextView
android:id="@+id/debugLogTitleTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_10"

View File

@@ -28,5 +28,10 @@
<color name="station_tag_color">#CAD6FF</color>
<color name="go_to_station_color">#00FFF8</color>
<color name="task_click_btn_color">#1D5EF3</color>
<color name="routing_verify_click_btn_color">#1D5EF3</color>
<color name="routing_verify_click_btn_pressed_color">#801D5EF3</color>
<color name="routing_verify_choose_line_bg">#F7151D41</color>
<color name="routing_verify_choose_line">#2966EC</color>
<color name="taxi_color_ccb9c3e9">#CCB9C3E9</color>
<color name="taxi_color_4dffffff">#4Dffffff</color>
</resources>

View File

@@ -117,6 +117,9 @@
<dimen name="taxi_traffic_light_time_size">60dp</dimen>
<dimen name="taxi_passenger_txt_size">34dp</dimen>
<dimen name="taxi_debug_view_width">1000dp</dimen>
<dimen name="taxi_routing_verify_view_height">934dp</dimen>
<dimen name="taxi_routing_choose_line_title">46dp</dimen>
<dimen name="taxi_choose_line_btn_margin_b">50dp</dimen>
</resources>

View File

@@ -60,5 +60,19 @@
<string name="view_data">查看</string>
<string name="routing_verify_btn_choose_task">选择任务</string>
<string name="routing_verify_btn_start_task">开始任务</string>
<string name="routing_verify_choose_line_title">任务列表</string>
<string name="routing_verify_choose_line_btn_txt">确认</string>
<string name="routing_verify_choose_line_no_task">暂无任务</string>
<string name="routing_verify_choose_line_select_task">选择时间</string>
<string name="routing_verify_choose_line_name">路线: </string>
<string name="routing_verify_choose_line_start">起点: </string>
<string name="routing_verify_choose_line_end">终点:</string>
<string name="routing_verify_line_item_goto_end">往%1$s方向</string>
<string name="routing_feedback_result_btn_sure">线路可用</string>
<string name="routing_feedback_result_btn_not_sure">线路不可用</string>
<string name="routing_feedback_result_hint">路线验证结束啦!点击下方按钮反馈验证结果吧</string>
<!-- endregion -->
</resources>

View File

@@ -23,4 +23,25 @@
<style name="och_speed_style2">
<item name="android:textSize">32dp</item>
</style>
<style name="RoutingChooseLineDialogStyle" parent="Theme.AppCompat.Dialog">
<item name="theme">@android:style/Theme.Translucent</item>
<!--是否去除标题 -->
<item name="windowNoTitle">true</item>
<!-- 背景透明 -->
<item name="android:background">#00000000</item>
<item name="android:windowBackground">#00000000</item>
<!-- 没有windowActionBar-->
<item name="windowActionBar">false</item>
<item name="android:windowContentOverlay">@null</item>
<!-- 设置窗体外面允不允许点击-->
<item name="android:windowCloseOnTouchOutside">true</item>
<item name="android:windowFullscreen">true</item>
<item name="android:windowIsFloating">true</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowFrame">@null</item>
<item name="android:windowAnimationStyle">@android:style/Animation.Translucent</item>
<item name="android:backgroundDimEnabled">false</item>
</style>
</resources>

View File

@@ -2,30 +2,32 @@ package com.mogo.eagle.core.function.hmi.ui
import android.content.Context
import android.text.TextUtils
import android.view.*
import android.view.Gravity
import android.view.ViewGroup
import androidx.lifecycle.ProcessLifecycleOwner
import androidx.lifecycle.lifecycleScope
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.data.deva.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.biz.dispatch.DispatchAdasAutoPilotLocReceiverBean
import com.mogo.eagle.core.data.biz.notice.NoticeNormalData
import com.mogo.eagle.core.data.biz.notice.NoticeTrafficStylePushData
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HmiBuildConfig
import com.mogo.eagle.core.data.constants.MogoServicePaths.PATH_FRAGMENT_HMI
import com.mogo.eagle.core.data.deva.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.BIZ_RTS
import com.mogo.eagle.core.data.deva.bizconfig.FuncBizConfig.Companion.V2I
import com.mogo.eagle.core.data.biz.dispatch.DispatchAdasAutoPilotLocReceiverBean
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
import com.mogo.eagle.core.data.map.Infrastructure
import com.mogo.eagle.core.data.biz.notice.NoticeNormalData
import com.mogo.eagle.core.data.biz.notice.NoticeTrafficStylePushData
import com.mogo.eagle.core.data.config.HmiBuildConfig
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoHmiProvider
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
import com.mogo.eagle.core.function.call.hmi.*
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
import com.mogo.eagle.core.function.call.v2x.CallerTrafficLightListenerManager
import com.mogo.eagle.core.function.call.v2x.CallerTurnLightListenerManager
import com.mogo.eagle.core.function.hmi.ui.camera.RoadVideoDialog
import com.mogo.eagle.core.function.hmi.ui.lookaround.*
import com.mogo.eagle.core.function.hmi.ui.lookaround.M1LookAroundView
import com.mogo.eagle.core.function.hmi.ui.notice.DispatchDialogManager
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeCheckDialog
import com.mogo.eagle.core.function.hmi.ui.notice.traffic.NoticeTrafficDialog
@@ -38,15 +40,18 @@ import com.mogo.eagle.core.function.hmi.ui.tools.ToBindingCarDialog
import com.mogo.eagle.core.function.hmi.ui.tools.UpgradeAppDialog
import com.mogo.eagle.core.function.hmi.ui.utils.HmiActionLog
import com.mogo.eagle.core.function.hmi.ui.widget.StatusBarView
import com.mogo.eagle.core.utilcode.floating.*
import com.mogo.eagle.core.utilcode.floating.MoGoPopWindow
import com.mogo.eagle.core.utilcode.kotlin.safeCancel
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_HMI
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.eagle.core.utilcode.util.AppStateManager
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.tts.base.IMogoTTSCallback
import com.zhjt.service_biz.BizConfig
import kotlinx.coroutines.*
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicReference
@@ -352,4 +357,24 @@ class MoGoHmiProvider : IMoGoHmiProvider {
CallerTurnLightListenerManager.invokeHideTurnLightView()
}
override fun isTaxiUnmanedDriverPerformTask(): Boolean {
return MogoStatusManager.getInstance().isTaxiUnmanedDriverPerformTask
}
override fun isTaxiUnmanedDriverTakingOrders(): Boolean {
return MogoStatusManager.getInstance().isTaxiUnmanedDriverTakingOrders
}
override fun isTaxiUnmanedDriverLineRoutingPerformTask(): Boolean {
return MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingPerformTask
}
override fun isTaxiUnmanedDriverLineRoutingVerifyMode(): Boolean {
return MogoStatusManager.getInstance().isTaxiUnmanedDriverLineRoutingVerifyMode
}
override fun setTaxiUnmanedDriverLineRoutingVerifyMode(isMode: Boolean) {
MogoStatusManager.getInstance().setTaxiUnmanedDriverLineRoutingVerifyMode(TAG, isMode)
}
}

View File

@@ -553,6 +553,41 @@ internal class SOPSettingView @JvmOverloads constructor(
}
}
// Taxi无人化司机端自主算路验证模式
scLineRoutingVerify?.also {
if (AppIdentityModeUtils.isTaxiDriver(FunctionBuildConfig.appIdentityMode)) {
it.isEnabled = true
it.visibility = View.VISIBLE
it.setOnCheckedChangeListener { buttonView, isChecked ->
if(!buttonView.isPressed) return@setOnCheckedChangeListener
if (isChecked) {
if (CallerHmiManager.isTaxiUnmanedDriverPerformTask()) {
ToastUtils.showLong("请先结束当前任务")
buttonView.isChecked = !isChecked
return@setOnCheckedChangeListener
}
if (CallerHmiManager.isTaxiUnmanedDriverTakingOrders()) {
ToastUtils.showLong("请先结束接单状态")
buttonView.isChecked = !isChecked
return@setOnCheckedChangeListener
}
CallerHmiManager.setTaxiUnmanedDriverLineRoutingVerifyMode(true)
} else {
if (CallerHmiManager.isTaxiUnmanedDriverLineRoutingPerformTask()) {
ToastUtils.showLong("请先结束当前任务")
buttonView.isChecked = !isChecked
return@setOnCheckedChangeListener
}
CallerHmiManager.setTaxiUnmanedDriverLineRoutingVerifyMode(false)
}
}
it.isChecked = CallerHmiManager.isTaxiUnmanedDriverLineRoutingVerifyMode()
} else {
it.isEnabled = false
it.visibility = View.GONE
}
}
//是否展示被动触发的录包弹窗(自动驾驶下出现问题触发的录包)
scShowBagRecordWindow.isChecked = FunctionBuildConfig.isShowBagRecordWindow
scShowBagRecordWindow.setOnCheckedChangeListener { _, isChecked ->

View File

@@ -548,6 +548,19 @@
app:layout_constraintRight_toRightOf="@id/otherGuideLine"
app:layout_constraintTop_toBottomOf="@id/scIPCReport" />
<!--自主算路验证模式-->
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/scLineRoutingVerify"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_25"
android:scaleX="1.2"
android:scaleY="1.2"
android:text="自主算路验证模式"
app:layout_constraintLeft_toRightOf="@id/scShowBagRecordWindow"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@id/scIPCReport" />
<TextView
android:id="@+id/tvPullTimeTitle"
android:layout_width="wrap_content"
@@ -558,7 +571,7 @@
android:textColor="@color/black"
android:textSize="32dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/scShowBagRecordWindow" />
app:layout_constraintTop_toBottomOf="@id/scLineRoutingVerify" />
<RadioGroup
android:id="@+id/rgPullTime"

View File

@@ -169,4 +169,30 @@ interface IMoGoHmiProvider :IProvider{
* 隐藏转向灯
*/
fun hideTurnLightView()
/**
* taxi无人化 是否在执行任务中(无人化模式和算路验证模式 都复用此变量)
*/
fun isTaxiUnmanedDriverPerformTask(): Boolean
/**
* taxi无人化司机端 是否在接单中
*/
fun isTaxiUnmanedDriverTakingOrders(): Boolean
/**
* taxi自主算路验证 是否在执行任务中
*/
fun isTaxiUnmanedDriverLineRoutingPerformTask(): Boolean
/**
* taxi无人化司机端 是否自主算路验证模式
*/
fun isTaxiUnmanedDriverLineRoutingVerifyMode(): Boolean
/**
* taxi无人化司机端 设置是否自主算路验证模式
*/
fun setTaxiUnmanedDriverLineRoutingVerifyMode(isMode: Boolean)
}

View File

@@ -3,14 +3,14 @@ package com.mogo.eagle.core.function.call.hmi
import android.content.Context
import android.view.ViewGroup
import com.alibaba.android.arouter.launcher.ARouter
import com.mogo.eagle.core.data.deva.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.data.biz.dispatch.DispatchAdasAutoPilotLocReceiverBean
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
import com.mogo.eagle.core.data.map.Infrastructure
import com.mogo.eagle.core.data.biz.notice.NoticeNormalData
import com.mogo.eagle.core.data.biz.notice.NoticeTrafficStylePushData
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.data.deva.bindingcar.IPCUpgradeStateInfo
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
import com.mogo.eagle.core.data.enums.WarningDirectionEnum.ALERT_WARNING_NON
import com.mogo.eagle.core.data.map.Infrastructure
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoHmiProvider
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
@@ -252,4 +252,39 @@ object CallerHmiManager {
hmiProviderApi?.hideTurnLightView()
}
/**
* taxi无人化司机端 是否在执行任务中(无人化模式和算路验证模式 都复用此变量)
*/
fun isTaxiUnmanedDriverPerformTask() :Boolean {
return hmiProviderApi?.isTaxiUnmanedDriverPerformTask() ?: false
}
/**
* taxi无人化司机端 是否在接单中
*/
fun isTaxiUnmanedDriverTakingOrders() :Boolean {
return hmiProviderApi?.isTaxiUnmanedDriverTakingOrders() ?: false
}
/**
* taxi自主算路验证 是否在执行任务中
*/
fun isTaxiUnmanedDriverLineRoutingPerformTask() :Boolean {
return hmiProviderApi?.isTaxiUnmanedDriverLineRoutingPerformTask() ?: false
}
/**
* taxi无人化司机端 是否自主算路验证模式
*/
fun isTaxiUnmanedDriverLineRoutingVerifyMode() :Boolean {
return hmiProviderApi?.isTaxiUnmanedDriverLineRoutingVerifyMode() ?: false
}
/**
* taxi无人化司机端 设置是否自主算路验证模式
*/
fun setTaxiUnmanedDriverLineRoutingVerifyMode(isMode: Boolean) {
hmiProviderApi?.setTaxiUnmanedDriverLineRoutingVerifyMode(isMode)
}
}

View File

@@ -110,6 +110,46 @@ public interface IMogoStatusManager extends IProvider {
*/
void setSeekHelping( String tag, boolean seekHelping );
/**
* taxi无人化司机端 是否在执行任务中
*
* @param tag
* @param isPerformingTask
*/
void setTaxiUnmanedDriverPerformTask( String tag, boolean isPerformingTask );
boolean isTaxiUnmanedDriverPerformTask();
/**
* taxi无人化司机端 是否在接单中
*
* @param tag
* @param isTakingOrders
*/
void setTaxiUnmanedDriverTakingOrders( String tag, boolean isTakingOrders );
boolean isTaxiUnmanedDriverTakingOrders();
/**
* taxi自主算路验证 是否在执行任务中
*
* @param tag
* @param isPerformTask
*/
void setTaxiUnmanedDriverLineRoutingPerformTask( String tag, boolean isPerformTask );
boolean isTaxiUnmanedDriverLineRoutingPerformTask();
/**
* taxi无人化司机端 是否是在自主算路验证模式
*
* @param tag
* @param isLineRoutingVerifyMode
*/
void setTaxiUnmanedDriverLineRoutingVerifyMode( String tag, boolean isLineRoutingVerifyMode );
boolean isTaxiUnmanedDriverLineRoutingVerifyMode();
/**
* 注册监听
*

View File

@@ -117,6 +117,46 @@ public class MogoStatusManager implements IMogoStatusManager {
doSetStatus(tag, StatusDescriptor.SEEK_HELPING, seekHelping);
}
@Override
public void setTaxiUnmanedDriverPerformTask(String tag, boolean isPerformingTask) {
doSetStatus(tag, StatusDescriptor.TAXI_UNMANED_DRIVER_PERFORM_TASK, isPerformingTask);
}
@Override
public boolean isTaxiUnmanedDriverPerformTask() {
return get_bool_val(StatusDescriptor.TAXI_UNMANED_DRIVER_PERFORM_TASK);
}
@Override
public void setTaxiUnmanedDriverTakingOrders(String tag, boolean isTakingOrders) {
doSetStatus(tag, StatusDescriptor.TAXI_UNMANED_DRIVER_TAKING_ORDERS, isTakingOrders);
}
@Override
public boolean isTaxiUnmanedDriverTakingOrders() {
return get_bool_val(StatusDescriptor.TAXI_UNMANED_DRIVER_TAKING_ORDERS);
}
@Override
public void setTaxiUnmanedDriverLineRoutingPerformTask(String tag, boolean isPerformTask) {
doSetStatus(tag, StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_PERFORM_TASK, isPerformTask);
}
@Override
public boolean isTaxiUnmanedDriverLineRoutingPerformTask() {
return get_bool_val(StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_PERFORM_TASK);
}
@Override
public void setTaxiUnmanedDriverLineRoutingVerifyMode(String tag, boolean isLineRoutingVerifyMode) {
doSetStatus(tag, StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE, isLineRoutingVerifyMode);
}
@Override
public boolean isTaxiUnmanedDriverLineRoutingVerifyMode() {
return get_bool_val(StatusDescriptor.TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE);
}
private void doSetStatus(String tag, StatusDescriptor target, boolean value) {
mStatus.put(target, value);
invokeStatusChangedListener(target, value);

View File

@@ -46,6 +46,26 @@ public enum StatusDescriptor {
/**
* 压屏状态
*/
SCREEN_COVER
SCREEN_COVER,
/**
* taxi无人化 是否执行任务中
*/
TAXI_UNMANED_DRIVER_PERFORM_TASK,
/**
* taxi无人化 是否接单状态中
*/
TAXI_UNMANED_DRIVER_TAKING_ORDERS,
/**
* taxi自主算路验证 是否执行任务中
*/
TAXI_UNMANED_DRIVER_LINE_ROUTING_PERFORM_TASK,
/**
* taxi无人化 是否在自主算路验证模式
*/
TAXI_UNMANED_DRIVER_LINE_ROUTING_VERIFY_MODE
}

View File

@@ -90,8 +90,8 @@ WEBSOCKET_VERSION=1.1.7
applicationId=com.mogo.launcer
applicationName=IntelligentPilot
# RoboBus司机端2.5.1RoboTaxi司机端2.5.1RoboTaxi乘客端1.0.0
versionCode=6001000
versionName=6.1.2
versionCode=6002002
versionName=6.2.2
################# 新架构模块Maven版本管理 #################
MOGO_CORE_FUNCTION_HMI_VERSION=0.0.58.10
@@ -163,7 +163,7 @@ TAXI_DRIVER_VERSION=6.2.0
TAXI_PASSENGER_VERSION=5.2.0
# 出租车模式司机端版本号
TAXIUNMANNED_DRIVER_VERSION=6.2.0
TAXIUNMANNED_DRIVER_VERSION=6.2.2
# 出租车模式乘客端端版本号
TAXIUNMANNED_PASSENGER_VERSION=5.2.0