Merge branch 'dev_robotaxi-d_250603_8.1.0' into 'master'
Dev robotaxi d 250603 8.1.0 See merge request SCA/L4HA/AndroidApp/MoGoEagleEye!875
@@ -100,15 +100,17 @@
|
||||
|
||||
|
||||
<!--红绿灯-->
|
||||
<com.mogo.eagle.core.function.hmi.ui.widget.SingleTrafficLightView
|
||||
<com.mogo.eagle.core.function.hmi.ui.widget.TrafficLightView
|
||||
android:id="@+id/viewTrafficLightVr"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_28"
|
||||
android:layout_marginEnd="@dimen/dp_40"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="@dimen/dp_14"
|
||||
android:layout_marginEnd="@dimen/dp_21"
|
||||
android:visibility="gone"
|
||||
app:lightUser="passenger"
|
||||
/>
|
||||
|
||||
<!--接管提示-->
|
||||
<com.mogo.eagle.core.function.hmi.ui.vehicle.TakeOverView
|
||||
|
||||
@@ -52,6 +52,7 @@ import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
|
||||
import com.mogo.och.common.module.manager.socket.lan.LedScreenManager
|
||||
import com.mogo.och.bridge.utils.CoordinateCalculateRouteUtil
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeManager
|
||||
import com.mogo.och.common.module.constant.OchCommonConst
|
||||
import com.mogo.och.common.module.utils.DateTimeUtil
|
||||
import com.mogo.och.common.module.utils.PinYinUtil
|
||||
import com.mogo.och.common.module.voice.VoiceNotice
|
||||
@@ -697,7 +698,7 @@ object CharterPassengerModel {
|
||||
}
|
||||
|
||||
val lastTime: Double =
|
||||
lastSumLength / CharterPassengerConst.Charter_AVERAGE_SPEED * 3.6 //秒
|
||||
lastSumLength / OchCommonConst.Charter_AVERAGE_SPEED * 3.6 //秒
|
||||
|
||||
d(
|
||||
M_BUS_P + "calculateDistance",
|
||||
|
||||
@@ -66,14 +66,14 @@ object LoginServiceManager : IOchLanPassengerStatusListener {
|
||||
if (oldValue != newValue) {
|
||||
OchChainLogManager.writeChainLog("登录状态变化", "${oldValue}-->${newValue}")
|
||||
Log.d(tag, "登录状态变化:${oldValue}-->${newValue}")
|
||||
// if (newValue == EnumLoginStatus.Login && AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
|
||||
// BizLoopManager.setLoopFunction(
|
||||
// TAGLoopStatus,
|
||||
// LoopInfo(60 * 2, ::queryLoginStatusByNet, immediately = false, scheduler = Schedulers.io())
|
||||
// )
|
||||
// } else {
|
||||
// BizLoopManager.removeLoopFunction(TAGLoopStatus)
|
||||
// }
|
||||
if (newValue == EnumLoginStatus.Login && AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)) {
|
||||
BizLoopManager.setLoopFunction(
|
||||
TAGLoopStatus,
|
||||
LoopInfo(60 * 10, ::queryLoginStatusByNet, immediately = false, scheduler = Schedulers.io())
|
||||
)
|
||||
} else {
|
||||
BizLoopManager.removeLoopFunction(TAGLoopStatus)
|
||||
}
|
||||
LoginStatusManager.invokeLoginStatusChange(loginStatus)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,12 @@ import com.mogo.eagle.core.utilcode.util.CoordinateUtils
|
||||
import com.mogo.och.bridge.autopilot.location.OchLocationManager
|
||||
import com.mogo.och.bridge.distance.TrajectoryAndDistanceManager
|
||||
import com.mogo.och.bridge.bridge.OchBridgeManager
|
||||
import com.mogo.och.bridge.bridge.OchVlmManager
|
||||
import com.mogo.och.bridge.trajectory.TrajectoryManager
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeService
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeListener
|
||||
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
|
||||
import com.mogo.och.common.module.biz.birdge.data.VlmData
|
||||
import com.mogo.och.common.module.constant.OchCommonConst
|
||||
|
||||
|
||||
@@ -29,7 +32,14 @@ class BridgeProvider : BridgeService, CallerBase<BridgeListener>() {
|
||||
|
||||
override fun init(context: Context?) {
|
||||
this.context = context
|
||||
|
||||
// 车前引导线+预测数据
|
||||
OchBridgeManager.load()
|
||||
|
||||
// if(EnvManager.isT1T2Passenger()){
|
||||
OchVlmManager.load()
|
||||
// }
|
||||
|
||||
TrajectoryManager.load()
|
||||
}
|
||||
|
||||
@@ -92,5 +102,17 @@ class BridgeProvider : BridgeService, CallerBase<BridgeListener>() {
|
||||
}
|
||||
}
|
||||
|
||||
fun invokeVlmDataDispatch(vlmData:VlmData){
|
||||
M_LISTENERS.forEach {
|
||||
it.value.onVlmDataListener(vlmData)
|
||||
}
|
||||
}
|
||||
|
||||
fun inVokeNdeData(title: String, desc: String, sortedList: List<RoadMsg>) {
|
||||
M_LISTENERS.forEach {
|
||||
it.value.onNdeDataListener(title,desc,sortedList)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -3,13 +3,10 @@ package com.mogo.och.bridge
|
||||
import android.annotation.SuppressLint
|
||||
import com.alibaba.android.arouter.launcher.ARouter
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OCHCOMMON
|
||||
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
|
||||
import com.mogo.och.common.module.biz.birdge.data.VlmData
|
||||
import com.mogo.och.common.module.constant.OchCommonConst
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.manager.loop.LoopInfo
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
object BridgeServiceManager {
|
||||
|
||||
@@ -19,52 +16,12 @@ object BridgeServiceManager {
|
||||
private var bridgeService: BridgeProvider? =
|
||||
ARouter.getInstance().build(OchCommonConst.BIZ_Bridge).navigation() as BridgeProvider
|
||||
|
||||
private var trajectoryTime = 0L
|
||||
private var predictionTime = 0L
|
||||
|
||||
init {
|
||||
BizLoopManager.setLoopFunction(TAG,
|
||||
LoopInfo(2, ::checkTimeout, immediately = false, scheduler = Schedulers.io())
|
||||
)
|
||||
}
|
||||
|
||||
// 是否有车前引导线
|
||||
private var haveTrajectoryInfo: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
bridgeService?.invokeTrajectoryHaveDataListener(newValue)
|
||||
CallerLogger.d(TAG,"haveTrajectoryInfo 发生变化:${newValue}")
|
||||
}
|
||||
trajectoryTime = System.currentTimeMillis()
|
||||
|
||||
}
|
||||
|
||||
// 是否有预测数据
|
||||
private var havePredictionInfo: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
bridgeService?.invokePredictionHavaData(newValue)
|
||||
CallerLogger.d(TAG,"havePredictionInfo 发生变化:${newValue}")
|
||||
}
|
||||
predictionTime = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
fun checkTimeout(){
|
||||
if(System.currentTimeMillis() - trajectoryTime>2_000){
|
||||
haveTrajectoryInfo = false
|
||||
CallerLogger.d(TAG,"超时设置为false:haveTrajectoryInfo ${haveTrajectoryInfo}")
|
||||
}
|
||||
if(System.currentTimeMillis() - predictionTime>2_000){
|
||||
havePredictionInfo = false
|
||||
CallerLogger.d(TAG,"超时设置为false:havePredictionInfo ${havePredictionInfo}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun invokePlanningListener(haveTrajectoryInfos:Boolean){
|
||||
this.haveTrajectoryInfo = haveTrajectoryInfos
|
||||
bridgeService?.invokeTrajectoryHaveDataListener(haveTrajectoryInfos)
|
||||
}
|
||||
|
||||
fun invokePredictionHaveData(havePredictionInfos:Boolean){
|
||||
this.havePredictionInfo = havePredictionInfos
|
||||
bridgeService?.invokePredictionHavaData(havePredictionInfos)
|
||||
}
|
||||
|
||||
fun invokeTrajectoryPoints(trajectoryList: MutableList<MogoLocation>){
|
||||
@@ -78,4 +35,15 @@ object BridgeServiceManager {
|
||||
this.bridgeService?.invokeTrajectoryPointAndDistance(trajectoryList, distance)
|
||||
}
|
||||
|
||||
/**
|
||||
* 分发vmData
|
||||
*/
|
||||
fun invokeVlmData(vlmData: VlmData){
|
||||
this.bridgeService?.invokeVlmDataDispatch(vlmData)
|
||||
}
|
||||
|
||||
fun invokeNdeData(title: String, desc: String, sortedList: List<RoadMsg>) {
|
||||
this.bridgeService?.inVokeNdeData(title,desc,sortedList)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -73,6 +73,7 @@ object OchAutopilotAnalytics {
|
||||
params[EVENT_PARAM_AUTOPILOTANALYTICS_GROUP] = EVENT_PARAM_AUTOPILOTANALYTICS_GROUP
|
||||
OchChainLogManager.addCommonParams(params)
|
||||
MogoAnalyticUtils.track(EVENT_KEY_START_AUTOPILOT_PARAMETERS, params)
|
||||
OchChainLogManager.writeChainLogAutopilot("正式启动自驾把参数传给底层",params.toString(),false)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -86,6 +87,7 @@ object OchAutopilotAnalytics {
|
||||
params[EVENT_PARAM_AUTOPILOTANALYTICS_GROUP] = EVENT_PARAM_AUTOPILOTANALYTICS_GROUP
|
||||
OchChainLogManager.addCommonParams(params)
|
||||
MogoAnalyticUtils.track(EVENT_KEY_START_AUTOPILOT_ACK, params)
|
||||
OchChainLogManager.writeChainLogAutopilot("底盘收到启动自驾的ack",params.toString(),false)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,6 +158,7 @@ object OchAutopilotAnalytics {
|
||||
mStartAutopilotParams[EVENT_PARAM_AUTOPILOTANALYTICS_GROUP] = EVENT_PARAM_AUTOPILOTANALYTICS_GROUP
|
||||
OchChainLogManager.addCommonParams(mStartAutopilotParams)
|
||||
MogoAnalyticUtils.track(mStartAutopilotKey, mStartAutopilotParams)
|
||||
OchChainLogManager.writeChainLogAutopilot("启动自驾失败",mStartAutopilotParams.toString(),false)
|
||||
clearStartAutopilotParams() //清空参数数据,防止误传
|
||||
}
|
||||
|
||||
@@ -200,6 +203,7 @@ object OchAutopilotAnalytics {
|
||||
mStartAutopilotParams[EVENT_PARAM_AUTOPILOTANALYTICS_GROUP] = EVENT_PARAM_AUTOPILOTANALYTICS_GROUP
|
||||
OchChainLogManager.addCommonParams(mStartAutopilotParams)
|
||||
MogoAnalyticUtils.track(mStartAutopilotKey, mStartAutopilotParams)
|
||||
OchChainLogManager.writeChainLogAutopilot("启动自驾成功",mStartAutopilotParams.toString(),false)
|
||||
clearStartAutopilotParams() //清空参数数据,防止误传
|
||||
} else {
|
||||
mStartAutopilotParams[EVENT_PARAM_ENV_ONLINE] = DebugConfig.getNetMode() == DebugConfig.NET_MODE_RELEASE
|
||||
@@ -251,6 +255,7 @@ object OchAutopilotAnalytics {
|
||||
params[EVENT_PARAM_AUTOPILOTANALYTICS_GROUP] = EVENT_PARAM_AUTOPILOTANALYTICS_GROUP
|
||||
OchChainLogManager.addCommonParams(mStartAutopilotParams)
|
||||
MogoAnalyticUtils.track(getEventKeyApUnableStartReason(), params)
|
||||
OchChainLogManager.writeChainLogAutopilot("触发\"无法开启自驾已知异常\"埋点",params.toString(),false)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -263,6 +268,7 @@ object OchAutopilotAnalytics {
|
||||
params[EVENT_PARAM_AUTOPILOTANALYTICS_GROUP] = EVENT_PARAM_AUTOPILOTANALYTICS_GROUP
|
||||
OchChainLogManager.addCommonParams(mStartAutopilotParams)
|
||||
MogoAnalyticUtils.track(getEventKeyClickStartAutopilot(), params)
|
||||
OchChainLogManager.writeChainLogAutopilot("用户点击启动自驾的时间",params.toString(),false)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.mogo.och.bridge.bridge
|
||||
|
||||
data class VlmImageData(val imageSourceTimestamp: Double ,var image: ByteArray?) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as VlmImageData
|
||||
|
||||
return imageSourceTimestamp == other.imageSourceTimestamp
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return imageSourceTimestamp.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "VlmImageData(imageSourceTimestamp=$imageSourceTimestamp)"
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
data class VlmMessageData(val messageSourceTimestamp: Double ,val id:Int?,val message:String?){
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as VlmMessageData
|
||||
|
||||
// if (messageSourceTimestamp != other.messageSourceTimestamp) return false
|
||||
if (id != other.id) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = messageSourceTimestamp.hashCode()
|
||||
result = 31 * result + (id ?: 0)
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -1,27 +1,96 @@
|
||||
package com.mogo.och.bridge.bridge
|
||||
|
||||
import android.util.Log
|
||||
import com.mogo.commons.env.ProjectUtils
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningActionsListener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningTrajectoryListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager.getWgs84Lat
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager.getWgs84Lon
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningActionsListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningTrajectoryListenerManager
|
||||
import com.mogo.eagle.core.function.call.base.CallerBase
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
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_OCHCOMMON
|
||||
import com.mogo.eagle.core.utilcode.util.LocationUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
|
||||
import com.mogo.map.MogoMap
|
||||
import com.mogo.map.MogoMap.Companion.mapInstance
|
||||
import com.mogo.map.overlay.core.Level
|
||||
import com.mogo.map.overlay.point.Point
|
||||
import com.mogo.och.bridge.BridgeServiceManager
|
||||
import com.mogo.och.bridge.R
|
||||
import prediction2025.Prediction2025
|
||||
import mogo.telematics.pad.MessagePad
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
object OchBridgeManager: CallerBase<IMoGoPlanningTrajectoryListener>(),
|
||||
IMoGoPlanningTrajectoryListener, IMoGoAutopilotIdentifyListener {
|
||||
object OchBridgeManager: IMoGoPlanningTrajectoryListener, IMoGoAutopilotIdentifyListener,
|
||||
IMoGoAutopilotPlanningActionsListener {
|
||||
private val TAG = "${M_OCHCOMMON}OchPlanningListenerManager"
|
||||
|
||||
private var trajectoryTime = 0L
|
||||
private var predictionTime = 0L
|
||||
|
||||
private val map by lazy {
|
||||
mapInstance.getMogoMap(MogoMap.DEFAULT)
|
||||
}
|
||||
|
||||
@Volatile
|
||||
private var lastTime: Long = 0L
|
||||
|
||||
@Volatile
|
||||
private var lastUpdateTime: Long = 0L
|
||||
|
||||
@Volatile
|
||||
private var isHide = false
|
||||
|
||||
fun load(){
|
||||
CallerPlanningTrajectoryListenerManager.addListener(TAG,this)
|
||||
CallerAutopilotIdentifyListenerManager.addListener(TAG,this)
|
||||
CallerPlanningActionsListenerManager.addListener(TAG, this)
|
||||
UiThreadHandler.postDelayed(timeRunnable, 1000)
|
||||
}
|
||||
|
||||
fun release(){
|
||||
fun release() {
|
||||
CallerPlanningTrajectoryListenerManager.removeListener(TAG)
|
||||
CallerAutopilotIdentifyListenerManager.removeListener(TAG)
|
||||
CallerPlanningActionsListenerManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
// 是否有车前引导线
|
||||
private var haveTrajectoryInfo: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
BridgeServiceManager.invokePlanningListener(newValue)
|
||||
CallerLogger.d(TAG,"haveTrajectoryInfo 发生变化:${newValue}")
|
||||
}
|
||||
trajectoryTime = System.currentTimeMillis()
|
||||
|
||||
}
|
||||
|
||||
// 是否有预测数据
|
||||
private var havePredictionInfo: Boolean by Delegates.observable(false) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
BridgeServiceManager.invokePredictionHaveData(newValue)
|
||||
CallerLogger.d(TAG,"havePredictionInfo 发生变化:${newValue}")
|
||||
}
|
||||
predictionTime = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
fun checkTimeout(){
|
||||
if(System.currentTimeMillis() - trajectoryTime>2_000){
|
||||
haveTrajectoryInfo = false
|
||||
CallerLogger.d(TAG,"超时设置为false:haveTrajectoryInfo $haveTrajectoryInfo")
|
||||
}
|
||||
if(System.currentTimeMillis() - predictionTime>2_000){
|
||||
havePredictionInfo = false
|
||||
CallerLogger.d(TAG,"超时设置为false:havePredictionInfo $havePredictionInfo")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -29,19 +98,100 @@ object OchBridgeManager: CallerBase<IMoGoPlanningTrajectoryListener>(),
|
||||
*/
|
||||
override fun onAutopilotTrajectory(trajectoryInfos: MutableList<MessagePad.TrajectoryPoint>) {
|
||||
if(trajectoryInfos.isEmpty()){
|
||||
BridgeServiceManager.invokePlanningListener(false)
|
||||
haveTrajectoryInfo = false
|
||||
}else{
|
||||
BridgeServiceManager.invokePlanningListener(true)
|
||||
haveTrajectoryInfo = true
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预测信息
|
||||
*/
|
||||
override fun onPredictionObstacleTrajectory(predictionObjects: Prediction2025.mPredictionObjects) {
|
||||
if (predictionObjects.objsAppList==null) {
|
||||
BridgeServiceManager.invokePredictionHaveData(false)
|
||||
havePredictionInfo = false
|
||||
}else{
|
||||
BridgeServiceManager.invokePredictionHaveData(true)
|
||||
havePredictionInfo = true
|
||||
}
|
||||
}
|
||||
|
||||
private val timeRunnable = Runnable {
|
||||
timeCheck()
|
||||
}
|
||||
|
||||
private fun timeCheck() {
|
||||
if (lastUpdateTime > 0 && System.currentTimeMillis() - lastUpdateTime > 1000) {
|
||||
ThreadUtils.getIoPool().execute {
|
||||
CallerMapUIServiceManager.getOverlayManager()?.hidePoint("RenderParkingModel")
|
||||
}
|
||||
isHide = true
|
||||
}
|
||||
UiThreadHandler.postDelayed(timeRunnable, 1000)
|
||||
}
|
||||
|
||||
override fun pncActions(planningActionMsg: MessagePad.PlanningActionMsg) {
|
||||
if (!FunctionBuildConfig.isParkingOpen) return
|
||||
val timeStamp = System.currentTimeMillis()
|
||||
lastUpdateTime = timeStamp
|
||||
if (timeStamp - lastTime >= 1000) {
|
||||
lastTime = System.currentTimeMillis()
|
||||
// Saas乘客屏且是自驾中
|
||||
if (ProjectUtils.isSaas() && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)
|
||||
) {
|
||||
Log.d(TAG, "pncActions-Sass乘客屏收到数据!")
|
||||
if (CallerAutoPilotStatusListenerManager.getState() != IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
|
||||
Log.d(TAG, "pncActions-非自驾中!")
|
||||
CallerMapUIServiceManager.getOverlayManager()?.hidePoint("RenderParkingModel")
|
||||
isHide = true
|
||||
} else {
|
||||
Log.d(TAG, "pncActions-UTM度带号:${planningActionMsg.utmZone},坐标为:(${planningActionMsg.updatedTerminal.x},${planningActionMsg.updatedTerminal.y}),角度为:${planningActionMsg.parkingLotHeading}")
|
||||
val lonLatArr = map?.switchData(
|
||||
planningActionMsg.updatedTerminal.x,
|
||||
planningActionMsg.updatedTerminal.y,
|
||||
false
|
||||
)
|
||||
lonLatArr?.let {
|
||||
if (it.size < 2) {
|
||||
Log.d(TAG, "pncActions-UTM坐标转换失败!")
|
||||
CallerMapUIServiceManager.getOverlayManager()?.hidePoint("RenderParkingModel")
|
||||
isHide = true
|
||||
return@let
|
||||
}
|
||||
val lon = getWgs84Lon()
|
||||
val lat = getWgs84Lat()
|
||||
val distance = LocationUtils.getDistance(it[0], it[1], lon, lat)
|
||||
Log.d(TAG, "自车位置:(${lon},${lat}),进站点位置:(${it[0]},${it[1]}),pncActions-进站点距离自车${distance}米!")
|
||||
// 只处理100m以内的
|
||||
if (distance >= 100) {
|
||||
Log.d(TAG, "pncActions-进站点距离自车过远,不展示!")
|
||||
CallerMapUIServiceManager.getOverlayManager()?.hidePoint("RenderParkingModel")
|
||||
isHide = true
|
||||
return@let
|
||||
}
|
||||
val angle = map!!.convertAngle(planningActionMsg.parkingLotHeading, it[0], it[1]).toFloat()
|
||||
// owner、level、id作为key去从缓存中取
|
||||
val builder =
|
||||
Point.Options.Builder("TYPE_MARKER_PNC", Level.MAP_MARKER)
|
||||
.setId("RenderParkingModel")
|
||||
.anchor(0.5f, 0.5f)
|
||||
.set3DMode(true)
|
||||
.isUseGps(true)
|
||||
.controlAngle(true)
|
||||
.rotate(angle)
|
||||
.icon3DRes(R.raw.parking_model)
|
||||
.longitude(it[0])
|
||||
.latitude(it[1])
|
||||
CallerMapUIServiceManager.getOverlayManager()
|
||||
?.showOrUpdatePoint(builder.build())
|
||||
Log.d(TAG, "pncActions-展示进站点(${it[0]},${it[1]}),角度为:${angle}!")
|
||||
if (isHide) {
|
||||
Log.d(TAG, "pncActions-显示被隐藏的进站点!")
|
||||
CallerMapUIServiceManager.getOverlayManager()?.showPoint("RenderParkingModel")
|
||||
isHide = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,24 +1,28 @@
|
||||
package com.mogo.och.unmanned.passenger.ui.aiview
|
||||
package com.mogo.och.bridge.bridge
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager
|
||||
import com.mogo.och.unmanned.passenger.ui.aiview.bean.AIMessage
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerVlmManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OCHCOMMON
|
||||
import com.mogo.och.bridge.BridgeServiceManager
|
||||
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
|
||||
|
||||
import mogo.telematics.pad.MessagePad.TrackedObject
|
||||
|
||||
class NDEViewModel: ViewModel(), IMoGoAutopilotIdentifyListener {
|
||||
object OchNdeManager : IMoGoAutopilotIdentifyListener {
|
||||
private val TAG = "${M_OCHCOMMON}OchVlmManager"
|
||||
|
||||
companion object{
|
||||
private const val TAG = "NDEViewModel"
|
||||
fun load(){
|
||||
CallerAutopilotIdentifyListenerManager.addListener(TAG, this)
|
||||
}
|
||||
|
||||
fun release(){
|
||||
CallerVlmManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
private var lastMap2 = HashMap<Int, String>()
|
||||
private var lastTime = 0L
|
||||
|
||||
fun init(){
|
||||
CallerAutopilotIdentifyListenerManager.addListener(TAG, this)
|
||||
}
|
||||
|
||||
override fun onAutopilotIdentifyDataUpdate(trafficData: List<TrackedObject>?){
|
||||
super.onAutopilotIdentifyDataUpdate(trafficData)
|
||||
handleCheLong(trafficData)
|
||||
@@ -27,7 +31,7 @@ class NDEViewModel: ViewModel(), IMoGoAutopilotIdentifyListener {
|
||||
private fun handleCheLong(trafficData: List<TrackedObject>?) {
|
||||
var hasCheLong = false
|
||||
var isNewData = false
|
||||
val roadMsgList = ArrayList<AIMessage.RoadMsg>()
|
||||
val roadMsgList = ArrayList<RoadMsg>()
|
||||
val curMap = HashMap<Int, String>()
|
||||
if (lastTime > 0 && System.currentTimeMillis() - lastTime > 60000) {
|
||||
lastMap2.clear()// 清除上次车龙事件的缓存
|
||||
@@ -55,8 +59,7 @@ class NDEViewModel: ViewModel(), IMoGoAutopilotIdentifyListener {
|
||||
curMap[obj.laneNum] = "0"
|
||||
}
|
||||
// 保存所有车道信息
|
||||
roadMsgList.add(
|
||||
AIMessage.RoadMsg(
|
||||
roadMsgList.add(RoadMsg(
|
||||
obj.arrowType,
|
||||
laneNum = obj.laneNum,
|
||||
isRecommend = obj.suggestedLanes,
|
||||
@@ -74,10 +77,8 @@ class NDEViewModel: ViewModel(), IMoGoAutopilotIdentifyListener {
|
||||
lastTime = System.currentTimeMillis()
|
||||
|
||||
val sortedList = roadMsgList.sortedWith(compareByDescending { it.laneNum })
|
||||
val ndeEvent = AIMessage.NDEData(System.currentTimeMillis().toString(),"路口车龙","前方路口有车龙",sortedList)
|
||||
AIMessageManager.post(ndeEvent)
|
||||
BridgeServiceManager.invokeNdeData("路口车龙","前方路口有车龙",sortedList)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
package com.mogo.och.bridge.bridge
|
||||
|
||||
import com.mogo.eagle.core.function.api.autopilot.IVlmListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerVlmManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OCHCOMMON
|
||||
import com.mogo.och.bridge.BridgeServiceManager
|
||||
import com.mogo.och.common.module.biz.birdge.data.VlmData
|
||||
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
|
||||
import vllm.Vlm
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
object OchVlmManager : IVlmListener {
|
||||
private val TAG = "${M_OCHCOMMON}OchVlmManager"
|
||||
|
||||
fun load(){
|
||||
CallerVlmManager.addListener(TAG,this)
|
||||
}
|
||||
|
||||
fun release(){
|
||||
CallerVlmManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
//
|
||||
private var vllmImageData: VlmImageData by Delegates.observable(VlmImageData(0.0,null)) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
if(newValue.imageSourceTimestamp == vllmData.messageSourceTimestamp){
|
||||
CallerLogger.d(TAG," message先来 图片后来 发送message和图片 ${newValue.imageSourceTimestamp}---${vllmData.messageSourceTimestamp}")
|
||||
val timemillis = System.currentTimeMillis()
|
||||
BridgeServiceManager.invokeVlmData(VlmData(vllmData.id,vllmData.message,newValue.image, timemillis))
|
||||
OchChainLogManager.writeChainLogEyeVlm("收到VlmData"," message先来 图片后来 发送message和图片 ${newValue.imageSourceTimestamp}---${vllmData.messageSourceTimestamp}--$timemillis")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private var vllmData: VlmMessageData by Delegates.observable(VlmMessageData(0.0,0,"")) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
val currentTimeMillis = System.currentTimeMillis()
|
||||
if(newValue.messageSourceTimestamp== vllmImageData.imageSourceTimestamp){
|
||||
// 图片先来 发送message和图片
|
||||
BridgeServiceManager.invokeVlmData(VlmData(newValue.id,newValue.message,
|
||||
vllmImageData.image, currentTimeMillis
|
||||
)
|
||||
)
|
||||
CallerLogger.d(TAG,"messsage后来 图片先来 发送message和图片 ${newValue.message}----${newValue.messageSourceTimestamp}---${newValue.id}")
|
||||
OchChainLogManager.writeChainLogEyeVlm("收到VlmData","messsage后来 图片先来 发送message和图片 ${newValue.message}----${newValue.messageSourceTimestamp}---${newValue.id}--$currentTimeMillis")
|
||||
}else{
|
||||
// message 先来 单独发送message 图片来了后 再次发送出去
|
||||
BridgeServiceManager.invokeVlmData(VlmData(newValue.id,newValue.message,null,
|
||||
currentTimeMillis
|
||||
))
|
||||
CallerLogger.d(TAG,"message先来 图片后来 发送message ${newValue.message}---${newValue.messageSourceTimestamp}---${newValue.id}---$currentTimeMillis")
|
||||
OchChainLogManager.writeChainLogEyeVlm("收到VlmData","message先来 图片后来 发送message ${newValue.message}---${newValue.messageSourceTimestamp}---${newValue.id}---$currentTimeMillis")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onVllm(sourceTimestamp: Double, vllm: Vlm.VLLMObject) {
|
||||
if(this.vllmData.id!=vllm.workZone.id){
|
||||
this.vllmData = VlmMessageData(sourceTimestamp,vllm.workZone.id,vllm.workZone.sceneExplantion)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVllmImage(sourceTimestamp: Double, image: ByteArray) {
|
||||
this.vllmImageData = VlmImageData(sourceTimestamp,image)
|
||||
}
|
||||
}
|
||||
BIN
OCH/common/bridge/src/main/res/raw/parking_model.nt3d
Normal file
@@ -1,6 +1,8 @@
|
||||
package com.mogo.och.common.module.debug
|
||||
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.BitmapFactory
|
||||
import android.os.Environment
|
||||
import android.os.SystemClock
|
||||
import chassis.Chassis
|
||||
@@ -8,6 +10,7 @@ import chassis.Chassis.DoorNumber
|
||||
import chassis.VehicleStateOuterClass
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.eagle.core.data.enums.DataSourceType
|
||||
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
@@ -24,6 +27,7 @@ import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02Lis
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisStatesListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningActionsListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerVlmManager
|
||||
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapRomaListener
|
||||
@@ -34,24 +38,25 @@ import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.eagle.core.utilcode.util.ActivityUtils
|
||||
import com.mogo.eagle.core.utilcode.util.GsonUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.common.module.R
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeManager
|
||||
import com.mogo.och.common.module.biz.order.OrderManager
|
||||
import com.mogo.och.common.module.debug.location.MogoLocationExit
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
//import com.mogo.och.bridge.distance.TrajectoryAndDistanceManager
|
||||
//import com.mogo.och.bridge.utils.CoordinateCalculateRouteUtil
|
||||
//import com.mogo.och.bridge.utils.CoordinateCalculateRouteUtil
|
||||
import com.mogo.och.common.module.view.DebugFloatWindow
|
||||
import com.mogo.och.common.module.wigets.media.MediaBeanManager
|
||||
import com.zhjt.mogo.adas.data.bean.AutopilotStatistics
|
||||
import mogo.telematics.pad.MessagePad
|
||||
import mogo_msg.MogoReportMsg
|
||||
import vllm.Vlm
|
||||
import java.io.BufferedReader
|
||||
import java.io.ByteArrayOutputStream
|
||||
import java.io.File
|
||||
import java.io.FileInputStream
|
||||
import java.io.IOException
|
||||
import java.io.InputStreamReader
|
||||
|
||||
|
||||
object DebugDataDispatch {
|
||||
|
||||
const val TAG = "DebugDataDispatch"
|
||||
@@ -73,6 +78,8 @@ object DebugDataDispatch {
|
||||
const val ota = "ota"
|
||||
const val video = "video"
|
||||
const val mediaMusic = "mediaAndMusic"
|
||||
const val vlmMessage = "vlmMessage"
|
||||
const val vlmImage = "vlmImage"
|
||||
|
||||
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "location" --es path "1111/11111"
|
||||
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "globalPath" --es path "sy73.json"
|
||||
@@ -89,7 +96,10 @@ object DebugDataDispatch {
|
||||
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "showDebugView"
|
||||
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "scanner" --es qrInfo ""
|
||||
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "ota" --ei "ota" 1
|
||||
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "video" --ei "video" 1 --es url "rtmp://video.zhidaozhixing.com/live/861130041693196C_2"
|
||||
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "vlmMessage" --es message "前方100米有道路施工,施工长度100米,影响第1、2车道通行。" --ei id 128 --ef time 1880.0
|
||||
// adb shell am broadcast -a com.mogo.launcher.debug -f 0x011000000 --es type "vlmImage" --ef time 1880.0
|
||||
|
||||
// adb shell am broadcast -a com.hmi.v2x.trafficlight -f 0x011000000 --ei trafficLightCheckType 1 --ei trafficLightCountDown 0 --ez trafficLightIsShow true // 红绿灯
|
||||
|
||||
|
||||
val ROOT_PATH =
|
||||
@@ -102,6 +112,25 @@ object DebugDataDispatch {
|
||||
|
||||
}
|
||||
when (type) {
|
||||
vlmMessage -> {
|
||||
val time = intent.getFloatExtra("time",0f)
|
||||
val id = intent.getIntExtra("id",0)
|
||||
val message = intent.getStringExtra("message")
|
||||
val newBuilder = Vlm.VLLMObject.newBuilder()
|
||||
val build = newBuilder.workZoneBuilder.setId(id).setSceneExplantion(message).build()
|
||||
newBuilder.workZone = build
|
||||
CallerVlmManager.invokeVllm(time.toDouble(),newBuilder.build())
|
||||
}
|
||||
vlmImage -> {
|
||||
val time = intent.getFloatExtra("time",0f)
|
||||
BizLoopManager.runInIoThread{
|
||||
val bitmap = BitmapFactory.decodeResource(AbsMogoApplication.getApp().resources, R.drawable.common_debug)
|
||||
val stream = ByteArrayOutputStream()
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream)
|
||||
val byteArray = stream.toByteArray()
|
||||
CallerVlmManager.invokeVllmImage(time.toDouble(),byteArray)
|
||||
}
|
||||
}
|
||||
mediaMusic -> {
|
||||
val musicList = MediaBeanManager.getMusicList()
|
||||
val mediaList = MediaBeanManager.getMediaList()
|
||||
|
||||
BIN
OCH/common/common/src/debug/res/drawable/common_debug.webp
Normal file
|
After Width: | Height: | Size: 182 KiB |
@@ -1,6 +1,8 @@
|
||||
package com.mogo.och.common.module.biz.birdge
|
||||
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
|
||||
import com.mogo.och.common.module.biz.birdge.data.VlmData
|
||||
|
||||
interface BridgeListener {
|
||||
/**
|
||||
@@ -15,4 +17,9 @@ interface BridgeListener {
|
||||
fun onTrajectoryDistanceListener(distance: Double){}
|
||||
|
||||
fun onTrajectoryPointsAndDistanceListener(trajectoryList: MutableList<MogoLocation>,distance: Double){}
|
||||
|
||||
|
||||
fun onVlmDataListener(vlmData: VlmData){}
|
||||
|
||||
fun onNdeDataListener(title: String, desc: String, sortedList: List<RoadMsg>) {}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.mogo.och.common.module.biz.birdge.data
|
||||
|
||||
data class RoadMsg(
|
||||
var arrowType: Int, // 车道类型,如直行201(详情参考文件:message_pad.proto)
|
||||
var laneNum: Int,// 车道号
|
||||
var isRecommend: Boolean,// 是否是推荐车道
|
||||
var isCheLong: Boolean// 是否有车龙,代表拥堵、行驶缓慢
|
||||
)
|
||||
@@ -0,0 +1,33 @@
|
||||
package com.mogo.och.common.module.biz.birdge.data
|
||||
|
||||
data class VlmData(
|
||||
val id: Int?,
|
||||
val message: String?,
|
||||
var image: ByteArray?,
|
||||
var timestamp: Long = System.currentTimeMillis()
|
||||
) {
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as VlmData
|
||||
|
||||
if (id != other.id) return false
|
||||
if (message != other.message) return false
|
||||
if (image != null) {
|
||||
if (other.image == null) return false
|
||||
if (!image.contentEquals(other.image)) return false
|
||||
} else if (other.image != null) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return id ?: 0
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return "VlmData(id=$id, message=$message)"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -71,5 +71,14 @@ class OchCommonConst {
|
||||
const val AUTOMATIC_PLANNING_MAX_DISTANCE = 15
|
||||
|
||||
const val ARRIVE_AT_END_STATION_DISTANCE = 10
|
||||
|
||||
|
||||
//b1 b2 平均速度 bus的平均里程:25km/h
|
||||
const val BUS_AVERAGE_SPEED = 25
|
||||
|
||||
//M1的平均里程:15km/h
|
||||
const val Charter_AVERAGE_SPEED = 15
|
||||
//T1T2的平均里程:38km/h
|
||||
const val TAXI_AVERAGE_SPEED = 38
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.mogo.och.common.module.manager
|
||||
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
|
||||
object EnvManager {
|
||||
fun isB1(): Boolean {
|
||||
return AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)
|
||||
}
|
||||
|
||||
fun isB1Driver(): Boolean {
|
||||
return isB1() && AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)
|
||||
}
|
||||
|
||||
fun isB1Passenger(): Boolean {
|
||||
return isB1() && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)
|
||||
}
|
||||
|
||||
fun isB2(): Boolean {
|
||||
return AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)
|
||||
}
|
||||
|
||||
fun isB2Driver(): Boolean {
|
||||
return isB2() && AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)
|
||||
}
|
||||
|
||||
fun isB2Passenger(): Boolean {
|
||||
return isB2() && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)
|
||||
}
|
||||
|
||||
fun isT1T2(): Boolean {
|
||||
return AppIdentityModeUtils.isT1T2(FunctionBuildConfig.appIdentityMode)
|
||||
}
|
||||
|
||||
fun isT1T2Driver(): Boolean {
|
||||
return isT1T2() && AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)
|
||||
}
|
||||
|
||||
fun isT1T2Passenger(): Boolean {
|
||||
return isT1T2() && AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -4,6 +4,7 @@ import android.content.Context
|
||||
import android.media.AudioManager
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.och.common.module.manager.EnvManager
|
||||
import com.mogo.och.common.module.manager.audition.AuditionManager
|
||||
import com.mogo.och.common.module.manager.audition.MusicData
|
||||
import com.mogo.och.common.module.manager.audition.PlayState
|
||||
@@ -64,7 +65,11 @@ object AudioFocusManager : AuditionManager.MusicDataChangeListener {
|
||||
if(isPlaying!= isPlayingVideo) {
|
||||
isPlayingVideo = isPlaying
|
||||
if(isPlaying){
|
||||
AuditionManager.stop()
|
||||
if(EnvManager.isT1T2Passenger()){
|
||||
AuditionManager.pause()
|
||||
}else {
|
||||
AuditionManager.stop()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,6 +64,15 @@ object AuditionManager: AuditionCacheManager.DataChangeListener, Audition.OnAudi
|
||||
return Audition.isPlaying
|
||||
}
|
||||
|
||||
fun pause(){
|
||||
val playing = isPlaying()
|
||||
if(playing){
|
||||
musicDataPlaying?.let {
|
||||
toggle(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun stop(){
|
||||
val playing = isPlaying()
|
||||
if(playing){
|
||||
|
||||
@@ -64,12 +64,16 @@ object OchChainLogManager {
|
||||
|
||||
const val EVENT_KEY_INFO_ERROR = "analytics_event_och_error"
|
||||
|
||||
const val EVENT_KEY_INFO_VLM = "analytics_event_och_vlm"
|
||||
|
||||
fun writeChainLogEye(title: String, info: String) {
|
||||
writeChainLog(title, info, true, EVENT_KEY_INFO_CALL_EYE)
|
||||
}
|
||||
|
||||
|
||||
fun writeChainLogEyeVlm(title: String, info: String) {
|
||||
writeChainLog(title, info, false, EVENT_KEY_INFO_VLM)
|
||||
}
|
||||
|
||||
// 时间方面的日志
|
||||
fun writeChainLogTime(title: String, info: String) {
|
||||
@@ -120,8 +124,8 @@ object OchChainLogManager {
|
||||
fun writeChainLogScanner(title: String, changeInfo: String) {
|
||||
writeChainLog(title, changeInfo, true, EVENT_KEY_INFO_SCANNER)
|
||||
}
|
||||
fun writeChainLogAutopilot(title: String, changeInfo: String) {
|
||||
writeChainLog(title, changeInfo, true, EVENT_KEY_INFO_AUTOPILOT)
|
||||
fun writeChainLogAutopilot(title: String, changeInfo: String,upload:Boolean = true) {
|
||||
writeChainLog(title, changeInfo, upload, EVENT_KEY_INFO_AUTOPILOT)
|
||||
}
|
||||
|
||||
fun writeChainLogInit(title: String, info: String) {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.mogo.och.common.module.wigets;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Paint;
|
||||
@@ -10,6 +11,8 @@ import android.util.AttributeSet;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatTextView;
|
||||
|
||||
import com.mogo.och.common.module.R;
|
||||
|
||||
/**
|
||||
* 通用渐变文字
|
||||
* @author: wangmingjun
|
||||
@@ -30,6 +33,8 @@ public class OCHGradientTextView extends AppCompatTextView {
|
||||
private float mdy;
|
||||
private int mColor;
|
||||
|
||||
private int ochgravity = 1;
|
||||
|
||||
public OCHGradientTextView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@@ -39,6 +44,11 @@ public class OCHGradientTextView extends AppCompatTextView {
|
||||
super(context, attrs);
|
||||
//设置默认的颜色
|
||||
mColorList = new int[]{0xFFFFFFFF, 0xFFFFFFF};
|
||||
|
||||
TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OCHGradientTextView);
|
||||
|
||||
ochgravity = array.getInt(R.styleable.OCHGradientTextView_ochgravity, 1);
|
||||
array.recycle();
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +70,11 @@ public class OCHGradientTextView extends AppCompatTextView {
|
||||
mPaint.setShadowLayer(mRadius, mdx, mdy, mColor);
|
||||
|
||||
//画出文字
|
||||
canvas.drawText(mTipText, getMeasuredWidth() / 2.0f - mTextBound.width() / 2.0f, getMeasuredHeight() / 2.0f + mTextBound.height() / 2.0f, mPaint);
|
||||
if(ochgravity==1) {
|
||||
canvas.drawText(mTipText, getMeasuredWidth() / 2.0f - mTextBound.width() / 2.0f, getMeasuredHeight() / 2.0f + mTextBound.height() / 2.0f, mPaint);
|
||||
}else if(ochgravity==0){
|
||||
canvas.drawText(mTipText, 0f, getMeasuredHeight() / 2.0f + mTextBound.height() / 2.0f-mTextBound.bottom, mPaint);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,6 +14,10 @@
|
||||
<attr name="assetsfolder" format="string" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="OCHGradientTextView">
|
||||
<attr name="ochgravity" format="integer" />
|
||||
</declare-styleable>
|
||||
|
||||
<declare-styleable name="EmptyView">
|
||||
<attr name="empty_title" format="string" />
|
||||
</declare-styleable>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<color name="taxi_111533">#111533</color>
|
||||
<color name="taxi_878890">#878890</color>
|
||||
<color name="taxi_EF262C">#EF262C</color>
|
||||
<color name="common_color_00000000">#00000000</color>
|
||||
<color name="common_color_4D000000">#4D000000</color>
|
||||
<color name="common_color_99000000">#99000000</color>
|
||||
|
||||
@@ -18,6 +19,7 @@
|
||||
|
||||
<color name="common_80000000">#80000000</color>
|
||||
<color name="common_80FFFFFF">#80FFFFFF</color>
|
||||
<color name="common_FFFFFF">#FFFFFF</color>
|
||||
<color name="common_1466FB">#1466FB</color>
|
||||
<color name="common_e0efff">#E0EFFF</color>
|
||||
<color name="common_b8c2d7">#B8C2D7</color>
|
||||
@@ -42,10 +44,15 @@
|
||||
<color name="common_FF4E41">#FF4E41</color>
|
||||
<color name="common_B3FFFFFF">#B3FFFFFF</color>
|
||||
<color name="common_cccccc">#CCCCCC</color>
|
||||
<color name="common_284F7E">#284F7E</color>
|
||||
<color name="common_f7151d41">#F7151D41</color>
|
||||
<color name="common_3B3D44">#3B3D44</color>
|
||||
<color name="common_2E323A">#2E323A</color>
|
||||
<color name="common_ffffffff">#ffffffff</color>
|
||||
<color name="common_10ffffff">#1Affffff</color>
|
||||
<color name="common_50ffffff">#80000000</color>
|
||||
<color name="common_2eacff">#2EACFF</color>
|
||||
<color name="common_d4d4d4">#D4D4D4</color>
|
||||
<color name="common_ff852e">#FF852E</color>
|
||||
|
||||
</resources>
|
||||
@@ -39,6 +39,7 @@ class TaskRunningAdapter(
|
||||
private var totalHeight = 0f
|
||||
|
||||
fun setDataList(dataList: List<BusStationBean>) {
|
||||
CallerLogger.d(TAG,"设置view-----")
|
||||
this.mData.clear()
|
||||
this.mData.addAll(dataList)
|
||||
if (LineModel.startStationIndex == 0) {
|
||||
@@ -47,7 +48,7 @@ class TaskRunningAdapter(
|
||||
totalHeight =
|
||||
(halfHeight + (dataList.size - 1 - LineModel.startStationIndex) * heightItem).toFloat()
|
||||
}
|
||||
notifyItemRangeChanged(0, dataList.size, true)
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
|
||||
@@ -48,13 +48,13 @@ android {
|
||||
main {
|
||||
res.srcDirs = [
|
||||
'src/main/res',
|
||||
'src/main/res/m2',
|
||||
'src/main/res/jinlv',
|
||||
'src/main/res/b2',
|
||||
'src/main/res/b1',
|
||||
]
|
||||
java.srcDirs = [
|
||||
'src/main/java',
|
||||
'src/main/java/m2',
|
||||
'src/main/java/jinlv',
|
||||
'src/main/java/b2',
|
||||
'src/main/java/b1',
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,11 +37,11 @@ class BaseBusPassengerPresenter(view: BusPassengerRouteFragment?) :
|
||||
}
|
||||
|
||||
private fun initListeners() {
|
||||
CommonModel.setRouteLineInfoCallback(this)
|
||||
CommonModel.setRouteLineInfoCallback(TAG,this)
|
||||
}
|
||||
|
||||
private fun releaseListeners() {
|
||||
CommonModel.setRouteLineInfoCallback(null)
|
||||
CommonModel.setRouteLineInfoCallback(TAG,null)
|
||||
}
|
||||
|
||||
override fun updateSpeed(location: Int) {
|
||||
@@ -0,0 +1,242 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.presenter
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.mogo.commons.mvp.Presenter
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeListener
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeManager
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.utils.RxUtils
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ADASCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.constant.M2Const.Companion.M2_MAP_STATION_MAKER
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.PM2ADASModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.map.PM2HPMapFragment
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.AIMessageManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
import io.reactivex.disposables.Disposable
|
||||
import kotlin.properties.Delegates
|
||||
|
||||
class PM2ADASPresenter(view: PM2HPMapFragment?) :
|
||||
Presenter<PM2HPMapFragment?>(view), ADASCallback, ICommonCallback, BridgeListener,
|
||||
AIMessageManager.AIMessageListener {
|
||||
|
||||
private val TAG = "PM2ADASPresenter"
|
||||
|
||||
private var haveTrajectoryInfos:Boolean by Delegates.observable(false) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
checkScreenChange()
|
||||
}
|
||||
}
|
||||
private var havePredictionInfos:Boolean by Delegates.observable(false) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
checkScreenChange()
|
||||
}
|
||||
}
|
||||
// 是否有订单
|
||||
private var haveLine:Boolean by Delegates.observable(false) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
checkScreenChange()
|
||||
}
|
||||
}
|
||||
private var arrived:Boolean by Delegates.observable(false) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
checkScreenChange()
|
||||
}
|
||||
}
|
||||
|
||||
private var aiMessageShowmagic:Boolean by Delegates.observable(false) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
checkScreenChange()
|
||||
}
|
||||
}
|
||||
|
||||
private var lastAiMessageTime:Long by Delegates.observable(System.currentTimeMillis()) { _, oldValue, newValue ->
|
||||
if (oldValue != newValue) {
|
||||
aiMessageShowmagic = true
|
||||
RxUtils.disposeSubscribe(lastAIMessageCountDown)
|
||||
lastAIMessageCountDown = RxUtils.createSubscribe(5_000) {
|
||||
aiMessageShowmagic = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private var lastAIMessageCountDown: Disposable? = null
|
||||
|
||||
override fun onCreate(owner: LifecycleOwner) {
|
||||
super.onCreate(owner)
|
||||
PM2ADASModel.INSTANCE.init(context)
|
||||
initListener()
|
||||
}
|
||||
|
||||
private fun initListener() {
|
||||
PM2ADASModel.INSTANCE.setAdasCallback(this)
|
||||
CommonModel.setRouteLineInfoCallback(TAG, this)
|
||||
BridgeManager.addBridgeListener(TAG,this)
|
||||
AIMessageManager.registerListener(this)
|
||||
}
|
||||
|
||||
private fun removeListener() {
|
||||
PM2ADASModel.INSTANCE.setAdasCallback(null)
|
||||
CommonModel.setRouteLineInfoCallback(TAG,null)
|
||||
CommonModel.releaseListeners()
|
||||
BridgeManager.removeBridgeListener(TAG)
|
||||
AIMessageManager.unregisterListener(this)
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
super.onDestroy(owner)
|
||||
removeListener()
|
||||
}
|
||||
|
||||
override fun updateHDMapStations(stations: MutableList<MutableList<Double>>) {
|
||||
for (i in stations.indices) {
|
||||
mView?.setMapMaker(M2_MAP_STATION_MAKER + i, stations[i])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun clearCustomPolyline() {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.clearCustomPolyline()
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateLineStations(stations: MutableList<BusStationBean>) {
|
||||
|
||||
val stationsList = mutableListOf<LatLng>()
|
||||
val stationsListPass = mutableListOf<LatLng>()
|
||||
var startStation: LatLng? = null
|
||||
var endStation: LatLng? = null
|
||||
|
||||
for (i in stations.indices) {
|
||||
val station = stations[i]
|
||||
val latLng = LatLng(station.gcjLat, station.gcjLon)
|
||||
if (i == 0) {
|
||||
startStation = latLng
|
||||
continue
|
||||
}
|
||||
if (i == stations.size - 1) {
|
||||
endStation = latLng
|
||||
continue
|
||||
}
|
||||
if (station.drivingStatus == 1) {//行驶信息,0初始值;1已经过;2当前站;3未到站
|
||||
stationsListPass.add(latLng)
|
||||
} else if (station.drivingStatus == 2) {
|
||||
if (station.isLeaving) {
|
||||
arrived = false
|
||||
stationsListPass.add(latLng)
|
||||
} else {
|
||||
arrived = true
|
||||
stationsList.add(latLng)
|
||||
}
|
||||
} else {
|
||||
stationsList.add(latLng)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateLineStations(stationsList, stationsListPass, startStation, endStation)
|
||||
}
|
||||
PM2ADASModel.INSTANCE.updateHDMapStations(stations)
|
||||
}
|
||||
|
||||
override fun removeHDMapStations() {
|
||||
mView?.removeMapMaker(M2_MAP_STATION_MAKER)
|
||||
}
|
||||
|
||||
override fun showNoTaskView(noLine: Boolean) {
|
||||
haveLine = !noLine
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.showNoTaskView(!noLine)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onTrajectoryHaveData(haveTrajectoryInfos: Boolean) {
|
||||
this.haveTrajectoryInfos = haveTrajectoryInfos
|
||||
// checkScreenChange()
|
||||
}
|
||||
|
||||
override fun onPredictionHavaData(havePredictionInfos: Boolean) {
|
||||
this.havePredictionInfos = havePredictionInfos
|
||||
// checkScreenChange()
|
||||
}
|
||||
|
||||
override fun onReceive(msg: AIMessage) {
|
||||
lastAiMessageTime = System.currentTimeMillis()
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
}
|
||||
|
||||
|
||||
fun checkScreenChange(){
|
||||
CallerLogger.d(TAG,"haveLine:$haveLine arrived:$arrived havePredictionInfos:$havePredictionInfos haveTrajectoryInfos:$haveTrajectoryInfos aiMessageShowmagic:$aiMessageShowmagic")
|
||||
BizLoopManager.runInMainThread{
|
||||
// 是否有订单
|
||||
if(haveLine){// 有订单
|
||||
if(arrived){//展示高德地图
|
||||
if(aiMessageShowmagic){
|
||||
updateMapFlag(false)
|
||||
// 展示高德地图+展示mogomind
|
||||
mView?.showAmap_mind()
|
||||
return@runInMainThread
|
||||
}else{
|
||||
updateMapFlag(false)
|
||||
// 展示高德地图
|
||||
mView?.showAmap()
|
||||
return@runInMainThread
|
||||
}
|
||||
}else{// 展示高精地图
|
||||
if(aiMessageShowmagic){
|
||||
updateMapFlag(false)
|
||||
// 展示高精地图
|
||||
mView?.showHDMap_mind()
|
||||
return@runInMainThread
|
||||
}else{
|
||||
// if(havePredictionInfos&&haveTrajectoryInfos){
|
||||
// updateMapFlag(true)
|
||||
// // 展示高精地图+展示预测和决策
|
||||
// mView?.showHDMap_aip_prediction()
|
||||
// return@runInMainThread
|
||||
// }else{
|
||||
updateMapFlag(false)
|
||||
// 展示高精地图
|
||||
mView?.showHDMap()
|
||||
return@runInMainThread
|
||||
// }
|
||||
}
|
||||
|
||||
}
|
||||
}else{// 没有订单
|
||||
if(aiMessageShowmagic){// 有mogomind 消息
|
||||
updateMapFlag(false)
|
||||
// 展示高精地图+mogoMind
|
||||
mView?.showHDMap_mind()
|
||||
}else{
|
||||
updateMapFlag(false)
|
||||
// 展示高精地图
|
||||
mView?.showHDMap()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateMapFlag(open: Boolean) {
|
||||
// if (open) {
|
||||
// FunctionBuildConfig.isDrawDecIdentifyData = true
|
||||
// FunctionBuildConfig.isDrawPreIdentifyData = true
|
||||
// } else {
|
||||
// FunctionBuildConfig.isDrawDecIdentifyData = false
|
||||
// FunctionBuildConfig.isDrawPreIdentifyData = false
|
||||
// }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.presenter
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.mogo.commons.mvp.Presenter
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.PM2ADASModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.line.PM2DrivingInfoFragment
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
|
||||
|
||||
class PM2DrivingPresenter(view: PM2DrivingInfoFragment?) :
|
||||
Presenter<PM2DrivingInfoFragment?>(view),
|
||||
ICommonCallback {
|
||||
|
||||
private val TAG = "PM2DrivingPresenter"
|
||||
|
||||
init {
|
||||
CommonModel.init(context)
|
||||
PM2ADASModel.INSTANCE.init(context)
|
||||
initListener()
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
super.onDestroy(owner)
|
||||
destroyListener()
|
||||
CommonModel.releaseListeners()
|
||||
}
|
||||
|
||||
private fun initListener(){
|
||||
CommonModel.setRouteLineInfoCallback(TAG,this)
|
||||
}
|
||||
|
||||
private fun destroyListener(){
|
||||
CommonModel.setRouteLineInfoCallback(TAG,null)
|
||||
}
|
||||
|
||||
override fun updateSpeed(speed: Int) {
|
||||
|
||||
}
|
||||
|
||||
override fun updateRemainMT(meters: Long, timeInSecond: Long) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateRemainMT(meters, timeInSecond) //米,秒
|
||||
}
|
||||
}
|
||||
|
||||
override fun showNoTaskView(empty: Boolean) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.showNoTaskView(empty)
|
||||
}
|
||||
if (empty){
|
||||
PM2ADASModel.INSTANCE.removeHDMapStations()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
override fun updateStationsInfo(stations: MutableList<BusStationBean>, i: Int, isArrived: Boolean) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateStationsInfo(stations,i,isArrived)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerRoadV2NEventWindowListenerManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapRoadListenerManager
|
||||
import com.mogo.eagle.core.utilcode.kotlin.onClick
|
||||
import com.mogo.eagle.core.utilcode.util.AppUtils
|
||||
import com.mogo.eagle.core.utilcode.util.UriUtils
|
||||
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
|
||||
import com.mogo.och.common.module.biz.media.MediaManager
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.manager.transform.OchTransform
|
||||
import com.mogo.och.common.module.manager.transform.OchTransformDispatch
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.presenter.PM2Presenter
|
||||
import com.mogo.och.common.module.wigets.media.MediaPlayerFragment
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.line.PM2DrivingInfoFragment
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.map.PM2HPMapFragment
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.AIMessageManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_fragment.test1
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_fragment.test2
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_fragment.test3
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_fragment.tv_shuttle_b2_p_version
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_fragment.video_fragment
|
||||
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/4/12
|
||||
*/
|
||||
class PM2BaseFragment :
|
||||
MvpFragment<PM2BaseFragment?, PM2Presenter?>() {
|
||||
|
||||
val TAG = PM2BaseFragment::class.java.simpleName
|
||||
|
||||
private var drivingFragment: PM2DrivingInfoFragment? = null
|
||||
private var hdMapFragment: PM2HPMapFragment? = null
|
||||
private var mediaFragment: MediaPlayerFragment? = null
|
||||
|
||||
// 视频直播流
|
||||
private val ochTransform = object : OchTransformDispatch {
|
||||
override fun setVideoView(target: View?) {
|
||||
super.setVideoView(target)
|
||||
if (target != null) {
|
||||
BizLoopManager.runInMainThread {
|
||||
target.id = R.id.video_show
|
||||
val params = FrameLayout.LayoutParams(
|
||||
ViewGroup.LayoutParams.MATCH_PARENT,
|
||||
ViewGroup.LayoutParams.MATCH_PARENT
|
||||
)
|
||||
video_fragment.addView(target, params)
|
||||
MediaManager.setMediaPause()
|
||||
}
|
||||
} else {
|
||||
BizLoopManager.runInMainThread {
|
||||
findViewById<View>(R.id.video_show)?.let {
|
||||
video_fragment.removeView(it)
|
||||
MediaManager.setMediaResume()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.shuttle_p_m2_fragment
|
||||
}
|
||||
|
||||
override fun getTagName(): String {
|
||||
return TAG
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
tv_shuttle_b2_p_version.text = "版本:${AppUtils.getAppVersionName()}"
|
||||
initFragment()
|
||||
OchTransform.addListener(TAG, ochTransform)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
OchTransform.removeListener(TAG)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化行程信息,高静地图,宣传 三个fragment
|
||||
*/
|
||||
private fun initFragment() {
|
||||
|
||||
if (drivingFragment == null) drivingFragment = PM2DrivingInfoFragment()
|
||||
childFragmentManager.beginTransaction().add(R.id.driving_fragment, drivingFragment!!)
|
||||
.show(drivingFragment!!).commitAllowingStateLoss()
|
||||
|
||||
if (hdMapFragment == null) hdMapFragment = PM2HPMapFragment()
|
||||
childFragmentManager.beginTransaction().add(R.id.hd_map_fragment, hdMapFragment!!)
|
||||
.show(hdMapFragment!!).commitAllowingStateLoss()
|
||||
|
||||
if (mediaFragment == null) mediaFragment = MediaPlayerFragment()
|
||||
childFragmentManager.beginTransaction().add(R.id.video_fragment, mediaFragment!!)
|
||||
.show(mediaFragment!!).commitAllowingStateLoss()
|
||||
|
||||
|
||||
test1.onClick {
|
||||
CallerRoadV2NEventWindowListenerManager.showImage(
|
||||
System.currentTimeMillis().toString(),
|
||||
System.currentTimeMillis(),
|
||||
EventTypeEnumNew.getUpdateIconRes(EventTypeEnumNew.TYPE_USECASE_ROAD_BUS_STATION.poiType),
|
||||
String.format(
|
||||
EventTypeEnumNew.getAlarmContent(EventTypeEnumNew.TYPE_USECASE_ROAD_BUS_STATION.poiType),
|
||||
100
|
||||
),
|
||||
false,
|
||||
EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ROAD_BUS_STATION.poiType),
|
||||
UriUtils.res2Uri(
|
||||
EventTypeEnumNew.getPoiTypeBg(
|
||||
EventTypeEnumNew.TYPE_USECASE_ROAD_BUS_STATION.poiType,
|
||||
false
|
||||
).toString()
|
||||
).toString()
|
||||
)
|
||||
}
|
||||
test2.onClick {
|
||||
CallerMapRoadListenerManager.invokeCrossDevice(true)
|
||||
}
|
||||
test3.onClick {
|
||||
val one = RoadMsg(201,1,true,false)
|
||||
val two = RoadMsg(202,2,false,false)
|
||||
val three = RoadMsg(203,3,false,true)
|
||||
|
||||
val sortedList = ArrayList<RoadMsg>()
|
||||
sortedList.add(one)
|
||||
sortedList.add(two)
|
||||
sortedList.add(three)
|
||||
val ndeEvent = AIMessage.NDEData(System.currentTimeMillis().toString(),"路口车龙","前方路口有车龙",sortedList)
|
||||
AIMessageManager.post(ndeEvent)
|
||||
|
||||
// CallerRoadV2NEventWindowListenerManager.showImage(
|
||||
// System.currentTimeMillis().toString(),
|
||||
// System.currentTimeMillis(),
|
||||
// EventTypeEnumNew.getUpdateIconRes(EventTypeEnumNew.TYPE_USECASE_ROAD_BUS_STATION.poiType),
|
||||
// String.format(
|
||||
// EventTypeEnumNew.getAlarmContent(EventTypeEnumNew.TYPE_USECASE_ROAD_BUS_STATION.poiType),
|
||||
// 100
|
||||
// ),
|
||||
// false,
|
||||
// String.format(
|
||||
// EventTypeEnumNew.getWarningTts(EventTypeEnumNew.TYPE_USECASE_ROAD_BUS_STATION.poiType),
|
||||
// 100
|
||||
// ),
|
||||
// UriUtils.res2Uri(
|
||||
// EventTypeEnumNew.getPoiTypeBg(
|
||||
// EventTypeEnumNew.TYPE_USECASE_ROAD_BUS_STATION.poiType,
|
||||
// false
|
||||
// ).toString()
|
||||
// ).toString()
|
||||
// )
|
||||
}
|
||||
}
|
||||
|
||||
override fun createPresenter(): PM2Presenter {
|
||||
return PM2Presenter(this)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.presenter.PM2DrivingPresenter
|
||||
import com.mogo.och.common.module.utils.NumberFormatUtil
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.arriveView
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.emptyView
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.lineView
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/4/12
|
||||
*/
|
||||
class PM2DrivingInfoFragment :
|
||||
MvpFragment<PM2DrivingInfoFragment?, PM2DrivingPresenter?>() {
|
||||
|
||||
|
||||
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.shuttle_p_m2_driving_info_fragment
|
||||
}
|
||||
|
||||
override fun getTagName(): String {
|
||||
return TAG
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
|
||||
}
|
||||
|
||||
override fun initViews(savedInstanceState: Bundle?) {
|
||||
super.initViews(savedInstanceState)
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
mPresenter?.onDestroy(this)
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
fun showNoTaskView(haveTask: Boolean) {
|
||||
if(haveTask){
|
||||
emptyView.visibility = View.VISIBLE
|
||||
arriveView.visibility = View.GONE
|
||||
lineView.visibility = View.GONE
|
||||
}else{
|
||||
emptyView.visibility = View.GONE
|
||||
arriveView.visibility = View.GONE
|
||||
lineView.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
override fun createPresenter(): PM2DrivingPresenter {
|
||||
return PM2DrivingPresenter(this)
|
||||
}
|
||||
|
||||
fun updateStationsInfo(stations: MutableList<BusStationBean>, i: Int, isArrived: Boolean) {
|
||||
if(stations.isEmpty()){
|
||||
emptyView.visibility = View.VISIBLE
|
||||
arriveView.visibility = View.GONE
|
||||
lineView.visibility = View.GONE
|
||||
}else{
|
||||
if(isArrived&&i!=0){
|
||||
emptyView.visibility = View.GONE
|
||||
arriveView.visibility = View.VISIBLE
|
||||
lineView.visibility = View.GONE
|
||||
arriveView.setArrivedStation(stations.get(i))
|
||||
}else{
|
||||
emptyView.visibility = View.GONE
|
||||
arriveView.visibility = View.GONE
|
||||
lineView.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 剩余里程和时间
|
||||
*/
|
||||
fun updateRemainMT(meters: Long, timeInSecond: Long) { //米。秒
|
||||
var disUnit = "公里"
|
||||
var remainDis: String? = "0"
|
||||
|
||||
if (meters > 0) {
|
||||
if (meters / 1000 < 1) {
|
||||
disUnit = "米"
|
||||
remainDis = meters.toFloat().roundToInt().toString()
|
||||
} else {
|
||||
disUnit = "公里"
|
||||
remainDis = NumberFormatUtil.formatLong(meters.toDouble() / 1000)
|
||||
}
|
||||
}
|
||||
|
||||
val time = ceil(timeInSecond / 60f).toInt()
|
||||
|
||||
// "$remainDis$disUnit".also { tv_distance.text = it }
|
||||
// "${time}分钟".also { tv_left_time.text = it }
|
||||
}
|
||||
|
||||
|
||||
companion object {
|
||||
private val TAG = PM2DrivingInfoFragment::class.java.simpleName
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,139 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.arrive
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import kotlinx.android.synthetic.main.m2_arrive_view.view.aciv_arrow_left
|
||||
import kotlinx.android.synthetic.main.m2_arrive_view.view.aciv_arrow_right
|
||||
import kotlinx.android.synthetic.main.m2_arrive_view.view.aciv_door_left
|
||||
import kotlinx.android.synthetic.main.m2_arrive_view.view.aciv_door_right
|
||||
import kotlinx.android.synthetic.main.m2_arrive_view.view.iv_animal_list
|
||||
import kotlinx.android.synthetic.main.m2_arrive_view.view.ochtv_arrive_station_value
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
|
||||
class ArrivedView : ConstraintLayout {
|
||||
|
||||
private val TAG = "ArrivedView"
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
|
||||
|
||||
val marginMax = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),-137f)
|
||||
val marginMin = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),-55f)
|
||||
|
||||
val animatorArrow = ValueAnimator.ofInt(0, 30).apply {
|
||||
duration = 500
|
||||
repeatMode = ValueAnimator.REVERSE
|
||||
repeatCount = -1
|
||||
addUpdateListener { animation ->
|
||||
val index = animation.animatedValue as Int
|
||||
val paramsLeft = aciv_arrow_left.layoutParams as LayoutParams
|
||||
paramsLeft.marginEnd = index
|
||||
aciv_arrow_left.layoutParams = paramsLeft
|
||||
|
||||
val paramsRight = aciv_arrow_right.layoutParams as LayoutParams
|
||||
paramsRight.marginStart = index
|
||||
aciv_arrow_right.layoutParams = paramsRight
|
||||
}
|
||||
}
|
||||
|
||||
val animator = ValueAnimator.ofInt(marginMax, marginMin).apply {
|
||||
duration = 500
|
||||
addUpdateListener { animation ->
|
||||
val index = animation.animatedValue as Int
|
||||
val paramsLeft = aciv_door_left.layoutParams as LayoutParams
|
||||
paramsLeft.marginEnd = index
|
||||
aciv_door_left.layoutParams = paramsLeft
|
||||
|
||||
val paramsRight = aciv_door_right.layoutParams as LayoutParams
|
||||
paramsRight.marginStart = index
|
||||
aciv_door_right.layoutParams = paramsRight
|
||||
|
||||
if(index==-100){
|
||||
aciv_arrow_left.visibility = VISIBLE
|
||||
aciv_arrow_right.visibility = VISIBLE
|
||||
}
|
||||
}
|
||||
addListener(object : AnimatorListenerAdapter() {
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
animatorArrow.start()
|
||||
CallerLogger.d(TAG,"动画结束了")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
LayoutInflater.from(context).inflate(R.layout.m2_arrive_view, this, true)
|
||||
|
||||
ochtv_arrive_station_value.setVertrial(true)
|
||||
val intArrayOf = intArrayOf(
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_43cefe),
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_1466fb),
|
||||
)
|
||||
ochtv_arrive_station_value.setmColorList(intArrayOf)
|
||||
|
||||
}
|
||||
|
||||
override fun onVisibilityAggregated(isVisible: Boolean) {
|
||||
super.onVisibilityAggregated(isVisible)
|
||||
CallerLogger.d(TAG,"isVisible:${isVisible}")
|
||||
if(isVisible) {
|
||||
if(!animator.isRunning){
|
||||
animator.start()
|
||||
}
|
||||
iv_animal_list.visibility = View.VISIBLE
|
||||
val animationDrawable = iv_animal_list.drawable as AnimationDrawable
|
||||
animationDrawable.start()
|
||||
}else{
|
||||
animator.cancel()
|
||||
val paramsLeft = aciv_door_left.layoutParams as LayoutParams
|
||||
paramsLeft.marginEnd =marginMax
|
||||
aciv_door_left.layoutParams = paramsLeft
|
||||
|
||||
val paramsRight = aciv_door_right.layoutParams as LayoutParams
|
||||
paramsRight.marginStart = marginMax
|
||||
aciv_door_right.layoutParams = paramsRight
|
||||
|
||||
aciv_arrow_left.visibility = GONE
|
||||
aciv_arrow_right.visibility = GONE
|
||||
animatorArrow.cancel()
|
||||
|
||||
iv_animal_list.visibility = View.VISIBLE
|
||||
val animationDrawable = iv_animal_list.drawable as AnimationDrawable
|
||||
animationDrawable.stop()
|
||||
}
|
||||
}
|
||||
|
||||
fun setArrivedStation(busStationBean: BusStationBean) {
|
||||
BizLoopManager.runInMainThread{
|
||||
ochtv_arrive_station_value.text = busStationBean.name
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
initView()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.autopilot
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView
|
||||
import com.mogo.och.bridge.autopilot.location.OchLocationManager
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import kotlinx.android.synthetic.main.m2_speed.view.tv_speed
|
||||
import kotlin.math.abs
|
||||
|
||||
class AutopilotView : ConstraintLayout {
|
||||
|
||||
private val TAG = "ItineraryView"
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
|
||||
|
||||
private fun initView() {
|
||||
LayoutInflater.from(context).inflate(R.layout.m2_autopilot, this, true)
|
||||
}
|
||||
|
||||
override fun onVisibilityAggregated(isVisible: Boolean) {
|
||||
super.onVisibilityAggregated(isVisible)
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
initView()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.widget
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.autopilot.light
|
||||
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ObjectAnimator
|
||||
@@ -16,11 +16,9 @@ import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.common.module.manager.light.TurnLightManager
|
||||
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_turn_light_status.view.left_nor_image
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_turn_light_status.view.left_select_image
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_turn_light_status.view.right_nor_image
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_turn_light_status.view.right_select_image
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_turn_light_status.view.turn_light_layout
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
@@ -43,8 +41,7 @@ class M2TurnLightView @JvmOverloads constructor(
|
||||
private var isDisappear: Boolean = false
|
||||
|
||||
init {
|
||||
LayoutInflater.from(context)
|
||||
.inflate(R.layout.shuttle_p_m2_turn_light_status, this, true)
|
||||
LayoutInflater.from(context).inflate(R.layout.shuttle_p_m2_turn_light_status, this, true)
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
@@ -126,12 +123,12 @@ class M2TurnLightView @JvmOverloads constructor(
|
||||
appearAnimation.duration = 300
|
||||
val appearAnimationImage = AlphaAnimation(0f, 1.0f)
|
||||
appearAnimation.duration = 500
|
||||
turn_light_layout.startAnimation(appearAnimation)
|
||||
left_nor_image.startAnimation(appearAnimationImage)
|
||||
// turn_light_layout.startAnimation(appearAnimation)
|
||||
// left_nor_image.startAnimation(appearAnimationImage)
|
||||
right_nor_image.startAnimation(appearAnimationImage)
|
||||
|
||||
turn_light_layout.visibility = View.VISIBLE
|
||||
left_nor_image.visibility = View.VISIBLE
|
||||
// turn_light_layout.visibility = View.VISIBLE
|
||||
// left_nor_image.visibility = View.VISIBLE
|
||||
right_nor_image.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
@@ -142,19 +139,15 @@ class M2TurnLightView @JvmOverloads constructor(
|
||||
left_select_image.clearAnimation()
|
||||
right_select_image.clearAnimation()
|
||||
|
||||
left_nor_image.clearAnimation()
|
||||
//left_nor_image.clearAnimation()
|
||||
right_nor_image.clearAnimation()
|
||||
turn_light_layout.clearAnimation()
|
||||
|
||||
val disappearAnimationLeft = AlphaAnimation(1.0f, 0f)
|
||||
disappearAnimationLeft.duration = 300
|
||||
|
||||
val disappearAnimationBg = AlphaAnimation(1.0f, 0f)
|
||||
disappearAnimationBg.duration = 500
|
||||
|
||||
left_nor_image.startAnimation(disappearAnimationLeft)
|
||||
//left_nor_image.startAnimation(disappearAnimationLeft)
|
||||
right_nor_image.startAnimation(disappearAnimationLeft)
|
||||
turn_light_layout.startAnimation(disappearAnimationBg)
|
||||
|
||||
|
||||
disappearAnimationLeft.setAnimationListener(object : Animation.AnimationListener {
|
||||
override fun onAnimationRepeat(p0: Animation?) {
|
||||
@@ -164,20 +157,8 @@ class M2TurnLightView @JvmOverloads constructor(
|
||||
}
|
||||
|
||||
override fun onAnimationEnd(p0: Animation?) {
|
||||
left_nor_image.visibility = View.GONE
|
||||
right_nor_image.visibility = View.GONE
|
||||
}
|
||||
})
|
||||
|
||||
disappearAnimationBg.setAnimationListener(object : Animation.AnimationListener {
|
||||
override fun onAnimationRepeat(p0: Animation?) {
|
||||
}
|
||||
|
||||
override fun onAnimationStart(p0: Animation?) {
|
||||
}
|
||||
|
||||
override fun onAnimationEnd(p0: Animation?) {
|
||||
turn_light_layout.visibility = View.GONE
|
||||
// left_nor_image.visibility = View.GONE
|
||||
// right_nor_image.visibility = View.GONE
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.autopilot.speed
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView
|
||||
import com.mogo.och.bridge.autopilot.location.OchLocationManager
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import kotlinx.android.synthetic.main.m2_speed.view.tv_speed
|
||||
import kotlin.math.abs
|
||||
|
||||
class SpeedView : ConstraintLayout, IMoGoChassisLocationGCJ02Listener {
|
||||
|
||||
private val TAG = "ItineraryView"
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
|
||||
|
||||
private fun initView() {
|
||||
LayoutInflater.from(context).inflate(R.layout.m2_speed, this, true)
|
||||
|
||||
tv_speed.setOnLongClickListener {
|
||||
context?.let { ToggleDebugView.toggleDebugView.toggle(it) }
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onVisibilityAggregated(isVisible: Boolean) {
|
||||
super.onVisibilityAggregated(isVisible)
|
||||
if(isVisible){
|
||||
OchLocationManager.addGCJ02Listener(TAG, 3, this)
|
||||
}else{
|
||||
OchLocationManager.removeGCJ02Listener(TAG)
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
initView()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
|
||||
mogoLocation?.let {
|
||||
BizLoopManager.runInMainThread {
|
||||
val speedKM = (abs(it.gnssSpeed) * 3.6f).toInt()
|
||||
tv_speed.text = speedKM.toString()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.autopilot.status
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
|
||||
|
||||
class StatusView : AppCompatTextView, ICommonCallback {
|
||||
|
||||
private val TAG = "ItineraryView"
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
|
||||
|
||||
private fun initView() {
|
||||
|
||||
}
|
||||
|
||||
override fun onVisibilityAggregated(isVisible: Boolean) {
|
||||
super.onVisibilityAggregated(isVisible)
|
||||
if(isVisible){
|
||||
CommonModel.setRouteLineInfoCallback(TAG,this)
|
||||
}else{
|
||||
CommonModel.setRouteLineInfoCallback(TAG,null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateAutoStatus(isAutoPilot: Boolean) {
|
||||
BizLoopManager.runInMainThread {
|
||||
context?.let {
|
||||
if (isAutoPilot) {
|
||||
setTextColor(ContextCompat.getColor(it, R.color.common_FFFFFF))
|
||||
background = ContextCompat.getDrawable(it, R.drawable.m2_autopilot_status_in)
|
||||
} else {
|
||||
setTextColor(ContextCompat.getColor(it, R.color.common_284F7E))
|
||||
background = ContextCompat.getDrawable(it, R.drawable.m2_autopilot_status_out)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
initView()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.empty
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import kotlinx.android.synthetic.main.m2_empty_view.view.tv_title
|
||||
|
||||
class EmptyView : ConstraintLayout {
|
||||
|
||||
private val TAG = "EmptyView"
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
|
||||
|
||||
private fun initView() {
|
||||
LayoutInflater.from(context).inflate(R.layout.m2_empty_view, this, true)
|
||||
|
||||
tv_title.setVertrial(true)
|
||||
val intArrayOf = intArrayOf(
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_43cefe),
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_1466fb),
|
||||
)
|
||||
tv_title.setmColorList(intArrayOf)
|
||||
}
|
||||
|
||||
override fun onVisibilityAggregated(isVisible: Boolean) {
|
||||
super.onVisibilityAggregated(isVisible)
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
initView()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.lineinfo
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.findViewTreeViewModelStoreOwner
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.eagle.core.utilcode.kotlin.onClick
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.view.SpacesItemDecoration
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.wigets.WrapContentLinearLayoutManager
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.line.lineinfo.item.ItemDecoration
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.line.lineinfo.item.StationAdapter
|
||||
import kotlinx.android.synthetic.main.m2_line_view.view.autoplit_info
|
||||
import kotlinx.android.synthetic.main.m2_line_view.view.ll_station_container
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
|
||||
class LineView : ConstraintLayout, LineViewModel.LineViewCallback {
|
||||
|
||||
private val TAG = "EmptyView"
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
|
||||
|
||||
private lateinit var mAdapter: StationAdapter
|
||||
|
||||
private lateinit var linearLayoutManager: LinearLayoutManager
|
||||
|
||||
private var viewModel:LineViewModel?=null
|
||||
|
||||
|
||||
|
||||
private fun initView() {
|
||||
LayoutInflater.from(context).inflate(R.layout.m2_line_view, this, true)
|
||||
|
||||
linearLayoutManager = LinearLayoutManager(context)
|
||||
ll_station_container.setLayoutManager(linearLayoutManager)
|
||||
mAdapter = StationAdapter()
|
||||
ll_station_container.addItemDecoration(ItemDecoration())
|
||||
|
||||
ll_station_container.setAdapter(mAdapter)
|
||||
|
||||
ll_station_container.itemAnimator?.addDuration = 0;
|
||||
ll_station_container.itemAnimator?.changeDuration = 0;
|
||||
ll_station_container.itemAnimator?.moveDuration = 0;
|
||||
ll_station_container.itemAnimator?.removeDuration = 0;
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
viewModel = findViewTreeViewModelStoreOwner()?.let {
|
||||
ViewModelProvider(it).get(LineViewModel::class.java)
|
||||
}
|
||||
viewModel?.setLineCallback(this)
|
||||
}
|
||||
|
||||
override fun onVisibilityAggregated(isVisible: Boolean) {
|
||||
super.onVisibilityAggregated(isVisible)
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
initView()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateLineStations(stations: MutableList<BusStationBean>?) {
|
||||
CallerLogger.d(TAG,"展示站点:${stations}")
|
||||
mAdapter.submitList(stations)
|
||||
}
|
||||
|
||||
override fun updateRemainMt(distance: String, time: String) {
|
||||
BizLoopManager.runInMainThread{
|
||||
mAdapter.notifyDistanceAndTime(distance,time)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.lineinfo
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.utils.NumberFormatUtil
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
|
||||
import io.reactivex.disposables.Disposable
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* @author XuXinChao
|
||||
* @description BadCase录包管理页面
|
||||
* @since: 2022/12/15
|
||||
*/
|
||||
class LineViewModel : ViewModel(), ICommonCallback {
|
||||
|
||||
private val TAG = M_BUS+LineViewModel::class.java.simpleName
|
||||
|
||||
private var viewCallback:LineViewCallback?=null
|
||||
|
||||
private var endTaskDisposable:Disposable?=null
|
||||
|
||||
|
||||
override fun onCleared() {
|
||||
d(TAG,"onCleared")
|
||||
CommonModel.setRouteLineInfoCallback(TAG,null)
|
||||
}
|
||||
|
||||
fun setLineCallback(viewCallback:LineViewCallback){
|
||||
this.viewCallback = viewCallback
|
||||
CommonModel.setRouteLineInfoCallback(TAG,this)
|
||||
}
|
||||
|
||||
override fun updateLineStations(stations: MutableList<BusStationBean>?) {
|
||||
BizLoopManager.runInMainThread{
|
||||
this.viewCallback?.updateLineStations(stations)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateRemainMT(meters: Long, timeInSecond: Long) {
|
||||
super.updateRemainMT(meters, timeInSecond)
|
||||
var disUnit = "公里"
|
||||
var remainDis: String? = "0"
|
||||
|
||||
if (meters > 0) {
|
||||
if (meters / 1000 < 1) {
|
||||
disUnit = "米"
|
||||
remainDis = meters.toFloat().roundToInt().toString()
|
||||
} else {
|
||||
disUnit = "公里"
|
||||
remainDis = NumberFormatUtil.formatLong(meters.toDouble() / 1000)
|
||||
}
|
||||
}
|
||||
|
||||
val time = ceil(timeInSecond / 60f).toInt()
|
||||
|
||||
// "$remainDis$disUnit".also { tv_distance.text = it }
|
||||
// "${time}分钟".also { tv_left_time.text = it }
|
||||
|
||||
this.viewCallback?.updateRemainMt("$remainDis$disUnit","${time}分钟")
|
||||
}
|
||||
|
||||
interface LineViewCallback{
|
||||
fun updateLineStations(stations: MutableList<BusStationBean>?)
|
||||
fun updateRemainMt(distance: String, time: String)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.lineinfo.item
|
||||
|
||||
import android.graphics.Rect
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
|
||||
/**
|
||||
* 这是LinearLayoutManager设置Item间距的的一个辅助类
|
||||
*
|
||||
* @author donghongyu
|
||||
*/
|
||||
class ItemDecoration() : RecyclerView.ItemDecoration() {
|
||||
override fun getItemOffsets(
|
||||
outRect: Rect, view: View,
|
||||
parent: RecyclerView, state: RecyclerView.State
|
||||
) {
|
||||
if((parent.adapter?.itemCount ?: 4) < 4) {
|
||||
val height = AutoSizeUtils.dp2px(parent.context, 140f)
|
||||
|
||||
val layoutParams = view.layoutParams as RecyclerView.LayoutParams
|
||||
layoutParams.height = height
|
||||
view.layoutParams = layoutParams
|
||||
}else if((parent.adapter?.itemCount ?: 4) == 4){
|
||||
val height = AutoSizeUtils.dp2px(parent.context, 100f)
|
||||
|
||||
val layoutParams = view.layoutParams as RecyclerView.LayoutParams
|
||||
layoutParams.height = height
|
||||
view.layoutParams = layoutParams
|
||||
}else{
|
||||
val height = AutoSizeUtils.dp2px(parent.context,68f)
|
||||
val layoutParams = view.layoutParams as RecyclerView.LayoutParams
|
||||
layoutParams.height = height
|
||||
view.layoutParams = layoutParams
|
||||
}
|
||||
|
||||
|
||||
super.getItemOffsets(outRect, view, parent, state)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,178 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.lineinfo.item
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
|
||||
class StationAdapter : ListAdapter<BusStationBean, StationViewHolder>(MessageDiffCallback()) {
|
||||
|
||||
var currentIndex = 0
|
||||
var isLeaving = false
|
||||
var showPassOmit = false
|
||||
var showFuluterOmit = false
|
||||
|
||||
var distanceAndTime = ""
|
||||
|
||||
override fun submitList(list: MutableList<BusStationBean>?) {
|
||||
val newDataList = mutableListOf<BusStationBean>()
|
||||
list?.let {
|
||||
it.forEachIndexed { index, busStationBean ->
|
||||
if (busStationBean.drivingStatus == 2) {
|
||||
currentIndex = index
|
||||
isLeaving = busStationBean.isLeaving
|
||||
return@forEachIndexed
|
||||
}
|
||||
}
|
||||
if (isLeaving) {
|
||||
currentIndex += 1
|
||||
}
|
||||
if ((it.size) <= 7) {
|
||||
showPassOmit = false
|
||||
showFuluterOmit = false
|
||||
newDataList.addAll(it.toList())
|
||||
} else {
|
||||
if(currentIndex-1<3){
|
||||
showPassOmit = false // 全展示
|
||||
}else{
|
||||
showPassOmit = true // 展示省略
|
||||
}
|
||||
|
||||
if(it.size-(currentIndex+1)-1<3) {// 全展示
|
||||
showFuluterOmit = false
|
||||
}else{// 展示省略
|
||||
showFuluterOmit = true
|
||||
}
|
||||
|
||||
if(showPassOmit&&showFuluterOmit){// 都有
|
||||
newDataList.add(it.first())
|
||||
newDataList.add(StationBeanOmit(currentIndex-1-1))
|
||||
newDataList.addAll(list.slice(currentIndex-1 .. currentIndex+1))
|
||||
newDataList.add(StationBeanOmit(list.size-(currentIndex+3)))// 减去+1 省略 和最后一个
|
||||
newDataList.add(list.last())
|
||||
}else{
|
||||
if(showFuluterOmit||showPassOmit){
|
||||
if(showFuluterOmit){// 只展示下面的省略号
|
||||
newDataList.addAll(list.subList(0,5))
|
||||
newDataList.add(StationBeanOmit(list.size-5-1))
|
||||
newDataList.add(list.last())
|
||||
}
|
||||
if(showPassOmit){// 只展示上面的手机号
|
||||
newDataList.add(list.first())
|
||||
newDataList.add(StationBeanOmit(list.size-5-1))
|
||||
newDataList.addAll(list.slice(list.size-5 until list.size))
|
||||
} else {
|
||||
|
||||
}
|
||||
}else{
|
||||
newDataList.addAll(it.toList())
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newDataList.forEachIndexed { index, busStationBean ->
|
||||
if (busStationBean.drivingStatus == 2) {
|
||||
currentIndex = index
|
||||
isLeaving = busStationBean.isLeaving
|
||||
if(isLeaving){
|
||||
currentIndex+=1
|
||||
}
|
||||
}
|
||||
}
|
||||
distanceAndTime = ""
|
||||
super.submitList(newDataList)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: StationViewHolder, position: Int) {
|
||||
getItem(position)?.let {
|
||||
holder.bind(it,distanceAndTime)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StationViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
return when (viewType) {
|
||||
StationViewHolder.NormalStationStart -> NormalStationStartViewHolder(
|
||||
inflater.inflate(R.layout.m2_station_normal_start_view, parent, false)
|
||||
)
|
||||
StationViewHolder.NormalStationEnd -> NormalStationEndViewHolder(
|
||||
inflater.inflate(R.layout.m2_station_normal_end_view, parent, false)
|
||||
)
|
||||
StationViewHolder.NormalStationFuture -> NormalStationFutureViewHolder(
|
||||
inflater.inflate(R.layout.m2_station_normal_future_view, parent, false)
|
||||
)
|
||||
StationViewHolder.NormalStationPass -> NormalStationPassViewHolder(
|
||||
inflater.inflate(R.layout.m2_station_normal_pass_view, parent, false)
|
||||
)
|
||||
|
||||
StationViewHolder.CurrentStationStart -> CurrentStationStartViewHolder(
|
||||
inflater.inflate(R.layout.m2_station_current_start_view, parent, false)
|
||||
)
|
||||
StationViewHolder.CurrentStationEnd -> CurrentStationEndViewHolder(
|
||||
inflater.inflate(R.layout.m2_station_current_end_view, parent, false)
|
||||
)
|
||||
StationViewHolder.CurrentStation -> CurrentStationViewHolder(
|
||||
inflater.inflate(R.layout.m2_station_current_view, parent, false)
|
||||
)
|
||||
|
||||
StationViewHolder.OmitStationPass -> OmitPassViewHolder(
|
||||
inflater.inflate(R.layout.m2_station_omit_view_pass, parent,false)
|
||||
)
|
||||
StationViewHolder.OmitStationFuture -> OmitFutureViewHolder(
|
||||
inflater.inflate(R.layout.m2_station_omit_view_future, parent,false)
|
||||
)
|
||||
|
||||
else -> throw IllegalArgumentException("Invalid view type")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
if (getItem(position) is StationBeanOmit) {
|
||||
return if (position < currentIndex) {
|
||||
StationViewHolder.OmitStationPass
|
||||
} else {
|
||||
StationViewHolder.OmitStationFuture
|
||||
}
|
||||
}
|
||||
when (position) {
|
||||
0 -> {
|
||||
return if (currentIndex == position) {
|
||||
StationViewHolder.CurrentStationStart
|
||||
} else {
|
||||
StationViewHolder.NormalStationStart
|
||||
}
|
||||
}
|
||||
|
||||
itemCount - 1 -> {
|
||||
return if (currentIndex == position) {
|
||||
StationViewHolder.CurrentStationEnd
|
||||
} else {
|
||||
StationViewHolder.NormalStationEnd
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
return if (currentIndex == position) {
|
||||
StationViewHolder.CurrentStation
|
||||
} else if (currentIndex < position) {
|
||||
StationViewHolder.NormalStationFuture
|
||||
} else {
|
||||
StationViewHolder.NormalStationPass
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewRecycled(holder: StationViewHolder) {
|
||||
super.onViewRecycled(holder)
|
||||
holder.viewRecycled(holder)
|
||||
}
|
||||
|
||||
fun notifyDistanceAndTime(distance: String, time: String) {
|
||||
distanceAndTime = "${distance}·${time}"
|
||||
notifyItemChanged(currentIndex)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.lineinfo.item
|
||||
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
|
||||
class MessageDiffCallback: DiffUtil.ItemCallback<BusStationBean>() {
|
||||
|
||||
override fun areContentsTheSame(oldItem: BusStationBean, newItem: BusStationBean): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
|
||||
override fun areItemsTheSame(oldItem: BusStationBean, newItem: BusStationBean): Boolean {
|
||||
return oldItem.siteId == newItem.siteId
|
||||
}
|
||||
}
|
||||
|
||||
data class StationBeanOmit(var coutOmit:Int):BusStationBean()
|
||||
@@ -0,0 +1,123 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.line.lineinfo.item
|
||||
|
||||
import android.view.View
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.common.module.wigets.OCHGradientTextView
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
|
||||
|
||||
abstract class StationViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
abstract fun bind(item: BusStationBean,distanceAndView:String)
|
||||
open fun viewRecycled(holder: StationViewHolder){}
|
||||
private val sampleDateFormat = SimpleDateFormat("HH:mm", Locale.CHINA)
|
||||
protected val TAG = javaClass.simpleName
|
||||
|
||||
companion object{
|
||||
val CurrentStationStart = 0
|
||||
val CurrentStationEnd = 1
|
||||
val CurrentStation = 2
|
||||
|
||||
val NormalStationStart = 3
|
||||
var NormalStationEnd = 4
|
||||
val NormalStationPass = 5
|
||||
val NormalStationFuture = 6
|
||||
|
||||
val OmitStationPass = 7
|
||||
val OmitStationFuture = 8
|
||||
}
|
||||
}
|
||||
|
||||
class NormalStationStartViewHolder(binding: View) : StationViewHolder(binding) {
|
||||
private var startStaionName: AppCompatTextView = binding.findViewById(R.id.actv_normal_station_start)
|
||||
override fun bind(item: BusStationBean,distanceAndView:String) {
|
||||
startStaionName.text = item.name
|
||||
}
|
||||
}
|
||||
class NormalStationEndViewHolder(binding: View) : StationViewHolder(binding) {
|
||||
private var endStaionName: AppCompatTextView = binding.findViewById(R.id.actv_normal_station_end)
|
||||
override fun bind(item: BusStationBean,distanceAndView:String) {
|
||||
endStaionName.text = item.name
|
||||
}
|
||||
}
|
||||
class NormalStationPassViewHolder(binding: View) : StationViewHolder(binding) {
|
||||
private var passStaionName: AppCompatTextView = binding.findViewById(R.id.actv_normal_station_pass)
|
||||
override fun bind(item: BusStationBean,distanceAndView:String) {
|
||||
passStaionName.text = item.name
|
||||
}
|
||||
}
|
||||
class NormalStationFutureViewHolder(binding: View) : StationViewHolder(binding) {
|
||||
private var futureStaionName: AppCompatTextView = binding.findViewById(R.id.actv_normal_station_future)
|
||||
override fun bind(item: BusStationBean,distanceAndView:String) {
|
||||
futureStaionName.text = item.name
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class CurrentStationViewHolder(binding: View) : StationViewHolder(binding) {
|
||||
private var currentStaionName: OCHGradientTextView = binding.findViewById(R.id.och_current_station_name)
|
||||
private var actv_distance: AppCompatTextView = binding.findViewById(R.id.actv_distance)
|
||||
override fun bind(item: BusStationBean,distanceAndView:String) {
|
||||
var text = item.name
|
||||
if(text.length>12){
|
||||
text = text.slice(0..10)+"…"
|
||||
}
|
||||
currentStaionName.text = text
|
||||
currentStaionName.setVertrial(true)
|
||||
val intArrayOf = intArrayOf(
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_43cefe),
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_1466fb),
|
||||
)
|
||||
currentStaionName.setmColorList(intArrayOf)
|
||||
actv_distance.text = distanceAndView
|
||||
}
|
||||
}
|
||||
class CurrentStationStartViewHolder(binding: View) : StationViewHolder(binding) {
|
||||
private var currentStaionStartName: OCHGradientTextView = binding.findViewById(R.id.och_current_station_start_name)
|
||||
override fun bind(item: BusStationBean,distanceAndView:String) {
|
||||
currentStaionStartName.text = item.name
|
||||
val intArrayOf = intArrayOf(
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_43cefe),
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_1466fb),
|
||||
)
|
||||
currentStaionStartName.setmColorList(intArrayOf)
|
||||
}
|
||||
}
|
||||
class CurrentStationEndViewHolder(binding: View) : StationViewHolder(binding) {
|
||||
private var currentStaionEndName: OCHGradientTextView = binding.findViewById(R.id.och_current_station_end_name)
|
||||
private var actv_distance_end: AppCompatTextView = binding.findViewById(R.id.actv_distance_end)
|
||||
override fun bind(item: BusStationBean,distanceAndView:String) {
|
||||
var text = item.name
|
||||
if(text.length>12){
|
||||
text = text.slice(0..10)+"…"
|
||||
}
|
||||
currentStaionEndName.text = text
|
||||
val intArrayOf = intArrayOf(
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_43cefe),
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_1466fb),
|
||||
)
|
||||
currentStaionEndName.setmColorList(intArrayOf)
|
||||
actv_distance_end.text = distanceAndView
|
||||
}
|
||||
}
|
||||
|
||||
class OmitPassViewHolder(binding: View) : StationViewHolder(binding) {
|
||||
private var omitCout: AppCompatTextView = binding.findViewById(R.id.actv_pass_omit_cout)
|
||||
override fun bind(item: BusStationBean,distanceAndView:String) {
|
||||
if(item is StationBeanOmit){
|
||||
omitCout.text = "${item.coutOmit}站"
|
||||
}
|
||||
}
|
||||
}
|
||||
class OmitFutureViewHolder(binding: View) : StationViewHolder(binding) {
|
||||
private var omitCout: AppCompatTextView = binding.findViewById(R.id.actv_future_omit_count)
|
||||
override fun bind(item: BusStationBean,distanceAndView:String) {
|
||||
if(item is StationBeanOmit){
|
||||
omitCout.text = "${item.coutOmit}站"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.map
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.view.marginEnd
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
import com.mogo.eagle.core.function.view.SiteMarkerBean
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.widget.media.video.TextureVideoViewOutlineProvider
|
||||
import com.mogo.map.overlay.core.Level
|
||||
import com.mogo.map.overlay.point.Point
|
||||
import com.mogo.map.MapDataWrapper
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.constant.M2Const.Companion.TYPE_MARKER_M2_LINE
|
||||
import com.mogo.och.shuttle.weaknet.passenger.presenter.PM2ADASPresenter
|
||||
import com.mogo.och.common.module.utils.OCHThreadPoolManager
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_hpmap_fragment.aciv_top_shader
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_hpmap_fragment.mHomeView
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_hpmap_fragment.mindView
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_hpmap_fragment.overMapView
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/4/12
|
||||
*/
|
||||
class PM2HPMapFragment :
|
||||
MvpFragment<PM2HPMapFragment?, PM2ADASPresenter?>() {
|
||||
|
||||
private val stationIcon = BitmapFactory.decodeResource(
|
||||
AbsMogoApplication.getApp().resources,
|
||||
R.drawable.shuttle_p_m2_map_staton_icon
|
||||
)
|
||||
private val stationPassIcon = BitmapFactory.decodeResource(
|
||||
AbsMogoApplication.getApp().resources,
|
||||
R.drawable.shuttle_p_m2_map_staton_arrived_icon
|
||||
)
|
||||
private val startStationIcon = BitmapFactory.decodeResource(
|
||||
AbsMogoApplication.getApp().resources,
|
||||
R.drawable.shuttle_p_m2_map_start_icon
|
||||
)
|
||||
private val endStationIcon = BitmapFactory.decodeResource(
|
||||
AbsMogoApplication.getApp().resources,
|
||||
R.drawable.shuttle_p_m2_map_end_icon
|
||||
)
|
||||
|
||||
/**
|
||||
* 改变自动驾驶状态
|
||||
*
|
||||
* @param status 2 - running 1 - enable 2 - disable
|
||||
*/
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.shuttle_p_m2_hpmap_fragment
|
||||
}
|
||||
|
||||
override fun getTagName(): String {
|
||||
return TAG
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
|
||||
}
|
||||
|
||||
override fun initViews(savedInstanceState: Bundle?) {
|
||||
super.initViews(savedInstanceState)
|
||||
mHomeView.onCreate(savedInstanceState)
|
||||
overMapView?.let {
|
||||
it.onCreateView(savedInstanceState)
|
||||
val radius = AutoSizeUtils.dp2px(requireContext(), 16f)
|
||||
it.outlineProvider = TextureVideoViewOutlineProvider(radius.toFloat())
|
||||
it.clipToOutline = true
|
||||
it.hideResetView()
|
||||
}
|
||||
// cl_prediction_contain.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mHomeView.onResume()
|
||||
overMapView?.onResume()
|
||||
// cl_prediction_contain.onResume()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mHomeView.onLowMemory()
|
||||
// cl_prediction_contain.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mHomeView.onSaveInstanceState(outState)
|
||||
// cl_prediction_contain.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mHomeView.onPause()
|
||||
overMapView?.onPause()
|
||||
// cl_prediction_contain.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
mHomeView.onDestroy()
|
||||
overMapView?.onDestroy()
|
||||
// cl_prediction_contain.onDestroy()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun createPresenter(): PM2ADASPresenter {
|
||||
return PM2ADASPresenter(this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = PM2HPMapFragment::class.java.simpleName
|
||||
}
|
||||
|
||||
fun updateLineStations(
|
||||
stations: MutableList<LatLng>,
|
||||
stationsPass: MutableList<LatLng>,
|
||||
startStation: LatLng?,
|
||||
endStation: LatLng?
|
||||
) {
|
||||
overMapView?.let {
|
||||
val stationsList: MutableList<SiteMarkerBean> = mutableListOf()
|
||||
startStation?.let { start ->
|
||||
stationsList.add(SiteMarkerBean(start, startStationIcon, 0.5f, 0.5f))
|
||||
}
|
||||
for (stationPass in stationsPass) {
|
||||
stationsList.add(SiteMarkerBean(stationPass, stationPassIcon, 0.5f, 0.5f))
|
||||
}
|
||||
for (stationPass in stations) {
|
||||
stationsList.add(SiteMarkerBean(stationPass, stationIcon, 0.5f, 0.5f))
|
||||
}
|
||||
endStation?.let { end ->
|
||||
stationsList.add(SiteMarkerBean(end, endStationIcon, 0.5f, 0.5f))
|
||||
}
|
||||
it.drawSiteMarkers(stationsList)
|
||||
}
|
||||
}
|
||||
|
||||
fun setMapMaker(
|
||||
uuid: String,
|
||||
station: MutableList<Double>,
|
||||
) {
|
||||
//开启线程执行起终点marker设置
|
||||
val setMapMarkerRunnable = Runnable {
|
||||
d(
|
||||
"setMapMaker= " + Thread.currentThread().name,
|
||||
uuid + "=latitude=" + station[1] + ",longitude=" + station[0]
|
||||
)
|
||||
|
||||
val builder = Point.Options.Builder(
|
||||
TYPE_MARKER_M2_LINE,
|
||||
Level.MAP_MARKER
|
||||
)
|
||||
.setId(uuid)
|
||||
.anchor(0.5f, 0.5f)
|
||||
.set3DMode(true)
|
||||
.isUseGps(true)
|
||||
.controlAngle(true)
|
||||
.icon3DRes(R.raw.star_marker)
|
||||
.longitude(station[0])
|
||||
.latitude(station[1])
|
||||
MapDataWrapper.getCenterLineInfo(
|
||||
station[0], station[1], -1f
|
||||
) {
|
||||
// 有可能鹰眼map为空没有角度。判空使用后可能造成maker角度跟道路角度不一致 地图未初始化会返回空
|
||||
it?.let{
|
||||
builder.rotate(it.angle.toFloat())
|
||||
}
|
||||
val overlayManager = CallerMapUIServiceManager.getOverlayManager()
|
||||
overlayManager?.showOrUpdatePoint(builder.build())
|
||||
}
|
||||
|
||||
}
|
||||
OCHThreadPoolManager.getsInstance().execute(setMapMarkerRunnable)
|
||||
}
|
||||
|
||||
fun removeMapMaker(
|
||||
uuid: String,
|
||||
) {
|
||||
//开启线程移除起终点marker设置
|
||||
val removeMapMarkerRunnable = Runnable {
|
||||
d("RemoveMapMaker=" + Thread.currentThread().name, uuid)
|
||||
val overlayManager = CallerMapUIServiceManager.getOverlayManager()
|
||||
overlayManager?.removeAllPointsInOwner(TYPE_MARKER_M2_LINE)
|
||||
}
|
||||
OCHThreadPoolManager.getsInstance().execute(removeMapMarkerRunnable)
|
||||
}
|
||||
|
||||
fun showNoTaskView(b: Boolean) {
|
||||
if(!b) {
|
||||
overMapView?.clearSiteMarkers()
|
||||
clearCustomPolyline()
|
||||
}
|
||||
}
|
||||
|
||||
fun clearCustomPolyline() {
|
||||
overMapView?.clearCustomPolyline()
|
||||
}
|
||||
|
||||
// 展示高精地图
|
||||
// 展示高精地图+展示预测和决策
|
||||
// 展示高精地图+mogoMind
|
||||
// 展示高德地图
|
||||
// 展示高德地图+展示mogomind
|
||||
|
||||
val hdMapMarginEnd = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),-170f)
|
||||
|
||||
// 展示高精地图
|
||||
fun showHDMap(){
|
||||
mHomeView.visibility = View.VISIBLE
|
||||
val layoutParams = mHomeView.layoutParams as ConstraintLayout.LayoutParams
|
||||
layoutParams.marginStart = 0
|
||||
mHomeView.layoutParams = layoutParams
|
||||
|
||||
aciv_top_shader.visibility = View.GONE
|
||||
|
||||
// cl_aip_contain.visibility = View.GONE
|
||||
// cl_prediction_contain.visibility = View.GONE
|
||||
|
||||
mindView.visibility = View.GONE
|
||||
overMapView.visibility = View.GONE
|
||||
}
|
||||
// 展示高德地图
|
||||
fun showAmap(){
|
||||
mHomeView.visibility = View.GONE
|
||||
aciv_top_shader.visibility = View.GONE
|
||||
|
||||
// cl_aip_contain.visibility = View.GONE
|
||||
// cl_prediction_contain.visibility = View.GONE
|
||||
|
||||
mindView.visibility = View.GONE
|
||||
overMapView.visibility = View.VISIBLE
|
||||
|
||||
val layoutParams = overMapView.layoutParams as ConstraintLayout.LayoutParams
|
||||
layoutParams.marginStart = 0
|
||||
overMapView.layoutParams = layoutParams
|
||||
}
|
||||
// 展示高精地图+mogoMind
|
||||
fun showHDMap_mind(){
|
||||
mHomeView.visibility = View.VISIBLE
|
||||
val layoutParams = mHomeView.layoutParams as ConstraintLayout.LayoutParams
|
||||
layoutParams.marginStart = hdMapMarginEnd
|
||||
mHomeView.layoutParams = layoutParams
|
||||
|
||||
aciv_top_shader.visibility = View.VISIBLE
|
||||
|
||||
// cl_aip_contain.visibility = View.GONE
|
||||
// cl_prediction_contain.visibility = View.GONE
|
||||
|
||||
mindView.visibility = View.VISIBLE
|
||||
overMapView.visibility = View.GONE
|
||||
}
|
||||
// 展示高精地图+展示预测和决策
|
||||
fun showHDMap_aip_prediction(){
|
||||
mHomeView.visibility = View.VISIBLE
|
||||
val layoutParams = mHomeView.layoutParams as ConstraintLayout.LayoutParams
|
||||
layoutParams.marginStart = hdMapMarginEnd
|
||||
mHomeView.layoutParams = layoutParams
|
||||
|
||||
aciv_top_shader.visibility = View.VISIBLE
|
||||
|
||||
// cl_aip_contain.visibility = View.VISIBLE
|
||||
// cl_prediction_contain.visibility = View.VISIBLE
|
||||
|
||||
mindView.visibility = View.GONE
|
||||
overMapView.visibility = View.GONE
|
||||
}
|
||||
|
||||
fun showAmap_mind(){
|
||||
mHomeView.visibility = View.GONE
|
||||
|
||||
aciv_top_shader.visibility = View.VISIBLE
|
||||
|
||||
// cl_aip_contain.visibility = View.GONE
|
||||
// cl_prediction_contain.visibility = View.GONE
|
||||
|
||||
mindView.visibility = View.VISIBLE
|
||||
|
||||
overMapView.visibility = View.VISIBLE
|
||||
|
||||
val layoutParams = overMapView.layoutParams as ConstraintLayout.LayoutParams
|
||||
layoutParams.marginStart = hdMapMarginEnd
|
||||
overMapView.layoutParams = layoutParams
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind
|
||||
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
|
||||
object AIMessageManager {
|
||||
|
||||
// 使用 CopyOnWriteArrayList 来存储消息回调列表,保证线程安全
|
||||
private val messageListeners: MutableList<AIMessageListener> = CopyOnWriteArrayList()
|
||||
|
||||
|
||||
/**
|
||||
* 注册一个消息监听器。
|
||||
*
|
||||
* @param listener 要注册的 AiMessageListener 实例。
|
||||
*/
|
||||
fun registerListener(listener: AIMessageListener) {
|
||||
messageListeners.add(listener)
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消注册一个消息监听器。
|
||||
*
|
||||
* @param listener 要取消注册的 AiMessageListener 实例。
|
||||
*/
|
||||
fun unregisterListener(listener: AIMessageListener) {
|
||||
messageListeners.remove(listener)
|
||||
}
|
||||
|
||||
/**
|
||||
* 发布一条消息。
|
||||
*
|
||||
* 这条消息会被发送给所有已注册的监听器。
|
||||
*
|
||||
* @param msg 要发布的消息。
|
||||
*/
|
||||
fun post(msg: AIMessage) {
|
||||
// 遍历所有已注册的监听器,并调用它们的 onReceive 方法
|
||||
messageListeners.forEach { callback ->
|
||||
callback.onReceive(msg)
|
||||
}
|
||||
}
|
||||
|
||||
fun clearData(){
|
||||
messageListeners.forEach { callback ->
|
||||
callback.clear()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 消息监听器接口。
|
||||
*/
|
||||
interface AIMessageListener {
|
||||
/**
|
||||
* 当接收到消息时,会调用此方法。
|
||||
*
|
||||
* @param msg 接收到的消息。
|
||||
*/
|
||||
fun onReceive(msg: AIMessage)
|
||||
|
||||
fun clear()
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.findViewTreeLifecycleOwner
|
||||
import androidx.lifecycle.findViewTreeViewModelStoreOwner
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerRoadV2NEventWindowListenerManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapRoadListenerManager
|
||||
import com.mogo.eagle.core.utilcode.kotlin.onClick
|
||||
import com.mogo.eagle.core.utilcode.util.UriUtils
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.line.lineinfo.LineViewModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.adapter.AIMessageAdapter
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.adapter.OnItemClickListener
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.adapter.PaddingItemDecoration
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.data.AutomaticExplorationViewModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.data.NDEViewModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.data.RoadCrossRoamViewModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.data.RoadV2NEventViewModel
|
||||
import kotlinx.android.synthetic.main.m2_mind_view.view.rv_mind_list
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MindView : ConstraintLayout, MindViewModel.AiViewCallback {
|
||||
|
||||
private val TAG = "MindView"
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
|
||||
|
||||
private var roadV2NEventModel: RoadV2NEventViewModel?= null
|
||||
private var roadCrossRoamModel: RoadCrossRoamViewModel?= null
|
||||
private var automaticExplorationModel: AutomaticExplorationViewModel?= null
|
||||
private var ndeViewModel: NDEViewModel?= null
|
||||
|
||||
|
||||
private var viewModel:MindViewModel?=null
|
||||
|
||||
private var isUserScrollingTime = 0L
|
||||
|
||||
private val SCROLL_THRESHOLD = 2000L
|
||||
|
||||
private val messageAdapter: AIMessageAdapter by lazy { AIMessageAdapter() }
|
||||
private val messageLayoutManager: LinearLayoutManager by lazy {
|
||||
LinearLayoutManager(context).apply {
|
||||
stackFromEnd = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
LayoutInflater.from(context).inflate(R.layout.m2_mind_view, this, true)
|
||||
|
||||
rv_mind_list.layoutManager = messageLayoutManager
|
||||
rv_mind_list.adapter = messageAdapter
|
||||
rv_mind_list.addItemDecoration(PaddingItemDecoration(200, 300))
|
||||
messageAdapter.onItemClickListener = OnItemClickListener { item, position ->
|
||||
if (item is AIMessage.Event) {
|
||||
|
||||
}
|
||||
}
|
||||
rv_mind_list.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
|
||||
super.onScrollStateChanged(recyclerView, newState)
|
||||
if (newState != RecyclerView.SCROLL_STATE_IDLE) {
|
||||
isUserScrollingTime = System.currentTimeMillis()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
viewModel = findViewTreeViewModelStoreOwner()?.let {
|
||||
ViewModelProvider(it).get(MindViewModel::class.java)
|
||||
}
|
||||
viewModel?.setViewCallback(this)
|
||||
|
||||
roadV2NEventModel = findViewTreeViewModelStoreOwner()?.let{
|
||||
ViewModelProvider(it)[RoadV2NEventViewModel::class.java]
|
||||
}
|
||||
roadV2NEventModel?.init()
|
||||
roadCrossRoamModel = findViewTreeViewModelStoreOwner()?.let{
|
||||
ViewModelProvider(it)[RoadCrossRoamViewModel::class.java]
|
||||
}
|
||||
roadCrossRoamModel?.init(context)
|
||||
automaticExplorationModel = findViewTreeViewModelStoreOwner()?.let{
|
||||
ViewModelProvider(it)[AutomaticExplorationViewModel::class.java]
|
||||
}
|
||||
automaticExplorationModel?.init()
|
||||
ndeViewModel = findViewTreeViewModelStoreOwner()?.let{
|
||||
ViewModelProvider(it)[NDEViewModel::class.java]
|
||||
}
|
||||
ndeViewModel?.init()
|
||||
|
||||
findViewTreeLifecycleOwner()?.lifecycleScope?.launch {
|
||||
viewModel?.messagesFlow?.collect {
|
||||
Log.d(TAG, "${tName()} onMessages update: ${it}")
|
||||
if(it.isNotEmpty()){
|
||||
rv_mind_list.visibility = View.VISIBLE
|
||||
}else{
|
||||
rv_mind_list.visibility = View.VISIBLE
|
||||
}
|
||||
messageAdapter.submitList(it) {
|
||||
Log.d(TAG, "${tName()} adapter submit: ")
|
||||
scrollToBottom()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 滚动到RecyclerView底部
|
||||
private fun scrollToBottom() {
|
||||
val delay = System.currentTimeMillis() - isUserScrollingTime
|
||||
if (delay < SCROLL_THRESHOLD) {
|
||||
return
|
||||
}
|
||||
val layoutManager = rv_mind_list.layoutManager as LinearLayoutManager
|
||||
layoutManager.scrollToPositionWithOffset(messageAdapter.itemCount - 1, 0)
|
||||
}
|
||||
|
||||
fun tName(): String {
|
||||
return "【${Thread.currentThread().name}】"
|
||||
}
|
||||
|
||||
override fun onVisibilityAggregated(isVisible: Boolean) {
|
||||
super.onVisibilityAggregated(isVisible)
|
||||
}
|
||||
|
||||
init {
|
||||
try {
|
||||
initView()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,174 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind
|
||||
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.mogo.eagle.core.data.ai.V2XRepository
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
import com.mogo.och.bridge.autopilot.location.OchLocationManager
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeListener
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeManager
|
||||
import com.mogo.och.common.module.voice.VoiceNotice
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharedFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MindViewModel : ViewModel(), AIMessageManager.AIMessageListener,
|
||||
BridgeListener {
|
||||
|
||||
private val msgList = mutableListOf<AIMessage>()
|
||||
private var lastTimestamp = System.currentTimeMillis()
|
||||
|
||||
// 记录最后一次事件发生的时间,使用 private set 限制外部修改
|
||||
// private val TIMESTAMP_THRESHOLD = 1000 * 60 * 5 // 5分钟
|
||||
private val TIMESTAMP_THRESHOLD = 1000 * 30
|
||||
|
||||
private var llmResultJob: Job? = null
|
||||
|
||||
private var isChecking = false
|
||||
|
||||
private val _messagesFlow = MutableStateFlow<List<AIMessage>>(emptyList())
|
||||
val messagesFlow: SharedFlow<List<AIMessage>> get() = _messagesFlow
|
||||
|
||||
private val commontCallback = object : ICommonCallback{
|
||||
override fun showNoTaskView(isTrue: Boolean) {
|
||||
if(isTrue){
|
||||
clearMsg()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val locationCallback = object : IMoGoChassisLocationGCJ02Listener {
|
||||
override fun onChassisLocationGCJ02(mogoLocation: MogoLocation?) {
|
||||
mogoLocation?.let {
|
||||
V2XRepository.provideLocation(it, 0)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
}
|
||||
|
||||
fun setViewCallback(aiView: AiViewCallback) {
|
||||
CommonModel.setRouteLineInfoCallback(TAG,commontCallback)
|
||||
OchLocationManager.addGCJ02Listener(TAG, 1, locationCallback)
|
||||
AIMessageManager.registerListener(this)
|
||||
|
||||
BridgeManager.addBridgeListener(TAG,this)
|
||||
|
||||
}
|
||||
|
||||
|
||||
override fun onCleared() {
|
||||
AIMessageManager.unregisterListener(this)
|
||||
llmResultJob?.cancel()
|
||||
CommonModel.setRouteLineInfoCallback(TAG,null)
|
||||
OchLocationManager.removeGCJ02Listener(TAG)
|
||||
super.onCleared()
|
||||
}
|
||||
|
||||
override fun onReceive(msg: AIMessage) {
|
||||
Log.d(TAG, "onReceive: $msg")
|
||||
if (isChecking) {
|
||||
if (msg is AIMessage.Event) {
|
||||
msg.showScanFlag = true
|
||||
}
|
||||
}
|
||||
|
||||
// 获更新消息
|
||||
updateMsg(msg)
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
clearMsg()
|
||||
}
|
||||
|
||||
private fun handleMsg(newMessage: AIMessage) {
|
||||
val existingIndex = findMessageIndex(newMessage.id)
|
||||
if (existingIndex != -1) {
|
||||
handleExistingMessage(existingIndex, newMessage)
|
||||
} else {
|
||||
handleNewMessage(newMessage)
|
||||
}
|
||||
}
|
||||
|
||||
private fun findMessageIndex(messageId: String): Int {
|
||||
return msgList.indexOfFirst { it.id == messageId }
|
||||
}
|
||||
|
||||
private fun handleExistingMessage(index: Int, newMessage: AIMessage) {
|
||||
val oldMessage = msgList[index]
|
||||
|
||||
newMessage.showTimestamp = oldMessage.showTimestamp
|
||||
msgList[index] = newMessage
|
||||
|
||||
speakMessageIfNeeded(newMessage, isLastMessage = msgList.last() == newMessage)
|
||||
}
|
||||
|
||||
private fun handleNewMessage(newMessage: AIMessage) {
|
||||
updateTimestampIfNeeded(newMessage)
|
||||
msgList.add(newMessage)
|
||||
speakMessageIfNeeded(newMessage, isLastMessage = true)
|
||||
}
|
||||
|
||||
private fun updateTimestampIfNeeded(newMessage: AIMessage) {
|
||||
val time = newMessage.timestamp - lastTimestamp
|
||||
if (time >= TIMESTAMP_THRESHOLD) {
|
||||
newMessage.showTimestamp = true
|
||||
lastTimestamp = newMessage.timestamp
|
||||
}
|
||||
}
|
||||
|
||||
private fun speakMessageIfNeeded(newMessage: AIMessage, isLastMessage: Boolean) {
|
||||
if (isLastMessage && newMessage.tts.isNotEmpty()) {
|
||||
VoiceNotice.showNotice(newMessage.tts)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "AiViewModel"
|
||||
}
|
||||
|
||||
private fun updateMsg(msg: AIMessage) {
|
||||
synchronized(msgList) {
|
||||
handleMsg(msg)
|
||||
_messagesFlow.value = msgList.toList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun deleteMsg(msgId: String) {
|
||||
synchronized(msgList) {
|
||||
val iterator = msgList.iterator()
|
||||
while (iterator.hasNext()) {
|
||||
if (iterator.next().id == msgId) {
|
||||
iterator.remove()
|
||||
}
|
||||
}
|
||||
_messagesFlow.value = msgList.toList()
|
||||
}
|
||||
}
|
||||
|
||||
private fun clearMsg() {
|
||||
synchronized(msgList) {
|
||||
msgList.clear()
|
||||
_messagesFlow.value = msgList.toList()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface AiViewCallback {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.adapter
|
||||
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.recyclerview.widget.ListAdapter
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
|
||||
class AIMessageAdapter : ListAdapter<AIMessage, MessageViewHolder>(MessageDiffCallback()) {
|
||||
|
||||
var onItemClickListener: OnItemClickListener? = null
|
||||
|
||||
override fun onBindViewHolder(holder: MessageViewHolder, position: Int) {
|
||||
getItem(position)?.let {
|
||||
holder.bind(it, onItemClickListener)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MessageViewHolder {
|
||||
val inflater = LayoutInflater.from(parent.context)
|
||||
return when (viewType) {
|
||||
AIMessage.TYPE_PNC_ACTION -> PNCActionViewHolder(inflater.inflate(R.layout.b2_item_ai_pnc_action,parent,false))
|
||||
AIMessage.TYPE_ROAD_V2N -> RoadV2NEventViewHolder(inflater.inflate(R.layout.b2_item_ai_road_v2n_event,parent,false))
|
||||
AIMessage.TYPE_ROAD_CROSS -> RoadCrossRoamViewHolder(inflater.inflate(R.layout.b2_item_ai_road_cross_roam,parent,false))// 全息路口
|
||||
AIMessage.TYPE_AUTOMATIC_EXPLORATION -> AutomaticExplorationViewHolder(inflater.inflate(R.layout.b2_item_ai_automatic_exploration,parent,false))// 探查
|
||||
AIMessage.TYPE_NDE -> NDEViewHolder(inflater.inflate(R.layout.b2_item_ai_nde_event,parent,false))// 车龙
|
||||
else -> throw IllegalArgumentException("Invalid view type")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemViewType(position: Int): Int {
|
||||
return when (getItem(position)) {
|
||||
is AIMessage.Event -> AIMessage.TYPE_EVENT
|
||||
is AIMessage.Scan -> AIMessage.TYPE_SCAN
|
||||
is AIMessage.Light -> AIMessage.TYPE_LIGHT
|
||||
is AIMessage.Speed -> AIMessage.TYPE_SPEED
|
||||
is AIMessage.Warning -> AIMessage.TYPE_WARNING
|
||||
is AIMessage.PNCAction -> AIMessage.TYPE_PNC_ACTION
|
||||
is AIMessage.RoadV2NEvent -> AIMessage.TYPE_ROAD_V2N
|
||||
is AIMessage.RoadCrossRoam -> AIMessage.TYPE_ROAD_CROSS
|
||||
is AIMessage.AutomaticExploration -> AIMessage.TYPE_AUTOMATIC_EXPLORATION
|
||||
is AIMessage.NDEData -> AIMessage.TYPE_NDE
|
||||
else -> AIMessage.TYPE_EVENT
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewRecycled(holder: MessageViewHolder) {
|
||||
super.onViewRecycled(holder)
|
||||
holder.viewRecycled(holder)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.adapter
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.graphics.Rect
|
||||
import android.util.Log
|
||||
import android.view.View
|
||||
import android.view.animation.LinearInterpolator
|
||||
import android.widget.FrameLayout
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.bumptech.glide.Glide
|
||||
import com.mogo.eagle.core.data.notice.AutoExplorationEntity
|
||||
import com.mogo.eagle.core.data.v2x.RoadV2NEventType
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationWGS84ListenerManager
|
||||
import com.mogo.eagle.core.function.hmi.ui.notice.exploration.AutomaticExplorationAdapter
|
||||
import com.mogo.eagle.core.function.hmi.ui.v2n.RoadV2NEventLivePlayView
|
||||
import com.mogo.eagle.core.function.view.MapRoamView
|
||||
import com.mogo.eagle.core.function.view.RoadCrossRoamListAdapter
|
||||
import com.mogo.eagle.core.utilcode.mogo.glide.GlideImageLoader
|
||||
import com.mogo.eagle.core.utilcode.mogo.imageloader.MogoImageView
|
||||
import com.mogo.eagle.core.utilcode.util.DateTimeUtils
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
|
||||
abstract class MessageViewHolder(view: View) : RecyclerView.ViewHolder(view) {
|
||||
abstract fun bind(item: AIMessage, onItemClickListener: OnItemClickListener? = null)
|
||||
open fun viewRecycled(holder: MessageViewHolder){}
|
||||
private val sampleDateFormat = SimpleDateFormat("HH:mm", Locale.CHINA)
|
||||
protected val TAG = javaClass.simpleName
|
||||
|
||||
fun handleTimestamp(item: AIMessage, tvTimestamp: TextView) {
|
||||
if (item.showTimestamp) {
|
||||
tvTimestamp.visibility = View.VISIBLE
|
||||
tvTimestamp.text = sampleDateFormat.format(Date(item.timestamp))
|
||||
} else {
|
||||
tvTimestamp.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
fun View.setVisibilityBasedOn(condition: Boolean) {
|
||||
visibility = if (condition) View.VISIBLE else View.GONE
|
||||
}
|
||||
|
||||
fun TextView.setTextAndVisibility(text: String) {
|
||||
if (text.isEmpty()) {
|
||||
visibility = View.GONE
|
||||
this.text = ""
|
||||
} else {
|
||||
visibility = View.VISIBLE
|
||||
this.text = text
|
||||
}
|
||||
}
|
||||
|
||||
fun ImageView.showOrHideWithUrl(url: String) {
|
||||
if (url.isEmpty()) {
|
||||
visibility = View.GONE
|
||||
|
||||
} else {
|
||||
visibility = View.VISIBLE
|
||||
Glide.with(this)
|
||||
.load(url)
|
||||
.placeholder(R.drawable.icon_pic_holder)
|
||||
.error(R.drawable.icon_pic_error)
|
||||
// .error(R.drawable.icon_marker_window_place_holder)
|
||||
// .placeholder(R.drawable.icon_marker_window_place_holder)
|
||||
.into(this)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class PNCActionViewHolder(binding: View) : MessageViewHolder(binding){
|
||||
|
||||
private var tvPncActionDesc: TextView = binding.findViewById(R.id.tvPNCHintContent)
|
||||
|
||||
override fun bind(item: AIMessage, onItemClickListener: OnItemClickListener?) {
|
||||
if(item is AIMessage.PNCAction){
|
||||
tvPncActionDesc.text = item.actionDesc
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RoadV2NEventViewHolder(binding: View) : MessageViewHolder(binding){
|
||||
|
||||
private var tvV2XHintContent: TextView = binding.findViewById(R.id.tvV2XHintContent)
|
||||
private var containerImageAndLiveVideo: FrameLayout = binding.findViewById(R.id.containerImageAndLiveVideo)
|
||||
private var livePlayView: RoadV2NEventLivePlayView = binding.findViewById(R.id.livePlayView)
|
||||
private var contentImageView: MogoImageView = binding.findViewById(R.id.contentImageView)
|
||||
|
||||
override fun bind(item: AIMessage, onItemClickListener: OnItemClickListener?) {
|
||||
if(item is AIMessage.RoadV2NEvent){
|
||||
tvV2XHintContent.text = item.title
|
||||
when (item.eventType) {
|
||||
RoadV2NEventType.TEXT -> {
|
||||
containerImageAndLiveVideo.visibility = View.GONE
|
||||
contentImageView.visibility = View.GONE
|
||||
livePlayView.visibility = View.GONE
|
||||
}
|
||||
|
||||
RoadV2NEventType.IMAGE -> {
|
||||
containerImageAndLiveVideo.visibility = View.VISIBLE
|
||||
contentImageView.visibility = View.VISIBLE
|
||||
livePlayView.visibility = View.GONE
|
||||
GlideImageLoader.getInstance()
|
||||
.displayImage(item.contentImageUrl, contentImageView)
|
||||
}
|
||||
|
||||
RoadV2NEventType.LIVE_VIDEO -> {
|
||||
containerImageAndLiveVideo.visibility = View.VISIBLE
|
||||
contentImageView.visibility = View.GONE
|
||||
livePlayView.visibility = View.VISIBLE
|
||||
val cityCode =
|
||||
CallerChassisLocationWGS84ListenerManager.getChassisLocationWGS84().cityCode
|
||||
livePlayView.startRoadCameraLive(
|
||||
item.id,
|
||||
item.cameraIp, item.lon, item.lat, cityCode
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class RoadCrossRoamViewHolder(binding: View) : MessageViewHolder(binding){
|
||||
|
||||
private var tvRoadRoamTitle: TextView = binding.findViewById(R.id.tvRoadRoamTitle)
|
||||
private var lvRoadCrossRoamTip: RecyclerView = binding.findViewById(R.id.lvRoadCrossRoamTip)
|
||||
|
||||
override fun bind(item: AIMessage, onItemClickListener: OnItemClickListener?) {
|
||||
if(item is AIMessage.RoadCrossRoam){
|
||||
lvRoadCrossRoamTip.layoutManager = NoScrollLayoutManager(itemView.context)
|
||||
lvRoadCrossRoamTip.adapter = RoadCrossRoamListB2Adapter(itemView.context)
|
||||
tvRoadRoamTitle.setTextColor(itemView.context.getColor(R.color.color_131415))
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class AutomaticExplorationViewHolder(binding: View) : MessageViewHolder(binding){
|
||||
|
||||
private var rvExplorationList: RecyclerView = binding.findViewById(R.id.rvExplorationList)
|
||||
private lateinit var automaticExplorationAdapter: AutomaticExplorationB2Adapter
|
||||
|
||||
override fun bind(item: AIMessage, onItemClickListener: OnItemClickListener?) {
|
||||
val linearLayoutManager = LinearLayoutManager(itemView.context)
|
||||
linearLayoutManager.orientation = LinearLayoutManager.VERTICAL
|
||||
automaticExplorationAdapter = AutomaticExplorationB2Adapter(itemView.context)
|
||||
rvExplorationList.adapter = automaticExplorationAdapter
|
||||
rvExplorationList.layoutManager = linearLayoutManager
|
||||
initData()
|
||||
}
|
||||
|
||||
private fun initData() {
|
||||
val dataList = ArrayList<AutoExplorationEntity>(7)
|
||||
dataList.add(AutoExplorationEntity("当前道路事件分析",2000L,false))
|
||||
dataList.add(AutoExplorationEntity("前方车辆",2000L,false))
|
||||
dataList.add(AutoExplorationEntity("两侧车辆",2600L,false))
|
||||
dataList.add(AutoExplorationEntity("后方车辆",3000L,false))
|
||||
dataList.add(AutoExplorationEntity("前方路口车辆流速分析",4000L,false))
|
||||
dataList.add(AutoExplorationEntity("前方路口行人/非机动车分析",4300L,false))
|
||||
dataList.add(AutoExplorationEntity("路侧视频分析",5000L,false))
|
||||
automaticExplorationAdapter.setListener(object: AutomaticExplorationB2Adapter.CompleteListener{
|
||||
override fun onComplete(entity: AutoExplorationEntity) {
|
||||
dataList.forEach {
|
||||
if(it.explorationContent == entity.explorationContent){
|
||||
it.explorationComplete = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})
|
||||
automaticExplorationAdapter.setData(dataList)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class NDEViewHolder(binding: View) : MessageViewHolder(binding){
|
||||
|
||||
private var tvNdeContent: TextView = binding.findViewById(R.id.tvNdeHintContent)
|
||||
private var rvNdeList: RecyclerView = binding.findViewById(R.id.rvNdeList)
|
||||
|
||||
override fun bind(item: AIMessage, onItemClickListener: OnItemClickListener?) {
|
||||
if(item is AIMessage.NDEData){
|
||||
tvNdeContent.text = item.desc
|
||||
val linearLayoutManager = LinearLayoutManager(itemView.context)
|
||||
linearLayoutManager.orientation = LinearLayoutManager.HORIZONTAL
|
||||
val ndeRoadAdapter = AINDERoadAdapter(itemView.context)
|
||||
rvNdeList.adapter = ndeRoadAdapter
|
||||
rvNdeList.layoutManager = linearLayoutManager
|
||||
ndeRoadAdapter.setData(item.roadList)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class NoScrollLayoutManager(context: Context?) : LinearLayoutManager(context) {
|
||||
override fun canScrollVertically(): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
override fun canScrollHorizontally(): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
fun interface OnItemClickListener {
|
||||
fun onItemClick(item: AIMessage, position: Int)
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
|
||||
class AINDERoadAdapter(private val context: Context): RecyclerView.Adapter<AINDERoadAdapter.AIRoadHolder>() {
|
||||
|
||||
private var roadList: List<RoadMsg>?= null
|
||||
|
||||
fun setData(list: List<RoadMsg>){
|
||||
roadList = list
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AIRoadHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.b2_item_ai_nde_road, parent, false)
|
||||
return AIRoadHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: AIRoadHolder, position: Int) {
|
||||
roadList?.let{
|
||||
val roadMsg = it[position]
|
||||
if(it.size < 3){
|
||||
//设置item宽度为最大宽度180dp
|
||||
val params = ConstraintLayout.LayoutParams(
|
||||
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 90f,
|
||||
context.resources.displayMetrics).toInt(),
|
||||
ConstraintLayout.LayoutParams.WRAP_CONTENT)
|
||||
holder.clRoadLayout.layoutParams = params
|
||||
}else if(it.size == 3){
|
||||
//设置item宽度为最大宽度180dp
|
||||
val params = ConstraintLayout.LayoutParams(
|
||||
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 60f,
|
||||
context.resources.displayMetrics).toInt(),
|
||||
ConstraintLayout.LayoutParams.WRAP_CONTENT)
|
||||
holder.clRoadLayout.layoutParams = params
|
||||
}else if(it.size == 4){
|
||||
//设置item宽度为最大宽度180dp
|
||||
val params = ConstraintLayout.LayoutParams(
|
||||
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 50f,
|
||||
context.resources.displayMetrics).toInt(),
|
||||
ConstraintLayout.LayoutParams.WRAP_CONTENT)
|
||||
holder.clRoadLayout.layoutParams = params
|
||||
}else{
|
||||
val params = ConstraintLayout.LayoutParams(
|
||||
TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 45f,
|
||||
context.resources.displayMetrics).toInt(),
|
||||
ConstraintLayout.LayoutParams.WRAP_CONTENT)
|
||||
holder.clRoadLayout.layoutParams = params
|
||||
}
|
||||
when(roadMsg.arrowType){
|
||||
//直行
|
||||
201->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_forward
|
||||
))
|
||||
}
|
||||
//直行或左转
|
||||
202->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_forward_or_turn_left
|
||||
))
|
||||
}
|
||||
//直行或右转
|
||||
203->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_forward_or_turn_right
|
||||
))
|
||||
}
|
||||
//直行或掉头
|
||||
204->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_forward_or_reverse
|
||||
))
|
||||
}
|
||||
//左转
|
||||
205->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_turn_left
|
||||
))
|
||||
}
|
||||
//左转或掉头
|
||||
206->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_turn_left_or_reverse
|
||||
))
|
||||
}
|
||||
//左弯或向左合流
|
||||
207->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_turn_or_merge_left
|
||||
))
|
||||
}
|
||||
//右转
|
||||
208->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_turn_right
|
||||
))
|
||||
}
|
||||
//右转或向右合流
|
||||
209->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_turn_or_merge_right
|
||||
))
|
||||
}
|
||||
//左右转弯
|
||||
210->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_turn_left_or_right
|
||||
))
|
||||
}
|
||||
//掉头
|
||||
211->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_reverse
|
||||
))
|
||||
}
|
||||
//禁止左转
|
||||
212->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_prohibit_turn_left
|
||||
))
|
||||
}
|
||||
//禁止右转
|
||||
213->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_prohibit_turn_right
|
||||
))
|
||||
}
|
||||
//禁止掉头
|
||||
214->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_prohibit_reverse
|
||||
))
|
||||
}
|
||||
//直行或左转或右转
|
||||
215->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_forward_turn_left_right
|
||||
))
|
||||
}
|
||||
//直行或掉头或左转
|
||||
216->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_forward_turn_left_reverse
|
||||
))
|
||||
}
|
||||
//右转或掉头
|
||||
217->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_turn_right_or_reverse
|
||||
))
|
||||
}
|
||||
//禁止右转或向右合流
|
||||
218->{
|
||||
holder.ivRoadType.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_road_prohibit_turn_or_merge_right
|
||||
))
|
||||
}
|
||||
}
|
||||
//是否是推荐车道
|
||||
if(roadMsg.isRecommend){
|
||||
holder.tvRoadStatus.text = context.getString(R.string.nde_road_recommend)
|
||||
holder.tvRoadStatus.setTextColor(context.getColor(R.color.msg_nde_road_recommend))
|
||||
holder.clRoadLayout.background = ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.bg_nde_road_recommend
|
||||
)
|
||||
}
|
||||
//是否有车龙,代表拥堵、行驶缓慢
|
||||
if(roadMsg.isCheLong){
|
||||
holder.tvRoadStatus.text = context.getString(R.string.nde_road_slow)
|
||||
holder.tvRoadStatus.setTextColor(context.getColor(R.color.msg_nde_road_slow))
|
||||
}
|
||||
if(position == it.lastIndex){
|
||||
holder.viewDivider.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = roadList?.size ?: 0
|
||||
|
||||
class AIRoadHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
|
||||
var clRoadLayout: ConstraintLayout = itemView.findViewById(R.id.clRoadLayout)
|
||||
var ivRoadType: ImageView = itemView.findViewById(R.id.ivRoadType)
|
||||
var tvRoadStatus: TextView = itemView.findViewById(R.id.tvRoadStatus)
|
||||
var viewDivider: View = itemView.findViewById(R.id.viewDivider)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.adapter
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorListenerAdapter
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.LinearInterpolator
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.eagle.core.data.notice.AutoExplorationEntity
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
|
||||
/**
|
||||
* 自动探查适配器
|
||||
* 鹰眼650需求
|
||||
*/
|
||||
class AutomaticExplorationB2Adapter(val context: Context): RecyclerView.Adapter<AutomaticExplorationB2Adapter.ExplorationHolder>() {
|
||||
|
||||
private var data: List<AutoExplorationEntity> ?= null
|
||||
private var completeListener: CompleteListener ?= null
|
||||
|
||||
fun setData(data: List<AutoExplorationEntity>){
|
||||
this.data = data
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
fun setListener(listener: CompleteListener){
|
||||
completeListener = listener
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ExplorationHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_auto_exploration_b2, parent, false)
|
||||
return ExplorationHolder(view)
|
||||
}
|
||||
|
||||
override fun getItemCount() = data?.size ?: 0
|
||||
|
||||
override fun onBindViewHolder(holder: ExplorationHolder, position: Int) {
|
||||
data?.let {
|
||||
val entity = it[position]
|
||||
holder.tvExplorationContent.text = entity.explorationContent
|
||||
holder.ivExplorationLoading.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_exploration_loading_p
|
||||
))
|
||||
val rotationAnim = ObjectAnimator.ofFloat(holder.ivExplorationLoading, "rotation", 0f, 360f)
|
||||
rotationAnim.repeatCount = entity.explorationDuration.toInt()/1000
|
||||
rotationAnim.repeatMode = ValueAnimator.RESTART
|
||||
rotationAnim.duration = 1000
|
||||
rotationAnim.interpolator = LinearInterpolator()
|
||||
rotationAnim.addListener(object: AnimatorListenerAdapter(){
|
||||
override fun onAnimationEnd(animation: Animator) {
|
||||
super.onAnimationEnd(animation)
|
||||
completeListener?.onComplete(entity)
|
||||
holder.ivExplorationLoading.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_exploration_done_p
|
||||
))
|
||||
}
|
||||
})
|
||||
rotationAnim.start()
|
||||
}
|
||||
}
|
||||
|
||||
class ExplorationHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
|
||||
var ivExplorationLoading: ImageView = itemView.findViewById(R.id.ivExplorationLoading)
|
||||
var tvExplorationContent: TextView = itemView.findViewById(R.id.tvExplorationContent)
|
||||
}
|
||||
|
||||
interface CompleteListener{
|
||||
fun onComplete(entity: AutoExplorationEntity)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.adapter
|
||||
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
|
||||
class MessageDiffCallback: DiffUtil.ItemCallback<AIMessage>() {
|
||||
|
||||
override fun areContentsTheSame(oldItem: AIMessage, newItem: AIMessage): Boolean {
|
||||
return oldItem == newItem
|
||||
}
|
||||
|
||||
override fun areItemsTheSame(oldItem: AIMessage, newItem: AIMessage): Boolean {
|
||||
return oldItem.id == newItem.id
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.adapter
|
||||
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Rect
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.view.View
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import androidx.recyclerview.widget.StaggeredGridLayoutManager
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
|
||||
class PaddingItemDecoration(private val topPadding: Int, private val bottomPadding: Int) : RecyclerView.ItemDecoration() {
|
||||
|
||||
private var divider: Drawable
|
||||
|
||||
private var padding = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),13f)
|
||||
|
||||
init {
|
||||
val shapeDrawable = GradientDrawable()
|
||||
shapeDrawable.setColor(ResourcesUtils.getColor(R.color.b2_BBC9D4))
|
||||
shapeDrawable.shape = GradientDrawable.RECTANGLE
|
||||
val width = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),343f)
|
||||
val height = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),1f)
|
||||
shapeDrawable.setSize(width, height)
|
||||
divider = shapeDrawable
|
||||
}
|
||||
|
||||
override fun getItemOffsets(outRect: Rect, view: View, parent: RecyclerView, state: RecyclerView.State) {
|
||||
super.getItemOffsets(outRect, view, parent, state)
|
||||
|
||||
|
||||
// 只有第一个 item 的顶部添加空白
|
||||
if (parent.getChildAdapterPosition(view) == 0) {
|
||||
outRect.top = topPadding
|
||||
} else{
|
||||
outRect.top = 0
|
||||
}
|
||||
|
||||
// 最后一个 item 的底部添加空白
|
||||
// if (parent.getChildAdapterPosition(view) == state.itemCount - 1) {
|
||||
// outRect.bottom = bottomPadding
|
||||
// } else{
|
||||
// outRect.bottom = 0
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onDraw(c: Canvas, parent: RecyclerView, state: RecyclerView.State) {
|
||||
super.onDraw(c, parent, state)
|
||||
val childCount = parent.childCount //获取可见item的数量
|
||||
val spanCount: Int = getSpanCount(parent)
|
||||
for (i in 0 until childCount) {
|
||||
val child = parent.getChildAt(i)
|
||||
val params = child
|
||||
.layoutParams as RecyclerView.LayoutParams
|
||||
val left = child.left - params.leftMargin + padding
|
||||
val right = child.right - padding //- params.rightMargin - divider.intrinsicWidth
|
||||
val top = child.bottom + params.bottomMargin
|
||||
val bottom = top + divider.intrinsicHeight
|
||||
divider.setBounds(left, top, right, bottom)
|
||||
divider.draw(c)
|
||||
if (i < spanCount) { //画第一行顶部的分割线
|
||||
drawHorizontalForFirstRow(c, child)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun drawHorizontalForFirstRow(c: Canvas, child: View) {
|
||||
val params = child
|
||||
.layoutParams as RecyclerView.LayoutParams
|
||||
val left = child.left - params.leftMargin - divider.intrinsicWidth
|
||||
val top = child.top - params.topMargin - divider.intrinsicHeight
|
||||
val right = child.right + params.rightMargin + divider.intrinsicWidth
|
||||
val bottom = top + divider.intrinsicHeight
|
||||
divider.setBounds(left, top, right, bottom)
|
||||
divider.draw(c)
|
||||
}
|
||||
|
||||
private fun getSpanCount(parent: RecyclerView): Int {
|
||||
// 列数
|
||||
var spanCount = -1
|
||||
val layoutManager = parent.layoutManager
|
||||
if (layoutManager is GridLayoutManager) {
|
||||
spanCount = layoutManager.spanCount
|
||||
} else if (layoutManager is StaggeredGridLayoutManager) {
|
||||
spanCount = layoutManager
|
||||
.spanCount
|
||||
}
|
||||
return spanCount
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import android.widget.ProgressBar
|
||||
import android.widget.TextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import kotlin.random.Random
|
||||
|
||||
|
||||
class RoadCrossRoamListB2Adapter(private val mContext: Context) : RecyclerView.Adapter<RoadCrossRoamListB2Adapter.ViewHolder>() {
|
||||
|
||||
private val items: MutableList<String> = mutableListOf()
|
||||
|
||||
init {
|
||||
items.add("前方路况拥堵分析")
|
||||
items.add("路口危险车辆分析")
|
||||
items.add("路口交通事故分析")
|
||||
items.add("路口行人碰撞分析")
|
||||
items.add("路口非机动车分析")
|
||||
items.add("路口灯态分析")
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
|
||||
val view: View =
|
||||
LayoutInflater.from(mContext).inflate(R.layout.item_road_cross_ai_roam_tip_b2, parent, false)
|
||||
return ViewHolder(view)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return 6
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||
val item = items[position]
|
||||
holder.textView.setTextColor(mContext.getColor(R.color.color_191A1C))
|
||||
holder.textView.text = item
|
||||
// 随机决定是否显示ProgressBar
|
||||
// if (Random.nextBoolean()) { // 50%的几率显示ProgressBar
|
||||
holder.progressBar.visibility = View.VISIBLE
|
||||
holder.checkIcon.visibility = View.INVISIBLE
|
||||
|
||||
val r0 = Random.nextInt(0,3)
|
||||
val r1 = Random.nextInt(1,9)
|
||||
// 模拟加载完成
|
||||
holder.itemView.postDelayed({
|
||||
holder.progressBar.visibility = View.INVISIBLE
|
||||
holder.checkIcon.visibility = View.VISIBLE
|
||||
},r0 * 1000L + r1 * 100L)
|
||||
// } else {
|
||||
// holder.progressBar.visibility = View.GONE
|
||||
// holder.checkIcon.visibility = View.VISIBLE
|
||||
// }
|
||||
}
|
||||
|
||||
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
var textView: TextView = itemView.findViewById(R.id.tvRoadItemTip)
|
||||
var progressBar: ProgressBar = itemView.findViewById(R.id.pbRoadItemTip)
|
||||
var checkIcon: ImageView = itemView.findViewById(R.id.ivRoadItemTip)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean
|
||||
|
||||
import android.os.CountDownTimer
|
||||
import android.util.Log
|
||||
import com.mogo.eagle.core.data.v2x.RoadV2NEventType
|
||||
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
|
||||
import com.mogo.och.common.module.biz.birdge.data.VlmData
|
||||
import kotlin.math.floor
|
||||
|
||||
|
||||
sealed class AIMessage(
|
||||
open val id: String,
|
||||
open val title: String,
|
||||
open val tts: String = "",
|
||||
val timestamp: Long = System.currentTimeMillis(),
|
||||
var showTimestamp: Boolean = false
|
||||
) {
|
||||
|
||||
companion object {
|
||||
const val TYPE_SCAN = 0
|
||||
const val TYPE_EVENT = 1
|
||||
const val TYPE_LIGHT = 3
|
||||
const val TYPE_SPEED = 4
|
||||
const val TYPE_WARNING = 5
|
||||
const val TYPE_PNC_ACTION = 6
|
||||
const val TYPE_ROAD_V2N = 7
|
||||
const val TYPE_ROAD_CROSS = 8
|
||||
const val TYPE_AUTOMATIC_EXPLORATION = 9
|
||||
const val TYPE_NDE = 11
|
||||
}
|
||||
|
||||
data class Scan(
|
||||
override val id: String,
|
||||
override val title: String,
|
||||
val pictureUrl: String = "",
|
||||
var showScanFlag: Boolean = false
|
||||
) : AIMessage(id, title)
|
||||
|
||||
data class Event(
|
||||
override val id: String,
|
||||
override val title: String,
|
||||
override val tts: String = "",
|
||||
val position: String = "",
|
||||
val distance: String = "",
|
||||
val range: String = "",
|
||||
val time: String = "",
|
||||
val pictureUrl: String = "",
|
||||
val videoUrl: String = "",
|
||||
var showScanFlag: Boolean = false
|
||||
) : AIMessage(id, title, tts)
|
||||
|
||||
data class QA(
|
||||
override val id: String,
|
||||
override val title: String,
|
||||
override val tts: String = "",
|
||||
val question: String,
|
||||
val answer: String,
|
||||
var state: QuestionState = QuestionState.UNDERSTAND,
|
||||
val pictureUrl: String = "",
|
||||
var pictureUrlList: List<String> = listOf(),
|
||||
val videoUrl: String = "",
|
||||
) : AIMessage(id, title, tts) {
|
||||
|
||||
enum class QuestionState(val code: Int) {
|
||||
UNDERSTAND(1),
|
||||
ANALYZE(2),
|
||||
ANSWER(3),
|
||||
FINISH(4),
|
||||
ERROR(-1),
|
||||
}
|
||||
}
|
||||
|
||||
data class Light(
|
||||
override val id: String,
|
||||
override val title: String,
|
||||
override val tts: String = "",
|
||||
var seconds: Int,
|
||||
val status: Int
|
||||
) : AIMessage(id, title, tts) {
|
||||
private var countDownTimer: CountDownTimer? = null
|
||||
private var listener: OnCountdownUpdateListener? = null
|
||||
|
||||
fun startCountdown(millisInFuture: Long, countDownInternal: Long) {
|
||||
countDownTimer?.cancel()
|
||||
countDownTimer = object : CountDownTimer(millisInFuture, countDownInternal) {
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
//倒计时开始
|
||||
Log.d(
|
||||
"StartOrSlowDownTip",
|
||||
"millisUntilFinished = $millisUntilFinished, countDownInternal = $countDownInternal"
|
||||
)
|
||||
val cd = millisUntilFinished / 1000.0
|
||||
// val split = String.format("%.2f", cd).split(".")
|
||||
seconds = floor(cd).toInt()
|
||||
listener?.onCountdownUpdate()
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
//倒计时完成
|
||||
seconds = 0
|
||||
listener?.onCountdownFinish()
|
||||
}
|
||||
}
|
||||
countDownTimer?.start()
|
||||
}
|
||||
|
||||
fun stopCountdown() {
|
||||
countDownTimer?.cancel()
|
||||
}
|
||||
|
||||
fun setOnCountdownUpdateListener(listener: OnCountdownUpdateListener) {
|
||||
this.listener = listener
|
||||
}
|
||||
|
||||
interface OnCountdownUpdateListener {
|
||||
fun onCountdownUpdate()
|
||||
fun onCountdownFinish()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
data class Speed(
|
||||
override val id: String,
|
||||
override val title: String,
|
||||
override val tts: String = "",
|
||||
val speedMax: Int,
|
||||
val speedMin: Int,
|
||||
) : AIMessage(id, title, tts)
|
||||
|
||||
data class Warning(
|
||||
override val id: String,
|
||||
override val title: String,
|
||||
override val tts: String = "",
|
||||
) : AIMessage(id, title, tts)
|
||||
|
||||
data class PNCAction(
|
||||
override val id: String,
|
||||
override val title: String,
|
||||
var actionDesc: String,
|
||||
var timeStamp: Long = 0, //事件发生事件戳
|
||||
): AIMessage(id,title)
|
||||
|
||||
data class RoadV2NEvent(
|
||||
override val id: String,
|
||||
override val title: String,
|
||||
override val tts: String = "", //TTS的文案
|
||||
var eventType: RoadV2NEventType, //事件弹框类型
|
||||
var timeStamp: Long = 0, //事件发生事件戳
|
||||
var iconResId: Int, //事件icon res id
|
||||
var isNeedTTS: Boolean = false, //事件文案是否需要同步tts
|
||||
var contentImageUrl: String, // Image 类型时图片 url
|
||||
var cameraIp: String, // 路侧camera ip,用于请求获取拉流地址
|
||||
var lon: Double, //事件坐标-经度
|
||||
var lat: Double, //事件坐标-纬度
|
||||
): AIMessage(id,title,tts)
|
||||
|
||||
data class RoadCrossRoam(
|
||||
override val id: String,
|
||||
override val title: String
|
||||
): AIMessage(id,title)
|
||||
|
||||
data class AutomaticExploration(
|
||||
override val id: String,
|
||||
override val title: String
|
||||
): AIMessage(id,title)
|
||||
|
||||
data class EvaluateData(
|
||||
override val id: String,
|
||||
override val title: String,
|
||||
var isFirst:Boolean = true
|
||||
): AIMessage(id,title)
|
||||
|
||||
data class NDEData(
|
||||
override val id: String,
|
||||
override val title: String,
|
||||
var desc: String,
|
||||
var roadList: List<RoadMsg>
|
||||
): AIMessage(id,title)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean
|
||||
|
||||
data class ListenUIState(val show: Boolean, val text: String, val showTips: Boolean = false)
|
||||
@@ -0,0 +1,118 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.data
|
||||
|
||||
import android.os.CountDownTimer
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
|
||||
import com.mogo.eagle.core.data.msgbox.MsgBoxType
|
||||
import com.mogo.eagle.core.data.msgbox.MsgCategory
|
||||
import com.mogo.eagle.core.function.api.datacenter.msgbox.IMsgBoxListener
|
||||
import com.mogo.eagle.core.function.call.msgbox.CallerMsgBoxListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.AIMessageManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
|
||||
/**
|
||||
* 自动探查
|
||||
*/
|
||||
class AutomaticExplorationViewModel: ViewModel(), IMsgBoxListener, ICommonCallback {
|
||||
|
||||
companion object{
|
||||
private const val TAG = "AutomaticExplorationViewModel"
|
||||
private const val EXPLORATION_SHOW_TIME = 300000L //距离用户在触发上一次事件播报的时间5分钟后,自动触发常规道路情况检测
|
||||
}
|
||||
|
||||
private var showViewTimer: CountDownTimer?= null //展示自动探查倒计时
|
||||
private var isCountingDown: Boolean = false //是否处于倒计时中
|
||||
private var hasOrder: Boolean = false // 车当前是否有订单
|
||||
|
||||
fun init(){
|
||||
CommonModel.setRouteLineInfoCallback(TAG,this)
|
||||
CallerMsgBoxListenerManager.addListener(TAG,this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
CommonModel.setRouteLineInfoCallback(TAG,null)
|
||||
CallerMsgBoxListenerManager.removeListener(TAG)
|
||||
}
|
||||
|
||||
override fun showNoTaskView(isTrue: Boolean) {
|
||||
super.showNoTaskView(isTrue)
|
||||
if(isTrue){
|
||||
cancelTimer()
|
||||
currentOrderStatus(false)
|
||||
}else{
|
||||
startShowTimer()
|
||||
currentOrderStatus(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onDataChanged(category: MsgCategory, msgBoxList: MsgBoxBean) {
|
||||
if(category == MsgCategory.NOTICE){
|
||||
if(msgBoxList.type == MsgBoxType.V2X){
|
||||
//重置倒计时时长
|
||||
cancelTimer()
|
||||
if(hasOrder){
|
||||
startShowTimer()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消倒计时
|
||||
*/
|
||||
private fun cancelTimer(){
|
||||
CallerLogger.d(TAG,"cancelTimer")
|
||||
showViewTimer?.cancel()
|
||||
showViewTimer = null
|
||||
isCountingDown = false
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始倒计时
|
||||
*/
|
||||
private fun startShowTimer(){
|
||||
CallerLogger.d(TAG,"startShowTimer")
|
||||
if(!isCountingDown){
|
||||
ThreadUtils.runOnUiThread {
|
||||
if(showViewTimer == null){
|
||||
showViewTimer = object: CountDownTimer(EXPLORATION_SHOW_TIME,EXPLORATION_SHOW_TIME){
|
||||
override fun onTick(millisUntilFinished: Long) {
|
||||
CallerLogger.d(TAG,"倒计时+:${millisUntilFinished}")
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
if(hasOrder){
|
||||
showAutoExploration()
|
||||
}
|
||||
isCountingDown = false
|
||||
}
|
||||
}
|
||||
}
|
||||
isCountingDown = true
|
||||
showViewTimer?.start()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置当前订单状态
|
||||
* @param orderStatus true有订单;false没有订单
|
||||
*/
|
||||
private fun currentOrderStatus(orderStatus: Boolean){
|
||||
hasOrder = orderStatus
|
||||
}
|
||||
|
||||
|
||||
|
||||
private fun showAutoExploration(){
|
||||
val automaticExploration = AIMessage.AutomaticExploration(System.currentTimeMillis().toString(),"")
|
||||
AIMessageManager.post(automaticExploration)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.data
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotIdentifyListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotIdentifyListenerManager
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeListener
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeManager
|
||||
import com.mogo.och.common.module.biz.birdge.data.RoadMsg
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.AIMessageManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
|
||||
/**
|
||||
* 车龙信息
|
||||
*/
|
||||
class NDEViewModel: ViewModel(), BridgeListener {
|
||||
|
||||
companion object{
|
||||
private const val TAG = "NDEViewModel"
|
||||
}
|
||||
|
||||
fun init(){
|
||||
BridgeManager.addBridgeListener(TAG,this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
BridgeManager.removeBridgeListener(TAG)
|
||||
}
|
||||
|
||||
override fun onNdeDataListener(title: String, desc: String, sortedList: List<RoadMsg>) {
|
||||
val ndeEvent = AIMessage.NDEData(System.currentTimeMillis().toString(),title,desc,sortedList)
|
||||
AIMessageManager.post(ndeEvent)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,259 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.data
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mogo.eagle.core.data.autopilot.pnc.PncActionsHelper
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotPlanningActionsListener
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningActionsListenerManager
|
||||
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.AIMessageManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
import mogo.telematics.pad.MessagePad
|
||||
|
||||
class PNCActionsViewModel: ViewModel(), IMoGoAutopilotPlanningActionsListener, ICommonCallback {
|
||||
|
||||
companion object{
|
||||
private const val TAG = "PNCActionsViewModel"
|
||||
}
|
||||
|
||||
private var currentAction = ""
|
||||
|
||||
private var currentStation:BusStationBean?=null
|
||||
|
||||
fun init(){
|
||||
CallerPlanningActionsListenerManager.addListener(TAG, this)
|
||||
CommonModel.setRouteLineInfoCallback(TAG,this)
|
||||
}
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
CallerPlanningActionsListenerManager.removeListener(TAG)
|
||||
CommonModel.setRouteLineInfoCallback(TAG,null)
|
||||
}
|
||||
|
||||
override fun updateStationsInfo(
|
||||
stations: MutableList<BusStationBean>?,
|
||||
currentStationIndex: Int,
|
||||
isArrived: Boolean
|
||||
) {
|
||||
try {
|
||||
currentStation = stations?.get(currentStationIndex)
|
||||
}catch (e:Exception){
|
||||
OchChainLogManager.writeChainLogError("PNCActionsViewModel 设置错误","${e.message}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun showNoTaskView(isTrue: Boolean) {
|
||||
super.showNoTaskView(isTrue)
|
||||
if(isTrue){
|
||||
currentStation = null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun pncActions(planningActionMsg: MessagePad.PlanningActionMsg) {
|
||||
try {
|
||||
BizLoopManager.runInMainThread {
|
||||
if (CallerAutoPilotStatusListenerManager.getState() == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
|
||||
var actions: String? = null
|
||||
planningActionMsg.actionMsg?.let {
|
||||
try {
|
||||
actions = PncActionsHelper.getAction(
|
||||
it.drivingState.number,
|
||||
it.drivingAction.number
|
||||
)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
planningActionMsg.v2NActionMsgList?.forEach { v2nAction ->
|
||||
actions = PncActionsHelper.getAction(
|
||||
v2nAction.drivingState.number,
|
||||
v2nAction.drivingAction.number
|
||||
)
|
||||
}
|
||||
// update view
|
||||
actions?.let {
|
||||
if(it.isNotEmpty() && it != currentAction){
|
||||
currentAction = it
|
||||
val title = getActionTitle(it)
|
||||
if(title.isNotEmpty()){
|
||||
val desc = getActionDesc(title)
|
||||
val action = AIMessage.PNCAction(it+System.currentTimeMillis(),title,desc,System.currentTimeMillis())
|
||||
AIMessageManager.post(action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
private fun getActionTitle(pncAction: String): String{
|
||||
return when(pncAction){
|
||||
"正在进站"->{
|
||||
"车辆进站"
|
||||
}
|
||||
"等待进站"->{
|
||||
"车辆等待进站"
|
||||
}
|
||||
"正在出站"->{
|
||||
"车辆出站"
|
||||
}
|
||||
"等待出站"->{
|
||||
"车辆等待出站"
|
||||
}
|
||||
"正在向左变道"->{
|
||||
"车辆向左变道"
|
||||
}
|
||||
"正在向右变道"->{
|
||||
"车辆向右变道"
|
||||
}
|
||||
"正在完成变道"->{
|
||||
"车辆完成变道"
|
||||
}
|
||||
"正在绕过障碍物"->{
|
||||
"车辆正在绕过前方障碍物"
|
||||
}
|
||||
"正在向左绕行避让前方静止障碍物"->{
|
||||
"车辆正在绕过前方障碍物"
|
||||
}
|
||||
"正在向右绕行避让前方静止障碍物"->{
|
||||
"车辆正在绕过前方障碍物"
|
||||
}
|
||||
"正在避让障碍物"->{
|
||||
"车辆正在避让前方障碍物"
|
||||
}
|
||||
"正在向左变道避让前方静止障碍物"->{
|
||||
"车辆正在避让前方障碍物"
|
||||
}
|
||||
"正在向右变道避让前方静止障碍物"->{
|
||||
"车辆正在避让前方障碍物"
|
||||
}
|
||||
"正在等红灯"->{
|
||||
"路口等红灯"
|
||||
}
|
||||
"正在向左变道避让前方道路施工"->{
|
||||
"车辆正在变道避让前方道路施工"
|
||||
}
|
||||
"正在向右变道避让前方道路施工"->{
|
||||
"车辆正在变道避让前方道路施工"
|
||||
}
|
||||
"正在向左绕行避让前方道路施工"->{
|
||||
"车辆正在绕行避让前方道路施工"
|
||||
}
|
||||
"正在向右绕行避让前方道路施工"->{
|
||||
"车辆正在绕行避让前方道路施工"
|
||||
}
|
||||
|
||||
"正在向左变道避让前方道路事故"->{
|
||||
"车辆正在变道避让前方道路事故"
|
||||
}
|
||||
"正在向右变道避让前方道路事故"->{
|
||||
"车辆正在变道避让前方道路事故"
|
||||
}
|
||||
"正在向左绕行避让前方道路事故"->{
|
||||
"车辆正在绕行避让前方道路事故"
|
||||
}
|
||||
"正在向右绕行避让前方道路事故"->{
|
||||
"车辆正在绕行避让前方道路事故"
|
||||
}
|
||||
"正在跟随车辆行驶"->{
|
||||
"车辆正在跟车通行"
|
||||
}
|
||||
"正在跟车行驶"->{
|
||||
"车辆正在跟车通行"
|
||||
}
|
||||
"正在向左变道避让前方车龙"->{
|
||||
"车辆正在绕行前方车龙"
|
||||
}
|
||||
"正在向右变道避让前方车龙"->{
|
||||
"车辆正在绕行前方车龙"
|
||||
}
|
||||
"正在使用云端规划通过路口"->{
|
||||
"车辆正在使用云端轨迹通行"
|
||||
}
|
||||
"正在避让后方来车"->{
|
||||
"车辆正在避让后方来车"
|
||||
}
|
||||
else->{
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun getActionDesc(action: String): String{
|
||||
return when(action){
|
||||
"车辆进站"->{
|
||||
"前方即将到达${CommonModel.routesResult}," +
|
||||
"车辆正在规划减速并进站停靠,请安心等待车辆停稳再下车哦~"
|
||||
}
|
||||
"车辆等待进站"->{
|
||||
"车辆待环境安全后进站,耐心等几秒,安全比赶路更重要~"
|
||||
}
|
||||
"车辆出站"->{
|
||||
"欢迎乘坐MOGO RoboTaxi~车辆正在规划出站,坐稳扶好哦,我们出发啦!小智持续守护您的行程。"
|
||||
}
|
||||
"车辆等待出站"->{
|
||||
"车辆待环境安全后出站,耐心等几秒,安全比赶路更重要~"
|
||||
}
|
||||
"车辆向左变道"->{
|
||||
"确认环境安全,车辆正在规划平稳向左变道,同时持续监测周边交通参与者动向,放心交给我们吧!"
|
||||
}
|
||||
"车辆向右变道"->{
|
||||
"确认环境安全,车辆正在规划平稳向右变道,同时持续监测周边交通参与者动向,放心交给我们吧!"
|
||||
}
|
||||
"车辆完成变道"->{
|
||||
"变道完成啦,继续前进!小智持续守护您的行程。"
|
||||
}
|
||||
"车辆正在绕过前方障碍物"->{
|
||||
"发现前方障碍物,车辆正在规划平稳变道,即将画出一条完美弧线~"
|
||||
}
|
||||
"车辆正在避让前方障碍物"->{
|
||||
"发现前方障碍物,车辆正在规划平稳避让,诠释优雅与丝滑~"
|
||||
}
|
||||
"车辆完成绕障"->{
|
||||
"绕障完成啦,继续前进!小智持续守护您的行程。"
|
||||
}
|
||||
"路口等红灯"->{
|
||||
"车辆正在路口等红灯,可以安心放空望望窗外~小智一直在您身边哦!"
|
||||
}
|
||||
"车辆正在变道避让前方道路施工"->{
|
||||
"车辆正在提前规划变道避让前方道路施工,稳稳的很安心~您已体验到车路云一体化协同应用场景,是当之无愧的先锋体验官!"
|
||||
}
|
||||
"车辆正在绕行避让前方道路施工"->{
|
||||
"车辆正在提前规划绕行避让前方道路施工,稳稳的很安心~您已体验到车路云一体化协同应用场景,是当之无愧的先锋体验官!"
|
||||
}
|
||||
"车辆正在变道避让前方道路事故"->{
|
||||
"车辆正在提前规划变道避让前方道路事故,放心看我表现吧!您已体验到车路云一体化协同应用场景,小智为您欢呼!"
|
||||
}
|
||||
"车辆正在绕行避让前方道路事故"->{
|
||||
"车辆正在提前规划绕行避让前方道路事故,放心看我表现吧!您已体验到车路云一体化协同应用场景,小智为您欢呼!"
|
||||
}
|
||||
"车辆正在跟车通行"->{
|
||||
"车辆正在跟随前车通行,舒适度MAX~您已体验到车路云一体化协同应用场景,超越全国99%的乘客!"
|
||||
}
|
||||
"车辆正在绕行前方车龙"->{
|
||||
"车辆正在提前规划变道避让路口车龙,舒适度MAX~。您已体验到车路云一体化协同应用场景,超越全国99%的乘客!"
|
||||
}
|
||||
"车辆正在使用云端轨迹通行"->{
|
||||
"前方智慧路口内有障碍物,车辆正在使用云端规划轨迹通行。您已体验到车路云一体化协同应用场景,超越全国99%的乘客!"
|
||||
}
|
||||
"车辆正在避让后方来车"->{
|
||||
"车辆正在避让后方来车,耐心等几秒,安全比赶路更重要~"
|
||||
}
|
||||
else->{
|
||||
""
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.data
|
||||
|
||||
import android.content.Context
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mogo.commons.voice.AIAssist
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.function.api.map.road.IMoGoMapRoadListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerServicesEventManager
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapIdentifyManager
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapRoadListenerManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.AIMessageManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
|
||||
class RoadCrossRoamViewModel: ViewModel(), IMoGoMapRoadListener {
|
||||
|
||||
companion object{
|
||||
const val TAG = "RoadCrossRoamViewModel"
|
||||
}
|
||||
|
||||
private lateinit var mContext: Context
|
||||
|
||||
fun init(context: Context){
|
||||
CallerMapRoadListenerManager.addListener(TAG, this)
|
||||
mContext = context
|
||||
}
|
||||
|
||||
override fun onCrossDevice(trigger: Boolean) {
|
||||
super.onCrossDevice(trigger)
|
||||
if(trigger){
|
||||
show()
|
||||
}
|
||||
}
|
||||
|
||||
private fun show(){
|
||||
// 没有路线不做提示
|
||||
if (CallerAutoPilotStatusListenerManager.getLineId() == 0L) {
|
||||
CallerLogger.d(TAG, "没有路线不做提示")
|
||||
return
|
||||
}
|
||||
// 首页被遮挡不做提示
|
||||
if (!CallerHmiViewControlListenerManager.getMainPageVisible()) {
|
||||
CallerLogger.d(TAG, "attachView return , mainPageVisible is false")
|
||||
return
|
||||
}
|
||||
// 没有路侧设备,不做处理
|
||||
CallerLogger.d(TAG, "命中,attachView")
|
||||
val cross = CallerMapRoadListenerManager.getCrossEndInfo()
|
||||
if (cross.isNullOrEmpty()) {
|
||||
CallerLogger.d(TAG, "未触发,路口ID:$cross")
|
||||
return
|
||||
}
|
||||
if (AppIdentityModeUtils.isDriver(FunctionBuildConfig.appIdentityMode)){
|
||||
val disStr = "为您提供路口全息影像,助力出行"
|
||||
AIAssist.getInstance(mContext).speakTTSVoiceWithLevel(disStr, AIAssist.NEW_LEVEL_2)
|
||||
}
|
||||
CallerServicesEventManager.updateServicesNum(CallerServicesEventManager.ServiceType.ROAD)
|
||||
AIMessageManager.post(AIMessage.RoadCrossRoam(System.currentTimeMillis().toString(),""))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.mind.data
|
||||
|
||||
import androidx.lifecycle.ProcessLifecycleOwner
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.mogo.commons.utils.MogoAnalyticUtils
|
||||
import com.mogo.eagle.core.data.v2x.RoadV2NEventWindowBean
|
||||
import com.mogo.eagle.core.function.api.hmi.v2n.IRoadV2NEventWindowListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerRoadV2NEventWindowListenerManager
|
||||
import com.mogo.eagle.core.function.hmi.ui.utils.HmiActionLog
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.AIMessageManager
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.mind.bean.AIMessage
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class RoadV2NEventViewModel: ViewModel(), IRoadV2NEventWindowListener {
|
||||
|
||||
companion object{
|
||||
const val TAG = "RoadV2NEventViewModel"
|
||||
const val ANALYTICS_KEY = "hmi_road_event_window_view"
|
||||
|
||||
fun trackEvent(msg: String) {
|
||||
ProcessLifecycleOwner.get().lifecycleScope.launch(Dispatchers.IO) {
|
||||
val map: MutableMap<String, Any> = HashMap()
|
||||
map["msg"] = msg
|
||||
MogoAnalyticUtils.track(
|
||||
ANALYTICS_KEY,
|
||||
map
|
||||
)
|
||||
HmiActionLog.hmiAction(TAG, msg)
|
||||
}
|
||||
CallerLogger.i(TAG, msg)
|
||||
}
|
||||
}
|
||||
|
||||
fun init(){
|
||||
CallerRoadV2NEventWindowListenerManager.addListener(TAG, this)
|
||||
}
|
||||
|
||||
override fun show(dataBean: RoadV2NEventWindowBean) {
|
||||
trackEvent("show --> $dataBean")
|
||||
val canShowV2NEventWindowView = CallerHmiViewControlListenerManager.getMainPageVisible()
|
||||
if (!canShowV2NEventWindowView) {
|
||||
trackEvent("show --> 当前不在高精地图页面,跳过")
|
||||
return
|
||||
}
|
||||
val lineId = CallerAutoPilotStatusListenerManager.getLineId()
|
||||
if (lineId <= 0) {
|
||||
trackEvent("show --> 当前无订单,跳过")
|
||||
return
|
||||
}
|
||||
val event = AIMessage.RoadV2NEvent(
|
||||
dataBean.eventId,
|
||||
dataBean.hintStr,
|
||||
"",
|
||||
dataBean.eventType,
|
||||
dataBean.timestamp,
|
||||
dataBean.iconResId,
|
||||
false,
|
||||
dataBean.contentImageUrl,
|
||||
dataBean.cameraIp,
|
||||
dataBean.lon,
|
||||
dataBean.lat
|
||||
)
|
||||
AIMessageManager.post(event)
|
||||
}
|
||||
|
||||
override fun dismiss(eventId: String) {
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,30 +1,29 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.widget
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.statusbar
|
||||
|
||||
import android.annotation.*
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import chassis.ChassisStatesOuterClass
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisStatesListener
|
||||
import com.mogo.eagle.core.function.api.hmi.view.IViewControlListener
|
||||
import com.mogo.eagle.core.function.api.setting.IMoGoSkinModeChangeListener
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerChassisStatesListenerManager
|
||||
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager
|
||||
import com.mogo.eagle.core.function.call.hmi.CallerHmiViewControlListenerManager
|
||||
import com.mogo.eagle.core.function.call.setting.CallerSkinModeListenerManager
|
||||
import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView
|
||||
import com.mogo.eagle.core.utilcode.kotlin.*
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.util.ClickUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.mogo.och.common.module.manager.bluetooth.BleManager
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_view_status_bar.view.aciv_wait_ele
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_view_status_bar.view.iv_logon
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_view_status_bar.view.progress
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_view_status_bar.view.tv_power_cos
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_view_status_bar.view.tv_status_line_name
|
||||
import kotlinx.coroutines.*
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
|
||||
@@ -34,8 +33,8 @@ import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
*/
|
||||
class M2StatusBarView @JvmOverloads constructor(
|
||||
context: Context, attrs: AttributeSet? = null
|
||||
) : ConstraintLayout(context, attrs), IViewControlListener, IMoGoSkinModeChangeListener,
|
||||
IMoGoChassisStatesListener {
|
||||
) : ConstraintLayout(context, attrs),
|
||||
IMoGoChassisStatesListener, ICommonCallback {
|
||||
|
||||
companion object {
|
||||
const val TAG = "M2StatusBarView"
|
||||
@@ -46,59 +45,70 @@ class M2StatusBarView @JvmOverloads constructor(
|
||||
|
||||
init {
|
||||
LayoutInflater.from(context).inflate(R.layout.shuttle_p_m2_view_status_bar, this, true)
|
||||
setBackgroundColor(Color.parseColor("#80FFFFFF"))
|
||||
setBackgroundColor(ResourcesUtils.getColor(R.color.white))
|
||||
isClickable = true
|
||||
isFocusable = true
|
||||
iv_logon.setOnLongClickListener {
|
||||
context?.let {
|
||||
ToggleDebugView.toggleDebugView.toggle(it)
|
||||
}
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@SuppressLint("ClickableViewAccessibility")
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
|
||||
CallerLogger.d(TAG,"onAttachedToWindow-------${this}")
|
||||
|
||||
post {
|
||||
val params: ViewGroup.LayoutParams = getLayoutParams()
|
||||
params.height = AutoSizeUtils.dp2px(context,60f)
|
||||
params.height = AutoSizeUtils.dp2px(context,100f)
|
||||
layoutParams = params
|
||||
}
|
||||
//添加view控制
|
||||
CallerHmiViewControlListenerManager.addListener(TAG,this)
|
||||
// 添加换肤监听
|
||||
CallerSkinModeListenerManager.addListener(TAG, this)
|
||||
|
||||
//电量
|
||||
CallerChassisStatesListenerManager.addListener(TAG,this)
|
||||
CommonModel.setRouteLineInfoCallback(TAG,this)
|
||||
|
||||
progress?.also {
|
||||
it.progress = 0
|
||||
aciv_wait_ele.visibility = VISIBLE
|
||||
}
|
||||
tv_power_cos?.also {
|
||||
it.text = "检测中"
|
||||
}
|
||||
iv_logon.onClick {
|
||||
BizLoopManager.runInMainThread{
|
||||
BleManager.scanLeDevice()
|
||||
}
|
||||
it.text = "?"
|
||||
}
|
||||
|
||||
tv_power_cos.onClick {
|
||||
BizLoopManager.runInIoThread {
|
||||
BleManager.sendData2Wx("1889480", "00,${System.currentTimeMillis()}")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onSkinModeChange(skinMode: Int) {
|
||||
when (skinMode) {
|
||||
0 -> setStatusBarDarkOrLight(false)
|
||||
1 -> setStatusBarDarkOrLight(true)
|
||||
override fun updateLineInfo(lineName: String?) {
|
||||
post {
|
||||
CallerLogger.d(TAG,"updateLineInfo2-------${lineName}----${this}")
|
||||
if(lineName==null){
|
||||
tv_status_line_name.setText(R.string.m2_line_name_detaile)
|
||||
}else{
|
||||
tv_status_line_name.text = lineName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun showNoTaskView(isTrue: Boolean) {
|
||||
BizLoopManager.runInMainThread {
|
||||
CallerLogger.d(TAG,"updateLineInfo1-------${isTrue}----${this}")
|
||||
if(isTrue) {
|
||||
tv_status_line_name.setText(R.string.m2_line_name_detaile)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
CallerHmiViewControlListenerManager.removeListener(TAG)
|
||||
CallerSkinModeListenerManager.removeListener(TAG)
|
||||
CallerChassisStatesListenerManager.removeListener(TAG)
|
||||
CallerDevaToolsManager.hideStatusBar()
|
||||
CommonModel.setRouteLineInfoCallback(TAG,null)
|
||||
}
|
||||
|
||||
@SuppressLint("SetTextI18n")
|
||||
@@ -112,14 +122,11 @@ class M2StatusBarView @JvmOverloads constructor(
|
||||
if (oldBmsSoc != bmsSoc ) {
|
||||
scope.launch {
|
||||
if(bmsSoc >1){
|
||||
progress?.also { it.progress = bmsSoc.toInt() }
|
||||
tv_power_cos?.also { it.text = "${bmsSoc.toInt()}%" }
|
||||
}else{
|
||||
val power = (bmsSoc * 100).toInt()
|
||||
progress?.also { it.progress = power }
|
||||
tv_power_cos?.also {it.text = "$power%" }
|
||||
}
|
||||
aciv_wait_ele.visibility = GONE
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
@@ -0,0 +1,19 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import com.mogo.eagle.core.function.view.MapBizView
|
||||
import com.mogo.eagle.core.widget.media.video.TextureVideoViewOutlineProvider
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
|
||||
class OchMapBizPView(context: Context?, attrs: AttributeSet?) : MapBizView(context, attrs) {
|
||||
|
||||
|
||||
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
|
||||
super.onSizeChanged(w, h, oldw, oldh)
|
||||
this.outlineProvider =
|
||||
TextureVideoViewOutlineProvider(AutoSizeUtils.dp2px(context, 36f).toFloat())
|
||||
this.clipToOutline = true
|
||||
}
|
||||
|
||||
}
|
||||
@@ -9,17 +9,15 @@ import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ActivityUtils
|
||||
import com.mogo.eagle.core.utilcode.util.DeviceUtils
|
||||
import com.mogo.eagle.core.utilcode.util.MultiDisplayUtils
|
||||
import com.mogo.och.bridge.ui.autopilot.AutopilotState
|
||||
import com.mogo.och.common.module.constant.OchCommonConst
|
||||
import com.mogo.och.common.module.biz.provider.CommonServiceImpl
|
||||
import com.mogo.och.common.module.biz.scanner.ScannerManager
|
||||
import com.mogo.och.common.module.voice.OutOffVoice
|
||||
import com.mogo.och.common.module.wigets.media.MediaPlayerActivity
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.TicketModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.widget.BusPStatusBarView
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.BusPassengerRouteFragment
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.PM2BaseFragment
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.widget.M2StatusBarView
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.statusbar.M2StatusBarView
|
||||
|
||||
/**
|
||||
* 网约车-Bus-乘客端
|
||||
|
||||
@@ -9,16 +9,16 @@ import java.util.List;
|
||||
* @date: 2022/4/6
|
||||
*/
|
||||
public interface ICommonCallback {
|
||||
void updateLineInfo(String lineName);
|
||||
void updateStationsInfo(List<BusStationBean> stations, int currentStationIndex, boolean isArrived);
|
||||
void updateSpeed(int location);
|
||||
void updateRemainMT(long meters, long timeInSecond);
|
||||
void showNoTaskView(boolean isTrue);
|
||||
default void updateLineInfo(String lineName){}
|
||||
default void updateStationsInfo(List<BusStationBean> stations, int currentStationIndex, boolean isArrived){}
|
||||
default void updateSpeed(int location){}
|
||||
default void updateRemainMT(long meters, long timeInSecond){}
|
||||
default void showNoTaskView(boolean isTrue){}
|
||||
|
||||
/**
|
||||
* false: 未开启自驾, true : 开启自驾
|
||||
*/
|
||||
void updateAutoStatus(boolean isOpen);
|
||||
default void updateAutoStatus(boolean isOpen){}
|
||||
|
||||
default void updateLineStations(List<BusStationBean> stations){}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import com.mogo.och.bridge.autopilot.location.OchLocationManager
|
||||
import com.mogo.och.bridge.distance.IDistanceListener
|
||||
import com.mogo.och.bridge.distance.TrajectoryAndDistanceManager
|
||||
import com.mogo.och.common.module.biz.birdge.BridgeManager
|
||||
import com.mogo.och.common.module.constant.OchCommonConst
|
||||
import com.mogo.och.common.module.manager.download.DownloadManager
|
||||
import com.mogo.och.common.module.manager.socket.cloud.OCHSocketMessageManager
|
||||
import com.mogo.och.common.module.manager.socket.lan.ILanMessageListener
|
||||
@@ -55,7 +56,7 @@ object CommonModel {
|
||||
var mContext: Context? = null
|
||||
|
||||
|
||||
private var mCommonCallback: ICommonCallback? = null // bus路线信息更新
|
||||
private var mCommonCallbackList = mutableMapOf<String,ICommonCallback>()
|
||||
|
||||
var mStations = mutableListOf<BusStationBean>()
|
||||
var mNextStationIndex = 0 // A-B要到达站的index
|
||||
@@ -99,11 +100,16 @@ object CommonModel {
|
||||
LanSocketManager.unRegisterSocketMessageListener(DPMsgType.TYPE_TASK_DETAILS.type, typeTaskDetails)
|
||||
LoginLanPassengerSocket.removeListener(TAG)
|
||||
cleanStation("release")
|
||||
this.mCommonCallbackList.clear()
|
||||
}
|
||||
|
||||
|
||||
fun setRouteLineInfoCallback(callback: ICommonCallback?) {
|
||||
this.mCommonCallback = callback
|
||||
fun setRouteLineInfoCallback(tag:String,callback: ICommonCallback?) {
|
||||
if(callback==null){
|
||||
this.mCommonCallbackList.remove(tag)
|
||||
return
|
||||
}
|
||||
this.mCommonCallbackList[tag] = callback
|
||||
}
|
||||
|
||||
|
||||
@@ -141,19 +147,25 @@ object CommonModel {
|
||||
mNextStationIndex >= 0 && mNextStationIndex <= mStations.size - 1
|
||||
&& isGoingToNextStation
|
||||
){
|
||||
mCommonCallback?.updateAutoStatus(true)
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.updateAutoStatus(true)
|
||||
}
|
||||
}else{//非美化模式下
|
||||
mCommonCallback?.updateAutoStatus(false)
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.updateAutoStatus(false)
|
||||
}
|
||||
}
|
||||
}else{//自驾状态 2
|
||||
mCommonCallback?.updateAutoStatus(true)
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.updateAutoStatus(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val trajectoryListener: IDistanceListener = object : IDistanceListener {
|
||||
override fun distanceCallback(distance: Float) {
|
||||
val lastTime = distance / BusPassengerConst.BUS_AVERAGE_SPEED * 3.6 //秒
|
||||
val lastTime = distance / OchCommonConst.BUS_AVERAGE_SPEED * 3.6 //秒
|
||||
d(TAG, "轨迹排查==lastSumLength = $distance")
|
||||
if (routesResult != null) {
|
||||
for (site in routesResult!!.sites) {
|
||||
@@ -172,10 +184,12 @@ object CommonModel {
|
||||
}
|
||||
}
|
||||
}
|
||||
mCommonCallback?.updateRemainMT(
|
||||
distance.toLong(),
|
||||
lastTime.toLong()
|
||||
)
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.updateRemainMT(
|
||||
distance.toLong(),
|
||||
lastTime.toLong()
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +240,9 @@ object CommonModel {
|
||||
mNextStationIndex = 0
|
||||
cleanStation("queryDriverSiteByCoordinate")
|
||||
isGoingToNextStation = false
|
||||
mCommonCallback?.showNoTaskView(true)
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.showNoTaskView(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -238,20 +254,26 @@ object CommonModel {
|
||||
|
||||
if (routesResult != null && routesResult!!.lineId != result.lineId) {
|
||||
d(TAG, "lineId change= clearCustomPolyline")
|
||||
mCommonCallback?.clearCustomPolyline()
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.clearCustomPolyline()
|
||||
}
|
||||
}
|
||||
|
||||
d(TAG, "queryDriverSiteByCoordinate = update")
|
||||
d(TAG, "queryDriverSiteByCoordinate = update ${result}")
|
||||
routesResult = result
|
||||
|
||||
if (result.sites != null) {
|
||||
mCommonCallback?.updateLineInfo(result.name)
|
||||
mCommonCallback?.showNoTaskView(false)
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.updateLineInfo(result.name)
|
||||
it.value.showNoTaskView(false)
|
||||
}
|
||||
if (result.sites != null) {
|
||||
val stations = result.sites
|
||||
mStations.clear()
|
||||
mStations.addAll(stations)
|
||||
mCommonCallback?.updateLineStations(mStations)
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.updateLineStations(mStations)
|
||||
}
|
||||
for (i in stations.indices) {
|
||||
val station = stations[i]
|
||||
if(station.drivingStatus == BusPassengerConst.STATION_STATUS_STOPPED){
|
||||
@@ -259,7 +281,9 @@ object CommonModel {
|
||||
if (station.isLeaving && i + 1 < stations.size
|
||||
) {
|
||||
isGoingToNextStation = true
|
||||
mCommonCallback?.updateStationsInfo(stations, i + 1, false)
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.updateStationsInfo(stations, i + 1, false)
|
||||
}
|
||||
mNextStationIndex = i + 1
|
||||
val startStation = mStations[i]
|
||||
val endStation = mStations[i + 1]
|
||||
@@ -272,7 +296,9 @@ object CommonModel {
|
||||
}
|
||||
isGoingToNextStation = false
|
||||
Logger.d(TAG, "order = station= arrive")
|
||||
mCommonCallback?.updateStationsInfo(stations, i, true)
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.updateStationsInfo(stations, i, true)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -411,6 +437,8 @@ object CommonModel {
|
||||
// km/h
|
||||
val speedKM = (abs(mogoLocation.gnssSpeed) * 3.6f).toInt()
|
||||
|
||||
mCommonCallback?.updateSpeed(speedKM)
|
||||
mCommonCallbackList.forEach {
|
||||
it.value.updateSpeed(speedKM)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.presenter
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.mogo.commons.mvp.Presenter
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ADASCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.constant.M2Const.Companion.M2_MAP_STATION_MAKER
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.PM2ADASModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.PM2HPMapFragment
|
||||
|
||||
class PM2ADASPresenter(view: PM2HPMapFragment?) :
|
||||
Presenter<PM2HPMapFragment?>(view), ADASCallback {
|
||||
|
||||
init {
|
||||
PM2ADASModel.INSTANCE.init(context)
|
||||
initListener()
|
||||
}
|
||||
|
||||
private fun initListener() {
|
||||
PM2ADASModel.INSTANCE.setAdasCallback(this)
|
||||
}
|
||||
|
||||
private fun removeListener() {
|
||||
PM2ADASModel.INSTANCE.setAdasCallback(null)
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
super.onDestroy(owner)
|
||||
removeListener()
|
||||
}
|
||||
|
||||
override fun updateHDMapStations(stations: MutableList<MutableList<Double>>) {
|
||||
for (i in stations.indices){
|
||||
mView?.setMapMaker(M2_MAP_STATION_MAKER+i,stations[i])
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun removeHDMapStations() {
|
||||
mView?.removeMapMaker(M2_MAP_STATION_MAKER)
|
||||
}
|
||||
}
|
||||
@@ -1,124 +0,0 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.presenter
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.mogo.commons.mvp.Presenter
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.PM2ADASModel
|
||||
import com.mogo.och.shuttle.weaknet.passenger.ui.PM2DrivingInfoFragment
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.shuttle.weaknet.passenger.callback.ICommonCallback
|
||||
import com.mogo.och.shuttle.weaknet.passenger.model.CommonModel
|
||||
|
||||
class PM2DrivingPresenter(view: PM2DrivingInfoFragment?) :
|
||||
Presenter<PM2DrivingInfoFragment?>(view),
|
||||
ICommonCallback {
|
||||
|
||||
init {
|
||||
CommonModel.init(context)
|
||||
PM2ADASModel.INSTANCE.init(context)
|
||||
initListener()
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
super.onDestroy(owner)
|
||||
destroyListener()
|
||||
CommonModel.releaseListeners()
|
||||
}
|
||||
|
||||
private fun initListener(){
|
||||
CommonModel.setRouteLineInfoCallback(this)
|
||||
}
|
||||
|
||||
private fun destroyListener(){
|
||||
CommonModel.setRouteLineInfoCallback(null)
|
||||
}
|
||||
|
||||
override fun updateSpeed(speed: Int) {
|
||||
// CallerLogger.d(
|
||||
// SceneConstant.M_BUS_P + "speed = ",speed.toString()
|
||||
// )
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateSpeed(speed)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateLineInfo(lineName: String) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateTaskName(lineName)
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateRemainMT(meters: Long, timeInSecond: Long) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateRemainMT(meters, timeInSecond) //米,秒
|
||||
}
|
||||
}
|
||||
|
||||
override fun showNoTaskView(isTrue: Boolean) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.showNoTaskView(!isTrue)
|
||||
}
|
||||
if (isTrue){
|
||||
PM2ADASModel.INSTANCE.removeHDMapStations()
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateLineStations(stations: MutableList<BusStationBean>) {
|
||||
|
||||
val stationsList = mutableListOf<LatLng>()
|
||||
val stationsListPass = mutableListOf<LatLng>()
|
||||
var startStation: LatLng? = null
|
||||
var endStation: LatLng? = null
|
||||
|
||||
for (i in stations.indices){
|
||||
val station = stations[i]
|
||||
val latLng = LatLng(station.gcjLat,station.gcjLon)
|
||||
if(i==0){
|
||||
startStation = latLng
|
||||
continue
|
||||
}
|
||||
if(i==stations.size-1){
|
||||
endStation = latLng
|
||||
continue
|
||||
}
|
||||
if(station.drivingStatus==1){//行驶信息,0初始值;1已经过;2当前站;3未到站
|
||||
stationsListPass.add(latLng)
|
||||
}else if(station.drivingStatus==2){
|
||||
if(station.isLeaving){
|
||||
stationsListPass.add(latLng)
|
||||
}else{
|
||||
stationsList.add(latLng)
|
||||
}
|
||||
}else{
|
||||
stationsList.add(latLng)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateLineStations(stationsList,stationsListPass,startStation,endStation)
|
||||
}
|
||||
PM2ADASModel.INSTANCE.updateHDMapStations(stations)
|
||||
}
|
||||
|
||||
override fun updateStationsInfo(stations: MutableList<BusStationBean>, i: Int, isArrived: Boolean) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateStationsInfo(stations,i,isArrived)
|
||||
}
|
||||
}
|
||||
|
||||
override fun clearCustomPolyline() {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.clearCustomPolyline()
|
||||
}
|
||||
}
|
||||
|
||||
override fun updateAutoStatus(isOpen: Boolean) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
mView?.updateAutoStatus(isOpen)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui
|
||||
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.FrameLayout
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.eagle.core.utilcode.util.AppUtils
|
||||
import com.mogo.och.common.module.biz.media.MediaManager
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.manager.transform.OchTransform
|
||||
import com.mogo.och.common.module.manager.transform.OchTransformDispatch
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.presenter.PM2Presenter
|
||||
import com.mogo.och.common.module.wigets.media.MediaPlayerFragment
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_fragment.tv_shuttle_b2_p_version
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_fragment.video_fragment
|
||||
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/4/12
|
||||
*/
|
||||
class PM2BaseFragment :
|
||||
MvpFragment<PM2BaseFragment?, PM2Presenter?>() {
|
||||
|
||||
private var drivingFragment : PM2DrivingInfoFragment? = null
|
||||
private var hdMapFragment : PM2HPMapFragment? = null
|
||||
private var mediaFragment : MediaPlayerFragment? = null
|
||||
|
||||
private val ochTransform = object : OchTransformDispatch{
|
||||
override fun setVideoView(target: View?) {
|
||||
super.setVideoView(target)
|
||||
if(target!=null){
|
||||
BizLoopManager.runInMainThread{
|
||||
target.id = R.id.video_show
|
||||
val params = FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT)
|
||||
video_fragment.addView(target,params)
|
||||
MediaManager.setMediaPause()
|
||||
}
|
||||
}else{
|
||||
BizLoopManager.runInMainThread{
|
||||
findViewById<View>(R.id.video_show)?.let {
|
||||
video_fragment.removeView(it)
|
||||
MediaManager.setMediaResume()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.shuttle_p_m2_fragment
|
||||
}
|
||||
|
||||
override fun getTagName(): String {
|
||||
return TAG
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
tv_shuttle_b2_p_version.text = "版本:${AppUtils.getAppVersionName()}"
|
||||
//隐藏小地图
|
||||
initFragment()
|
||||
OchTransform.addListener(TAG,ochTransform)
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
OchTransform.removeListener(TAG)
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化行程信息,高静地图,宣传 三个fragment
|
||||
*/
|
||||
private fun initFragment() {
|
||||
|
||||
if (drivingFragment == null) drivingFragment = PM2DrivingInfoFragment()
|
||||
childFragmentManager.beginTransaction().add(R.id.driving_fragment, drivingFragment!!)
|
||||
.show(drivingFragment!!).commitAllowingStateLoss()
|
||||
|
||||
if (hdMapFragment == null) hdMapFragment = PM2HPMapFragment()
|
||||
childFragmentManager.beginTransaction().add(R.id.hd_map_fragment, hdMapFragment!!)
|
||||
.show(hdMapFragment!!).commitAllowingStateLoss()
|
||||
|
||||
if (mediaFragment == null) mediaFragment = MediaPlayerFragment()
|
||||
childFragmentManager.beginTransaction().add(R.id.video_fragment, mediaFragment!!)
|
||||
.show(mediaFragment!!).commitAllowingStateLoss()
|
||||
}
|
||||
|
||||
override fun createPresenter(): PM2Presenter {
|
||||
return PM2Presenter(this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
public val TAG = PM2BaseFragment::class.java.simpleName
|
||||
}
|
||||
}
|
||||
@@ -1,285 +0,0 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui
|
||||
|
||||
import android.graphics.BitmapFactory
|
||||
import android.graphics.drawable.AnimationDrawable
|
||||
import android.os.Bundle
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.amap.api.maps.model.LatLng
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.eagle.core.function.hmi.ui.setting.ToggleDebugView
|
||||
import com.mogo.eagle.core.function.view.SiteMarkerBean
|
||||
import com.mogo.eagle.core.widget.media.video.TextureVideoViewOutlineProvider
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.presenter.PM2DrivingPresenter
|
||||
import com.mogo.och.common.module.utils.NumberFormatUtil
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.auto_tv
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.clg_distance_left_time
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.group_not_select_line
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.group_stationinfo
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.iv_animal_list
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.line_name_tv
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.overMapView
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.speed_tv
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.station_name_tv
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.tv_arrived_notice
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.tv_distance
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.tv_left_time
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_driving_info_fragment.tv_next_station_title
|
||||
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
import kotlin.math.ceil
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/4/12
|
||||
*/
|
||||
class PM2DrivingInfoFragment :
|
||||
MvpFragment<PM2DrivingInfoFragment?, PM2DrivingPresenter?>() {
|
||||
|
||||
private val stationIcon = BitmapFactory.decodeResource(
|
||||
AbsMogoApplication.getApp().resources,
|
||||
R.drawable.shuttle_p_m2_map_staton_icon
|
||||
)
|
||||
private val stationPassIcon = BitmapFactory.decodeResource(
|
||||
AbsMogoApplication.getApp().resources,
|
||||
R.drawable.shuttle_p_m2_map_staton_arrived_icon
|
||||
)
|
||||
private val startStationIcon = BitmapFactory.decodeResource(
|
||||
AbsMogoApplication.getApp().resources,
|
||||
R.drawable.shuttle_p_m2_map_start_icon
|
||||
)
|
||||
private val endStationIcon = BitmapFactory.decodeResource(
|
||||
AbsMogoApplication.getApp().resources,
|
||||
R.drawable.shuttle_p_m2_map_end_icon
|
||||
)
|
||||
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.shuttle_p_m2_driving_info_fragment
|
||||
}
|
||||
|
||||
override fun getTagName(): String {
|
||||
return TAG
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
speed_tv.setOnLongClickListener {
|
||||
context?.let { ToggleDebugView.toggleDebugView.toggle(it) }
|
||||
true
|
||||
}
|
||||
|
||||
line_name_tv.setTextColor(ResourcesUtils.getColor(R.color.shuttle_p_m2_line_name_tv_color))
|
||||
station_name_tv.setTextColor(ResourcesUtils.getColor(R.color.shuttle_p_m2_line_name_tv_color))
|
||||
speed_tv.setVertrial(true)
|
||||
val intArrayOf = intArrayOf(
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_43cefe),
|
||||
ResourcesUtils.getColor(R.color.shuttle_p_m2_color_1466fb),
|
||||
)
|
||||
speed_tv.setmColorList(intArrayOf)
|
||||
}
|
||||
|
||||
override fun initViews(savedInstanceState: Bundle?) {
|
||||
super.initViews(savedInstanceState)
|
||||
overMapView?.let {
|
||||
it.onCreateView(savedInstanceState)
|
||||
val radius = AutoSizeUtils.dp2px(requireContext(), 16f)
|
||||
it.outlineProvider = TextureVideoViewOutlineProvider(radius.toFloat())
|
||||
it.clipToOutline = true
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
overMapView?.onResume()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
overMapView?.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
overMapView?.onDestroy()
|
||||
mPresenter?.onDestroy(this)
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
fun updateSpeed(speed: Int) {
|
||||
speed_tv.text = speed.toString()
|
||||
}
|
||||
|
||||
fun updateTaskName(name: String) {
|
||||
line_name_tv.text = name
|
||||
}
|
||||
|
||||
fun showNoTaskView(haveTask: Boolean) {
|
||||
setLineInfoView(haveTask)
|
||||
}
|
||||
|
||||
private fun setLineInfoView(isShow: Boolean) {
|
||||
if (!isShow) {
|
||||
updateNoOrderUI()
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateNoOrderUI() {
|
||||
line_name_tv.text = resources.getString(R.string.shuttle_p_m2_not_select_line_content)
|
||||
updateNoStationView()
|
||||
overMapView?.clearSiteMarkers()
|
||||
clearCustomPolyline()
|
||||
}
|
||||
|
||||
fun clearCustomPolyline() {
|
||||
overMapView?.clearCustomPolyline()
|
||||
}
|
||||
|
||||
private fun updateNoStationView() {
|
||||
station_name_tv.setTextColor(ResourcesUtils.getColor(R.color.shuttle_p_m2_next_tv_color))
|
||||
station_name_tv.text = resources.getString(R.string.shuttle_p_m2_empty_tv)
|
||||
tv_distance.text = resources.getString(R.string.shuttle_p_m2_empty_remain_km)
|
||||
tv_left_time.text = resources.getString(R.string.shuttle_p_m2_empty_remain_minute)
|
||||
noLineShow()
|
||||
}
|
||||
|
||||
override fun createPresenter(): PM2DrivingPresenter {
|
||||
return PM2DrivingPresenter(this)
|
||||
}
|
||||
|
||||
fun updateAutoStatus(isAutoPilot: Boolean) {
|
||||
if (isAutoPilot) {
|
||||
context?.let {
|
||||
auto_tv.setTextColor(
|
||||
ContextCompat.getColor(
|
||||
it,
|
||||
R.color.shuttle_p_m2_white_color
|
||||
)
|
||||
)
|
||||
}
|
||||
context?.let {
|
||||
auto_tv.background =
|
||||
ContextCompat.getDrawable(it, R.drawable.shuttle_p_m2_auto_button_bg)
|
||||
}
|
||||
} else {
|
||||
context?.let {
|
||||
auto_tv.setTextColor(
|
||||
ContextCompat.getColor(
|
||||
it,
|
||||
R.color.shuttle_p_m2_color_7094ad
|
||||
)
|
||||
)
|
||||
}
|
||||
context?.let {
|
||||
auto_tv.background =
|
||||
ContextCompat.getDrawable(it, R.drawable.shuttle_p_m2_bg_p_m2_auto)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun updateLineStations(
|
||||
stations: MutableList<LatLng>,
|
||||
stationsPass: MutableList<LatLng>,
|
||||
startStation: LatLng?,
|
||||
endStation: LatLng?
|
||||
) {
|
||||
overMapView?.let {
|
||||
val stationsList: MutableList<SiteMarkerBean> = mutableListOf()
|
||||
startStation?.let { start ->
|
||||
stationsList.add(SiteMarkerBean(start, startStationIcon, 0.5f, 0.5f))
|
||||
}
|
||||
for (stationPass in stationsPass) {
|
||||
stationsList.add(SiteMarkerBean(stationPass, stationPassIcon, 0.5f, 0.5f))
|
||||
}
|
||||
for (stationPass in stations) {
|
||||
stationsList.add(SiteMarkerBean(stationPass, stationIcon, 0.5f, 0.5f))
|
||||
}
|
||||
endStation?.let { end ->
|
||||
stationsList.add(SiteMarkerBean(end, endStationIcon, 0.5f, 0.5f))
|
||||
}
|
||||
it.drawSiteMarkers(stationsList)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateStationsInfo(stations: MutableList<BusStationBean>, i: Int, isArrived: Boolean) {
|
||||
if (stations.size == 0) return
|
||||
if (0 <= i && i < stations.size) {
|
||||
station_name_tv.setTextColor(ResourcesUtils.getColor(R.color.shuttle_p_m2_next_tv_color))
|
||||
station_name_tv.text = stations[i].name
|
||||
}
|
||||
if (isArrived) {//到站
|
||||
tv_distance.text = resources.getString(R.string.shuttle_p_m2_empty_remain_km)
|
||||
tv_left_time.text = resources.getString(R.string.shuttle_p_m2_empty_remain_minute)
|
||||
tv_next_station_title.text =
|
||||
resources.getString(R.string.shuttle_p_m2_station_title_arrived_tv)
|
||||
haveLineAndArrivedStation()
|
||||
} else { //前往目的地中
|
||||
tv_next_station_title.text =
|
||||
resources.getString(R.string.shuttle_p_m2_next_station_title)
|
||||
haveLineAndArriveingStation()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 剩余里程和时间
|
||||
*/
|
||||
fun updateRemainMT(meters: Long, timeInSecond: Long) { //米。秒
|
||||
var disUnit = "公里"
|
||||
var remainDis: String? = "0"
|
||||
|
||||
if (meters > 0) {
|
||||
if (meters / 1000 < 1) {
|
||||
disUnit = "米"
|
||||
remainDis = meters.toFloat().roundToInt().toString()
|
||||
} else {
|
||||
disUnit = "公里"
|
||||
remainDis = NumberFormatUtil.formatLong(meters.toDouble() / 1000)
|
||||
}
|
||||
}
|
||||
|
||||
val time = ceil(timeInSecond / 60f).toInt()
|
||||
|
||||
"$remainDis$disUnit".also { tv_distance.text = it }
|
||||
"${time}分钟".also { tv_left_time.text = it }
|
||||
}
|
||||
|
||||
fun noLineShow() {
|
||||
// 没有线路展示
|
||||
group_not_select_line.visibility = View.VISIBLE
|
||||
// 下一个站点
|
||||
group_stationinfo.visibility = View.GONE
|
||||
// 距离和剩余大概时间
|
||||
clg_distance_left_time.visibility = View.GONE
|
||||
// 到达站点
|
||||
tv_arrived_notice.visibility = View.GONE
|
||||
|
||||
iv_animal_list.visibility = View.GONE
|
||||
}
|
||||
|
||||
// 有线路正在到站点
|
||||
fun haveLineAndArriveingStation() {
|
||||
group_not_select_line.visibility = View.GONE
|
||||
group_stationinfo.visibility = View.VISIBLE
|
||||
clg_distance_left_time.visibility = View.VISIBLE
|
||||
tv_arrived_notice.visibility = View.GONE
|
||||
iv_animal_list.visibility = View.GONE
|
||||
}
|
||||
|
||||
// 有线路到达站点
|
||||
private fun haveLineAndArrivedStation() {
|
||||
group_not_select_line.visibility = View.GONE
|
||||
group_stationinfo.visibility = View.VISIBLE
|
||||
clg_distance_left_time.visibility = View.GONE
|
||||
tv_arrived_notice.visibility = View.VISIBLE
|
||||
iv_animal_list.visibility = View.VISIBLE
|
||||
val animationDrawable = iv_animal_list.drawable as AnimationDrawable
|
||||
animationDrawable.start()
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = PM2DrivingInfoFragment::class.java.simpleName
|
||||
}
|
||||
}
|
||||
@@ -1,128 +0,0 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui
|
||||
|
||||
import android.os.Bundle
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.map.overlay.core.Level
|
||||
import com.mogo.map.overlay.point.Point
|
||||
import com.mogo.map.MapDataWrapper
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import com.mogo.och.shuttle.weaknet.passenger.constant.M2Const.Companion.TYPE_MARKER_M2_LINE
|
||||
import com.mogo.och.shuttle.weaknet.passenger.presenter.PM2ADASPresenter
|
||||
import com.mogo.och.common.module.utils.OCHThreadPoolManager
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_hpmap_fragment.mHomeView
|
||||
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/4/12
|
||||
*/
|
||||
class PM2HPMapFragment :
|
||||
MvpFragment<PM2HPMapFragment?, PM2ADASPresenter?>() {
|
||||
/**
|
||||
* 改变自动驾驶状态
|
||||
*
|
||||
* @param status 2 - running 1 - enable 2 - disable
|
||||
*/
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.shuttle_p_m2_hpmap_fragment
|
||||
}
|
||||
|
||||
override fun getTagName(): String {
|
||||
return TAG
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
}
|
||||
|
||||
override fun initViews(savedInstanceState: Bundle?) {
|
||||
super.initViews(savedInstanceState)
|
||||
mHomeView.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mHomeView.onResume()
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mHomeView.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mHomeView.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mHomeView.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
mHomeView.onDestroy()
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun createPresenter(): PM2ADASPresenter {
|
||||
return PM2ADASPresenter(this)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val TAG = PM2HPMapFragment::class.java.simpleName
|
||||
}
|
||||
|
||||
fun setMapMaker(
|
||||
uuid: String,
|
||||
station: MutableList<Double>,
|
||||
) {
|
||||
//开启线程执行起终点marker设置
|
||||
val setMapMarkerRunnable = Runnable {
|
||||
d(
|
||||
"setMapMaker= " + Thread.currentThread().name,
|
||||
uuid + "=latitude=" + station[1] + ",longitude=" + station[0]
|
||||
)
|
||||
|
||||
val builder = Point.Options.Builder(
|
||||
TYPE_MARKER_M2_LINE,
|
||||
Level.MAP_MARKER
|
||||
)
|
||||
.setId(uuid)
|
||||
.anchor(0.5f, 0.5f)
|
||||
.set3DMode(true)
|
||||
.isUseGps(true)
|
||||
.controlAngle(true)
|
||||
.icon3DRes(R.raw.star_marker)
|
||||
.longitude(station[0])
|
||||
.latitude(station[1])
|
||||
MapDataWrapper.getCenterLineInfo(
|
||||
station[0], station[1], -1f
|
||||
) {
|
||||
// 有可能鹰眼map为空没有角度。判空使用后可能造成maker角度跟道路角度不一致 地图未初始化会返回空
|
||||
it?.let{
|
||||
builder.rotate(it.angle.toFloat())
|
||||
}
|
||||
val overlayManager = CallerMapUIServiceManager.getOverlayManager()
|
||||
overlayManager?.showOrUpdatePoint(builder.build())
|
||||
}
|
||||
|
||||
}
|
||||
OCHThreadPoolManager.getsInstance().execute(setMapMarkerRunnable)
|
||||
}
|
||||
|
||||
fun removeMapMaker(
|
||||
uuid: String,
|
||||
) {
|
||||
//开启线程移除起终点marker设置
|
||||
val removeMapMarkerRunnable = Runnable {
|
||||
d("RemoveMapMaker=" + Thread.currentThread().name, uuid)
|
||||
val overlayManager = CallerMapUIServiceManager.getOverlayManager()
|
||||
overlayManager?.removeAllPointsInOwner(TYPE_MARKER_M2_LINE)
|
||||
}
|
||||
OCHThreadPoolManager.getsInstance().execute(removeMapMarkerRunnable)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
package com.mogo.och.shuttle.weaknet.passenger.ui.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import com.mogo.eagle.core.function.api.devatools.IMoGoDevaToolsListener
|
||||
import com.mogo.eagle.core.function.hmi.ui.widget.BlueToothView
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.shuttle.weaknet.passenger.R
|
||||
import kotlinx.android.synthetic.main.shuttle_p_m2_view_blue_tooth.view.blueView
|
||||
|
||||
/**
|
||||
* 魔戒蓝牙控件
|
||||
* 放置于StatusBar右侧位置
|
||||
*/
|
||||
class M2BlueToothView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : BlueToothView(context, attrs, defStyleAttr),IMoGoDevaToolsListener {
|
||||
|
||||
init {
|
||||
LayoutInflater.from(context).inflate(R.layout.shuttle_p_m2_view_blue_tooth, this, true)
|
||||
}
|
||||
|
||||
override fun mofangStatus(status: Boolean) {
|
||||
ThreadUtils.runOnUiThread {
|
||||
if (status) {
|
||||
blueView.setImageResource(R.drawable.shuttle_p_m2_blue_tooth_close)
|
||||
} else {
|
||||
blueView.setImageResource(R.drawable.shuttle_p_m2_blue_tooth_open)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 5.7 KiB After Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
|
Before Width: | Height: | Size: 6.2 KiB After Width: | Height: | Size: 6.2 KiB |
|
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 900 B After Width: | Height: | Size: 900 B |
|
Before Width: | Height: | Size: 838 B After Width: | Height: | Size: 838 B |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 8.1 KiB After Width: | Height: | Size: 8.1 KiB |
|
Before Width: | Height: | Size: 8.5 KiB After Width: | Height: | Size: 8.5 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 765 B After Width: | Height: | Size: 765 B |
|
Before Width: | Height: | Size: 797 B After Width: | Height: | Size: 797 B |