[charter] m1司机端初始化

This commit is contained in:
wangmingjun
2023-02-22 21:16:11 +08:00
parent 4f63d38c94
commit ebc4e6a5dc
154 changed files with 3193 additions and 3 deletions

1
OCH/mogo-och-charter/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/build

View File

@@ -0,0 +1,48 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
}
android {
compileSdkVersion 31
defaultConfig {
minSdkVersion 23
targetSdkVersion 31
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation rootProject.ext.dependencies.kotlinstdlibjdk7
implementation rootProject.ext.dependencies.androidxappcompat
implementation rootProject.ext.dependencies.arouter
annotationProcessor rootProject.ext.dependencies.aroutercompiler
implementation rootProject.ext.dependencies.androidxconstraintlayout
implementation rootProject.ext.dependencies.amapnavi3dmap
implementation rootProject.ext.dependencies.rxjava
implementation rootProject.ext.dependencies.rxandroid
implementation rootProject.ext.dependencies.androidxrecyclerview
compileOnly rootProject.ext.dependencies.recyclerviewadapterhelper
implementation project(":OCH:mogo-och-common-module")
compileOnly project(":libraries:mogo-map")
}

View File

21
OCH/mogo-och-charter/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -0,0 +1,68 @@
package com.magic.mogo.och.charter
import android.content.Context
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.magic.mogo.och.charter.constant.CharterConst
import com.magic.mogo.och.charter.fragment.DriverM1Fragment
/**
* @author: wangmingjun
* @date: 2023/2/22
*/
@Route(path = CharterConst.PATH)
class CharterProvider: ICharterOCH{
private var mActivity: FragmentActivity? = null
private var mContainerId = 0
private var driverM1Fragment: Fragment? = null
override fun createCoverage(activity: FragmentActivity?, containerId: Int) {}
override fun createCoverage(activity: FragmentActivity?, containerId: Int?): Fragment? {
mActivity = activity
mContainerId = containerId!!
showFragment()
return null
}
private fun showFragment() {
val supportFragmentManager = mActivity?.supportFragmentManager
if (driverM1Fragment == null) {
d(TAG, "准备add fragment======")
val fragmentByTag = supportFragmentManager?.findFragmentByTag(DriverM1Fragment.TAG)
driverM1Fragment = if (fragmentByTag is DriverM1Fragment) {
fragmentByTag
} else {
DriverM1Fragment()
}
if (!driverM1Fragment!!.isAdded) {
supportFragmentManager?.beginTransaction()
?.add(mContainerId, driverM1Fragment!!, DriverM1Fragment.TAG)?.commitAllowingStateLoss()
}
return
}
d(TAG, "准备show fragment")
supportFragmentManager?.beginTransaction()?.show(driverM1Fragment!!)?.commitAllowingStateLoss()
}
override fun init(context: Context?) {
}
override val functionName: String
get() = "och-charter-driver-m1"
override fun onDestroy() {
// 若不调用finish, 设置中打开关闭UITouch,会造成och fragment 重叠
mActivity?.finish()
}
companion object {
private val TAG = CharterProvider::class.java.simpleName
}
}

View File

@@ -0,0 +1,17 @@
package com.magic.mogo.och.charter.callback;
import com.mogo.eagle.core.data.map.MogoLocation;
/**
* Created on 2021/9/10
*
* Model->Presenter回调状态控制器监听accOn、adas ui show、voice ui show、push ui show、v2x ui show等等
*/
public interface IDriverM1ControllerStatusCallback {
// 是否vr map模式
void onVRModeChanged(boolean isVRMode);
// 自车定位
void onCarLocationChanged(MogoLocation location);
//开始开启自动驾驶
void startOpenAutopilot();
}

View File

@@ -0,0 +1,50 @@
package com.magic.mogo.och.charter.fragment
import android.view.View
import com.magic.mogo.och.charter.presenter.DriverM1Presenter
import com.charter.driverm1.view.SlidePanelView
import com.magic.mogo.och.charter.base.CharterBaseFragment
/**
* @author: wangmingjun
* @date: 2023/2/22
*/
class DriverM1Fragment : CharterBaseFragment<DriverM1Fragment?, DriverM1Presenter?>(),
SlidePanelView.OnSlidePanelMoveToEndListener, View.OnClickListener {
companion object{
val TAG = DriverM1Fragment::class.java.name
}
override fun moveToEnd() {
TODO("Not yet implemented")
}
override fun onArriveStation() {
TODO("Not yet implemented")
}
override fun getStationPanelViewId(): Int {
TODO("Not yet implemented")
}
override fun restartAutopilot() {
TODO("Not yet implemented")
}
override fun debugAutoPilotStatus(status: Int) {
TODO("Not yet implemented")
}
override fun getTagName(): String {
TODO("Not yet implemented")
}
override fun createPresenter(): DriverM1Presenter {
TODO("Not yet implemented")
}
override fun onClick(p0: View?) {
TODO("Not yet implemented")
}
}

View File

@@ -0,0 +1,550 @@
package com.magic.mogo.och.charter.model
import android.content.Context
import android.os.Handler
import com.alibaba.android.arouter.launcher.ARouter
import com.elegant.network.utils.GsonUtil
import com.magic.mogo.och.charter.callback.IADASStatusCallback
import com.magic.mogo.och.charter.callback.IDriverM1ControllerStatusCallback
import com.magic.mogo.och.charter.constant.CharterConst
import com.mogo.aicloud.services.socket.IMogoOnMessageListener
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.module.status.IMogoStatusChangedListener
import com.mogo.commons.module.status.MogoStatusManager
import com.mogo.commons.module.status.StatusDescriptor
import com.mogo.eagle.core.data.BaseData
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters.AutoPilotLine
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters.AutoPilotLonLat
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.map.MogoLocation
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener
import com.mogo.eagle.core.function.api.autopilot.IMoGoPlanningRottingListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.setIPCDemoMode
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.setIgnoreConditionDraw
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager.startAutoPilot
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo
import com.mogo.eagle.core.function.call.autopilot.CallerChassisLocationGCJ02ListenerManager
import com.mogo.eagle.core.function.call.autopilot.CallerPlanningRottingListenerManager
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.e
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager
import com.mogo.och.common.module.biz.common.socketmessage.OCHSocketMessageManager.releaseSocketMessageListener
import com.mogo.och.common.module.biz.constant.OchCommonConst
import com.mogo.och.common.module.biz.provider.LoginService
import com.mogo.och.common.module.callback.OchAdasStartFailureCallback
import com.mogo.och.common.module.manager.AbnormalFactorsLoopManager.startLoopAbnormalFactors
import com.mogo.och.common.module.manager.AbnormalFactorsLoopManager.stopLoopAbnormalFactors
import com.mogo.och.common.module.manager.OCHAdasAbilityManager
import com.mogo.och.common.module.utils.*
import io.reactivex.exceptions.UndeliverableException
import io.reactivex.functions.Consumer
import io.reactivex.plugins.RxJavaPlugins
import java.io.IOException
/**
* @author: wangmingjun
* @date: 2023/2/22
*/
class DriverM1Model {
private val TAG: String = DriverM1Model::class.java.getSimpleName()
private var currentLineId = -1
private var currentTaskId = -1
private var backgroundCurrentStationIndex = 0 //A->B 此处值是A站点索引
@Volatile
private var sInstance: DriverM1Model? = null
var mLongitude = 0.0
var mLatitude = 0.0
private var mContext: Context? = null
/**
* 用来表示是否正在开往下一站
*/
private var isGoingToNextStation = false
// 运营类型
private val VEHICLE_TYPE = 10
private val MSG_QUERY_BUS_STATION = 1001
private val QUERY_BUS_STATION_DELAY: Long = 5000
// private var slidePanelHideCallback: ISlidePannelHideCallback? = null
private var mControllerStatusCallback //Model->PresenterVR mode等
: IDriverM1ControllerStatusCallback? = null
private var mADASStatusCallback: IADASStatusCallback? = null
@Volatile
private var isArrivedStation = false
//0: 代表没有启动过 1代表是启动第一次当>=1 代表是重试 每次到站/路线结束清空置为0
@Volatile
private var firstStartAutopilot = 0
private var loginService: LoginService? = null
private val handler = Handler(Handler.Callback { msg ->
if (msg.what == MSG_QUERY_BUS_STATION) {
return@Callback true
}
false
})
fun getInstance(): DriverM1Model? {
if (sInstance == null) {
synchronized(DriverM1Model::class.java) {
if (sInstance == null) {
sInstance = DriverM1Model()
}
}
}
return sInstance
}
private fun OrderModel() {}
fun init() {
mContext = AbsMogoApplication.getApp()
loginService =
ARouter.getInstance().build(OchCommonConst.LOGINSERVICE).navigation() as LoginService
// 定位监听
CallerChassisLocationGCJ02ListenerManager.addListener(TAG, mMapLocationListener)
MogoStatusManager.getInstance().registerStatusChangedListener(
TAG,
StatusDescriptor.VR_MODE,
mMogoStatusChangedListener
)
//自动驾驶路线规划接口
CallerPlanningRottingListenerManager.addListener(TAG, moGoAutopilotPlanningListener)
//开启自驾后 异常信息返回
OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(mAdasStartFailureListener)
// registerSocketMessageListener( //监听运营消息
// OCHSocketMessageManager.msgMonitorType,
// mMogoOnMessageListener
// )
// registerSocketMessageListener<WriteOffPassenger>( //监听核销乘客
// OCHSocketMessageManager.msgWriteOffPassengerType,
// mWriteOffPassengeOnMessageListener
// )
startLoopAbnormalFactors(mContext!!)
//2022.1.28
// 调用Disposable.dispose() 时候会出现InterruptedException 导致出现崩溃
// The exception could not be delivered to the consumer because it has already canceled/disposed
// the flow or the excTeption has nowhere to go to begin with
RxJavaPlugins.setErrorHandler(object : Consumer<Throwable?>{
override fun accept(e: Throwable?) {
var e = e
if (e is UndeliverableException) {
e = e.cause!!
d(SceneConstant.M_BUS + TAG, "UndeliverableException")
}
if (e is IOException) { //
// fine, irrelevant network problem or API that throws on cancellation
d(SceneConstant.M_BUS + TAG, "IOException")
return
}
if (e is InterruptedException) {
// fine, some blocking code was interrupted by a dispose call
d(SceneConstant.M_BUS + TAG, "InterruptedException")
return
}
if (e is NullPointerException || e is IllegalArgumentException) {
// that's likely a bug in the application
d(SceneConstant.M_BUS + TAG, "NullPointerException or IllegalArgumentException")
Thread.currentThread().uncaughtExceptionHandler.uncaughtException(
Thread.currentThread(),
e
)
return
}
if (e is IllegalStateException) {
// that's a bug in RxJava or in a custom operator
d(SceneConstant.M_BUS + TAG, "IllegalStateException")
Thread.currentThread().uncaughtExceptionHandler.uncaughtException(
Thread.currentThread(),
e
)
return
}
d(SceneConstant.M_BUS + TAG, "Undeliverable exception")
}
})
}
// private val mMogoOnMessageListener: IMogoOnMessageListener<OCHOperationalMessage> =
// object : IMogoOnMessageListener<OCHOperationalMessage?> {
// override fun target(): Class<OCHOperationalMessage> {
// return OCHOperationalMessage::class.java
// }
//
// fun onMsgReceived(obj: OCHOperationalMessage) {
// if (obj == null) {
// d(SceneConstant.M_BUS + TAG, "onMsgReceived = null")
// return
// }
// i(SceneConstant.M_BUS + TAG, "onMsgReceived = " + obj.message)
// pushAppOperationalMsgBox(
// obj.pushTimeStamp,
// obj.message
// )
// }
// }
// private val mWriteOffPassengeOnMessageListener: IMogoOnMessageListener<WriteOffPassenger> =
// object : IMogoOnMessageListener<WriteOffPassenger?> {
// override fun target(): Class<WriteOffPassenger> {
// return WriteOffPassenger::class.java
// }
//
// override fun onMsgReceived(passenger: WriteOffPassenger) {
// //进行播报
// i(SceneConstant.M_BUS + TAG, "passenger = " + GsonUtil.jsonFromObject(passenger))
// if (passenger != null && passenger.passengerSize == 0) return
// if (mPassengerCallback != null) {
// mPassengerCallback.playPassenger(passenger)
// }
// }
// }
fun setAdasStatusCallback(callback: IADASStatusCallback?) {
mADASStatusCallback = callback
}
// fun setSlidePanelHideCallback(callback: ISlidePannelHideCallback?) {
// slidePanelHideCallback = callback
// }
fun setControllerStatusCallback(callback: IDriverM1ControllerStatusCallback?) {
mControllerStatusCallback = callback
}
private val moGoAutopilotPlanningListener: IMoGoPlanningRottingListener =
object : IMoGoPlanningRottingListener {
override fun onAutopilotRotting(routeList: GlobalPathResp?) {
if (null != routeList && routeList.getWayPointsList().size() > 0) {
// points.clear()
// points.addAll(
// coordinateConverterWgsToGcjList(
// mContext,
// routeList.getWayPointsList()
// )!!
// )
// updateOrderRoute()
}
}
}
fun release() {
// startOrStopOrderLoop(false)
MogoStatusManager.getInstance().unregisterStatusChangedListener(
TAG,
StatusDescriptor.VR_MODE,
mMogoStatusChangedListener
)
// 注销定位监听
CallerChassisLocationGCJ02ListenerManager.removeListener(TAG)
//自动驾驶路线规划接口
CallerPlanningRottingListenerManager.removeListener(moGoAutopilotPlanningListener)
loginService = null
OCHAdasAbilityManager.getInstance().setAdasStartFailureCallback(null)
releaseSocketMessageListener(
OCHSocketMessageManager.msgMonitorType
)
releaseSocketMessageListener(
OCHSocketMessageManager.msgWriteOffPassengerType
)
stopLoopAbnormalFactors()
}
private fun readResolve(): Any? {
// 阻止反序列化,必须实现 Serializable 接口
return sInstance
}
private val mMogoStatusChangedListener: IMogoStatusChangedListener =
IMogoStatusChangedListener { descriptor, isTrue ->
// VR mode变更回调
if (StatusDescriptor.VR_MODE == descriptor) {
mControllerStatusCallback?.onVRModeChanged(isTrue)
}
}
private val mAdasStartFailureListener: OchAdasStartFailureCallback =
object : OchAdasStartFailureCallback {
override fun onStartAutopilotFailure(
startFailedCode: String,
startFailedMessage: String
) {
// BusAnalyticsManager.getInstance()
// .triggerStartAutopilotFailureEventByAdas(startFailedCode, startFailedMessage)
// if (mADASStatusCallback != null && !FunctionBuildConfig.isDemoMode) {
// e(
// SceneConstant.M_BUS + TAG,
// "mAdasStartFailureListener = $startFailedMessage"
// )
// mADASStatusCallback.onStartAdasFailure()
// }
}
}
// 自车定位
private val mMapLocationListener: IMoGoChassisLocationGCJ02Listener =
object : IMoGoChassisLocationGCJ02Listener {
override fun onChassisLocationGCJ02(gnssInfo: MogoLocation?) {
if (null == gnssInfo) return
mLongitude = gnssInfo.longitude
mLatitude = gnssInfo.latitude
// if (mControllerStatusCallback != null) {
// mControllerStatusCallback.onCarLocationChanged(gnssInfo)
// }
//是否到站的围栏判断 离站状态并且自动驾驶还未触发到站
if (isGoingToNextStation && !isArrivedStation) {
judgeArrivedStation(gnssInfo)
}
}
}
//根据围栏判断,是否到达站点
private fun judgeArrivedStation(location: MogoLocation) {
// if (backgroundCurrentStationIndex + 1 > stationList!!.size - 1) {
// e(SceneConstant.M_BUS + TAG, "到站数组越界")
// return
// }
// val upcomingStation: BusStationBean = stationList[backgroundCurrentStationIndex + 1]
// val startLon: Double = upcomingStation.getGcjLon()
// val startLat: Double = upcomingStation.getGcjLat()
// val distance = CoordinateUtils.calculateLineDistance(
// startLon, startLat,
// location.longitude, location.latitude
// ).toDouble()
// if (distance <= CharterConst.ARRIVE_AT_END_STATION_DISTANCE) {
// d(
// SceneConstant.M_BUS + TAG, "行程日志-judgeArrivedStation() distance = " + distance
// + " to " + upcomingStation.getName()
// )
// onArriveAt(null) //无自动驾驶到站信息传null
// return
// }
}
private fun onStartAutopilot(leaveIndex: Int) {
//开启自动驾驶 2.10.0: 如果自动驾驶状态下开启, 非自动驾驶状态下不开启,需手动点击自动驾驶按钮开启
isGoingToNextStation = true
if (getAutoPilotStatusInfo().state
== IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
) {
startAutopilot(false, leaveIndex)
} else {
firstStartAutopilot = 0
}
}
/**
* 开启自动驾驶
*
* @param isRestart
*/
private fun startAutopilot(isRestart: Boolean, leaveIndex: Int) {
if (!FunctionBuildConfig.isDemoMode && !OCHAdasAbilityManager.getInstance().autopilotAbilityStatus) {
ToastUtils.showLong(
OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason +
", 请稍候重试"
)
triggerUnableStartAPReasonEvent()
return
}
firstStartAutopilot++
triggerStartServiceEvent(isRestart, false)
val parameters = initAutopilotControlParameters(leaveIndex)
if (null == parameters) {
e(SceneConstant.M_BUS + TAG, "行程日志-AutopilotControlParameters is empty.")
return
}
startAutoPilot(parameters)
d(
SceneConstant.M_BUS + TAG, "行程日志-开启自动驾驶====" + GsonUtil.jsonFromObject(parameters)
+ " startLatLon=" + parameters.startName + "endLatLon=" + parameters.endName +
"isRestart = " + isRestart
)
if (mControllerStatusCallback != null) {
mControllerStatusCallback.startOpenAutopilot()
}
//车站10s后播报
// private fun leaveTTSTips(nextStation: String) {
// showNotice(
// String.format(
// mContext
// .getString(R.string.bus_leave_station_tip),
// nextStation
// ), CharterConst.Companion.DELAY_10S
// )
// }
/**
* 关闭美化模式
*/
fun closeBeautificationMode() {
if (FunctionBuildConfig.isDemoMode) { //收车结束美化
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData =
false //是否强制绘制引导线
setIgnoreConditionDraw(false) // 同步给乘客屏
setIPCDemoMode(false) //是否自动启动自驾
d(SceneConstant.M_BUS + TAG, "美化模式-ignore置为false")
}
}
fun clearStartAutopilotTag() {
firstStartAutopilot = 0
}
fun startBeautificationMode() {
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true
setIgnoreConditionDraw(true)
setIPCDemoMode(true)
}
/**
* 延时查询站点信心
*/
fun queryBusStationDelay() {
handler.sendEmptyMessageDelayed(MSG_QUERY_BUS_STATION, QUERY_BUS_STATION_DELAY)
}
/**
* 在踩刹车、控制方向盘等操作后,会停止自动驾驶,重启自动驾驶的话相当于重新设置自动驾驶目的地
*/
fun restartAutopilot() {
d(SceneConstant.M_BUS + TAG, "行程日志-重启自动驾驶===$isGoingToNextStation")
//只去启动自动驾驶,不再去上报离站
startAutopilot(firstStartAutopilot >= 1, -1)
}
fun isRestartAutopilot(): Boolean {
return firstStartAutopilot > 1
}
fun isGoingToNextStation(): Boolean {
return isGoingToNextStation
}
fun sendWriteOffNumToClient(msg: String?) {}
// fun startOrStopOrderLoop(start: Boolean) {
// d(SceneConstant.M_BUS + TAG, "startOrStopOrderLoop() $start")
// if (start) {
// BusModelLoopManager.getInstance().startHeartbeatLoop()
// } else {
// BusModelLoopManager.getInstance().stopHeartbeatLoop()
// }
// }
// 登出
fun logout() {
loginService!!.loginOut(mLatitude, mLongitude)
}
fun triggerStartServiceEvent(isRestart: Boolean, send: Boolean) {
// if (stationList == null || backgroundCurrentStationIndex >= stationList.size - 1) {
// return
// }
// val currentStation: BusStationBean = stationList[backgroundCurrentStationIndex]
// val nextStation: BusStationBean = stationList[backgroundCurrentStationIndex + 1]
// BusAnalyticsManager.getInstance().triggerStartAutopilotEvent(
// isRestart, send,
// currentStation.getName(), nextStation.getName(), currentLineId
// )
}
fun triggerUnableStartAPReasonEvent() {
// if (stationList == null || backgroundCurrentStationIndex >= stationList.size - 1) {
// return
// }
// val currentStation: BusStationBean = stationList[backgroundCurrentStationIndex]
// val nextStation: BusStationBean = stationList[backgroundCurrentStationIndex + 1]
// BusAnalyticsManager.getInstance().triggerUnableStartAPReasonEvent(
// currentStation.getName(), nextStation.getName(), currentLineId,
// OCHAdasAbilityManager.getInstance().autopilotUnAbilityReason
// )
}
fun getCurrentStationIndex(): Int {
return backgroundCurrentStationIndex
}
/**
* 将业务订单信息保存,鹰眼可取用
*/
fun updateAutopilotControlParameters() {
// TODO: 业务信息保存
val parameters = initAutopilotControlParameters(-1)
if (null == parameters) {
e(SceneConstant.M_BUS + TAG, "AutopilotControlParameters is empty.")
return
}
d(SceneConstant.M_BUS + TAG, "AutopilotControlParameters is update.")
updateAutopilotControlParameters(parameters)
}
fun clearAutopilotControlParameters() {
// d(SceneConstant.M_BUS + TAG, "AutopilotControlParameters is clear.")
// updateAutopilotControlParameters(null)
}
fun initAutopilotControlParameters(leaveIndex: Int): AutopilotControlParameters? {
// var currentStation: BusStationBean? = null
// var nextStation: BusStationBean? = null
// if (leaveIndex < 0) {
// if (backgroundCurrentStationIndex + 1 > stationList!!.size - 1 || !isGoingToNextStation) {
// e(SceneConstant.M_BUS + TAG, "行程日志-mismatch condition1.")
// return null
// }
// currentStation = stationList[backgroundCurrentStationIndex]
// nextStation = stationList[backgroundCurrentStationIndex + 1]
// } else {
// if (leaveIndex + 1 > stationList!!.size - 1 || !isGoingToNextStation) {
// e(SceneConstant.M_BUS + TAG, "行程日志-mismatch condition2.")
// return null
// }
// currentStation = stationList[leaveIndex]
// nextStation = stationList[leaveIndex + 1]
// }
var parameters = AutopilotControlParameters()
// parameters.routeID = busRoutesResult.getLineId()
// parameters.routeName = busRoutesResult.getName()
// parameters.startName = PinYinUtil.getPinYinHeadChar(currentStation.getName())
// parameters.endName = PinYinUtil.getPinYinHeadChar(nextStation.getName())
// parameters.startLatLon = AutoPilotLonLat(currentStation.getLat(), currentStation.getLon())
// parameters.endLatLon = AutoPilotLonLat(nextStation.getLat(), nextStation.getLon())
// parameters.vehicleType = VEHICLE_TYPE
// if (parameters.autoPilotLine == null) {
// parameters.autoPilotLine = AutoPilotLine(
// busRoutesResult.getLineId(),
// busRoutesResult.csvFileUrl, busRoutesResult.csvFileMd5,
// busRoutesResult.txtFileUrl, busRoutesResult.txtFileMd5,
// busRoutesResult.contrailSaveTime, busRoutesResult.carModel,
// busRoutesResult.csvFileUrlDPQP, busRoutesResult.csvFileMd5DPQP,
// busRoutesResult.txtFileUrlDPQP, busRoutesResult.txtFileMd5DPQP,
// busRoutesResult.contrailSaveTimeDPQP
// )
// }
return parameters
}
}
}

View File

@@ -0,0 +1,13 @@
package com.magic.mogo.och.charter.net
import com.mogo.eagle.core.data.BaseData
import io.reactivex.Observable
import retrofit2.http.*
/**
* @author: wangmingjun
* @date: 2023/2/22
*/
interface IDriverM1Service {
}

View File

@@ -0,0 +1,33 @@
package com.magic.mogo.och.charter.presenter
import com.magic.mogo.och.charter.fragment.DriverM1Fragment
import com.mogo.commons.mvp.Presenter
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.och.common.module.biz.bean.DriverStatusQueryRespBean
import com.mogo.och.common.module.biz.callback.ILoginCallback
import com.mogo.och.common.module.biz.constant.LoginStatusManager.isLogin
/**
* @author: wangmingjun
* @date: 2023/2/22
*/
class DriverM1Presenter(view: DriverM1Fragment?) :
Presenter<DriverM1Fragment?>(view),ILoginCallback{
private val TAG = DriverM1Presenter::class.java.name
override fun loginSuccess(data: DriverStatusQueryRespBean?) {
d(SceneConstant.M_BUS + TAG, " loginStatus =" + isLogin())
if (isLogin()) {
// todo 已经登陆
} else {
// todo 未登陆
}
}
override fun loginFail(isLogin: Boolean) {
//todo 登陆失败
}
}

View File

@@ -0,0 +1,278 @@
package com.charter.driverm1.view
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.animation.DecelerateInterpolator
import com.mogo.commons.AbsMogoApplication
import me.jessyan.autosize.AutoSizeConfig
import me.jessyan.autosize.utils.AutoSizeUtils
/**
* @author: wangmingjun
* @date: 2023/2/22
*/
class SlidePanelView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) :
View(context, attrs, defStyleAttr) {
private val bgPaint = Paint(Paint.ANTI_ALIAS_FLAG)
private val blockPaint = Paint(Paint.ANTI_ALIAS_FLAG)
private val textPaint = Paint(Paint.ANTI_ALIAS_FLAG)
private var textMarginLeft = NORMAL_TEXT_MARGIN_LEFT
private var textMarginRight = NORMAL_TEXT_MARGIN_RIGHT
private var moveToEndListener: OnSlidePanelMoveToEndListener? = null
private var blockWidth = 0
private var blockOffset = 0
private var lastX = 0f
private var isToEnd = false
private var bgRectF: RectF? = null
private var bmBlock: Bitmap? = null
private val gradientMatrix = Matrix()
private var matrixTranslate = 0f
private val textRect = Rect()
private var textGradient: LinearGradient? = null
private var matrixAnim: ObjectAnimator? = null
private var blockText = STRING_SLIDE_TO_RIGHT
private val blockTextMetrics = Paint.FontMetrics()
fun setOnSlidePanelMoveToEndListener(moveToEndListener: OnSlidePanelMoveToEndListener?) {
this.moveToEndListener = moveToEndListener
}
private fun setBlockOffset(blockOffset: Int) {
this.blockOffset = blockOffset
invalidate()
}
private fun setMatrixTranslate(matrixTranslate: Float) {
this.matrixTranslate = matrixTranslate
invalidate()
}
fun setText(text: String) {
blockText = text
requestLayout()
invalidate()
}
private fun init() {
bgRectF = RectF(0, 0, 0, 0)
bgPaint.color = Color.parseColor("#CC0F1325")
bgPaint.style = Paint.Style.FILL
textPaint.style = Paint.Style.FILL
textPaint.textSize = textSize.toFloat()
textPaint.textAlign = Paint.Align.LEFT
textGradient = LinearGradient(
-GRADIENT_OFFSET,
0,
0,
0,
intArrayOf(0x33ffffff, -0x1, 0x33ffffff),
null,
Shader.TileMode.CLAMP
)
textGradient!!.setLocalMatrix(gradientMatrix)
textPaint.shader = textGradient
textPaint.getFontMetrics(blockTextMetrics)
val size = AutoSizeUtils.dp2px(context, 120f)
val opts = BitmapFactory.Options()
opts.inDensity = AutoSizeConfig.getInstance().initDensity.toInt()
bmBlock = BitmapFactory.decodeResource(resources, R.drawable.bus_base_slide_block, opts)
bmBlock = Bitmap.createScaledBitmap(bmBlock, size, size, true)
blockWidth = bmBlock.getWidth()
}
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
var widthMeasureSpec = widthMeasureSpec
var heightMeasureSpec = heightMeasureSpec
val widthMode = MeasureSpec.getMode(widthMeasureSpec)
val heightMode = MeasureSpec.getMode(heightMeasureSpec)
val widthSize: Int
val heightSize: Int
if (blockText.length < 5) {
textMarginLeft = SHORT_TEXT_MARGIN_LEFT
textMarginRight = SHORT_TEXT_MARGIN_RIGHT
} else {
textMarginLeft = NORMAL_TEXT_MARGIN_LEFT
textMarginRight = NORMAL_TEXT_MARGIN_RIGHT
}
if (widthMode == MeasureSpec.AT_MOST) {
// 宽度根据图片大小,字符串长度,各种间隔确定
// 高度根据图片大小和上下间隔确定
textPaint.getTextBounds(blockText, 0, blockText.length, textRect)
widthSize =
BLOCK_START_X * 2 + bmBlock!!.width + textMarginLeft + textMarginRight + textRect.width()
heightSize = BLOCK_START_Y * 2 + bmBlock!!.height
widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode)
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode)
}
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
}
private var textOffset = 0f
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
super.onSizeChanged(w, h, oldw, oldh)
if (bgRectF != null) {
bgRectF!!.left = 0f
bgRectF!!.top = 0f
bgRectF!!.right = w.toFloat()
bgRectF!!.bottom = h.toFloat()
}
if (matrixAnim != null) {
matrixAnim!!.cancel()
}
textOffset = (height - blockTextMetrics.ascent - blockTextMetrics.descent) / 2
matrixAnim =
ObjectAnimator.ofFloat(this, "matrixTranslate", 0f, (w + GRADIENT_OFFSET).toFloat())
.setDuration(2000)
matrixAnim!!.repeatCount = ValueAnimator.INFINITE
matrixAnim!!.start()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
if (matrixAnim != null) {
matrixAnim!!.start()
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
if (matrixAnim != null) {
matrixAnim!!.cancel()
}
}
override fun onTouchEvent(event: MotionEvent): Boolean {
val x = event.x
val y = event.y
when (event.action) {
MotionEvent.ACTION_DOWN -> if (x > BLOCK_START_X + blockOffset && x < blockWidth + BLOCK_START_X + blockOffset && y > BLOCK_START_Y && y < height - BLOCK_START_Y) {
isToEnd = false
lastX = x
}
MotionEvent.ACTION_MOVE -> if (lastX != 0f) {
blockOffset = (x - lastX).toInt()
if (blockOffset < 0) {
blockOffset = 0
}
if (blockOffset + BLOCK_START_X + blockWidth > width) {
// 超出右边界
blockOffset = width - BLOCK_START_X - blockWidth
if (!isToEnd) {
isToEnd = true
if (moveToEndListener != null) {
moveToEndListener!!.moveToEnd()
}
startBlockBackAnim()
}
}
invalidate()
}
MotionEvent.ACTION_UP -> // 执行滑块回归动画
if (!isToEnd) {
startBlockBackAnim()
}
else -> {}
}
return true
}
private fun startBlockBackAnim() {
val blockBackanimator = ObjectAnimator.ofInt(this, "blockOffset", blockOffset, 0)
blockBackanimator.interpolator = DecelerateInterpolator()
blockBackanimator.duration = (1000 * blockOffset / width).toLong()
blockBackanimator.start()
lastX = 0f
}
override fun onDraw(canvas: Canvas) {
super.onDraw(canvas)
// 画背景
canvas.drawRoundRect(bgRectF!!, height.toFloat() / 2, height.toFloat() / 2, bgPaint)
// 画文字
gradientMatrix.setTranslate(matrixTranslate, 0f)
textGradient!!.setLocalMatrix(gradientMatrix)
canvas.save()
canvas.drawText(
blockText,
(blockWidth + BLOCK_START_X + textMarginLeft).toFloat(),
textOffset,
textPaint
)
canvas.restore()
// 画滑块
canvas.drawBitmap(
bmBlock!!,
(BLOCK_START_X + blockOffset).toFloat(),
BLOCK_START_Y.toFloat(),
blockPaint
)
}
interface OnSlidePanelMoveToEndListener {
/**
* 滑块滑到了末尾
*/
fun moveToEnd()
}
companion object {
private const val TAG = "SlidePanelView"
private var textSize = 40
private var BLOCK_START_X = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(), 15f)
private var BLOCK_START_Y = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(), 15f)
private var NORMAL_TEXT_MARGIN_LEFT = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(), 40f)
private var NORMAL_TEXT_MARGIN_RIGHT = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(), 60f)
private var SHORT_TEXT_MARGIN_LEFT = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(), 60f)
private var SHORT_TEXT_MARGIN_RIGHT = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(), 70f)
private const val STRING_SLIDE_TO_RIGHT = "向右滑动"
private const val GRADIENT_OFFSET = 200
}
init {
val mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.SlidePanelView)
textSize =
mTypedArray.getDimension(R.styleable.SlidePanelView_textSize, textSize.toFloat())
.toInt()
BLOCK_START_X =
mTypedArray.getDimension(
R.styleable.SlidePanelView_BLOCK_START_X,
BLOCK_START_X.toFloat()
)
.toInt()
BLOCK_START_Y =
mTypedArray.getDimension(
R.styleable.SlidePanelView_BLOCK_START_Y,
BLOCK_START_Y.toFloat()
)
.toInt()
NORMAL_TEXT_MARGIN_LEFT = mTypedArray.getDimension(
R.styleable.SlidePanelView_NORMAL_TEXT_MARGIN_LEFT,
NORMAL_TEXT_MARGIN_LEFT.toFloat()
)
.toInt()
NORMAL_TEXT_MARGIN_RIGHT = mTypedArray.getDimension(
R.styleable.SlidePanelView_NORMAL_TEXT_MARGIN_RIGHT,
NORMAL_TEXT_MARGIN_RIGHT.toFloat()
)
.toInt()
SHORT_TEXT_MARGIN_LEFT = mTypedArray.getDimension(
R.styleable.SlidePanelView_SHORT_TEXT_MARGIN_LEFT,
SHORT_TEXT_MARGIN_LEFT.toFloat()
)
.toInt()
SHORT_TEXT_MARGIN_RIGHT = mTypedArray.getDimension(
R.styleable.SlidePanelView_SHORT_TEXT_MARGIN_RIGHT,
SHORT_TEXT_MARGIN_RIGHT.toFloat()
)
.toInt()
init()
}
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.magic.mogo.och.charter">
</manifest>

View File

@@ -0,0 +1,24 @@
package com.magic.mogo.och.charter;
import androidx.annotation.IdRes;
import androidx.fragment.app.FragmentActivity;
import com.mogo.eagle.core.function.api.base.IMoGoFunctionProvider;
public
/**
* @author congtaowang
* @since 2021/1/15
*
* 网约车抽象接口
*/
interface ICharterOCH extends IMoGoFunctionProvider {
/**
* 初始化网约车容器
*
* @param activity
* @param containerId 容器ID
*/
void createCoverage(FragmentActivity activity, @IdRes int containerId);
}

View File

@@ -0,0 +1,508 @@
package com.magic.mogo.och.charter.base
import android.animation.ObjectAnimator
import android.annotation.SuppressLint
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.LinearInterpolator
import android.widget.*
import androidx.constraintlayout.widget.Group
import com.magic.mogo.och.charter.R
import com.magic.mogo.och.charter.constant.CharterConst
import com.mogo.commons.mvp.IView
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.mvp.Presenter
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotRecordListener
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getAutoPilotStatusInfo
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager.initAiCollect
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager.initBadCase
import com.mogo.eagle.core.function.call.hmi.CallerHmiManager.showToolsView
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMapUIController
import com.mogo.eagle.core.function.call.map.CallerVisualAngleManager.updateLongSightLevel
import com.mogo.eagle.core.function.hmi.ui.msgbox.DriverMsgBoxBubbleView
import com.mogo.eagle.core.function.hmi.ui.msgbox.DriverMsgBoxButtonView
import com.mogo.eagle.core.function.hmi.ui.msgbox.DriverMsgBoxButtonView.ClickListener
import com.mogo.eagle.core.function.hmi.ui.msgbox.DriverMsgBoxListView
import com.mogo.eagle.core.function.hmi.ui.widget.TrafficDataView
import com.mogo.eagle.core.function.smp.view.SmallMapView
import com.mogo.eagle.core.function.view.MapBizView
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.map.listener.IMogoMapListener
import com.mogo.map.listener.MogoMapListenerHandler.Companion.mogoMapListenerHandler
import com.mogo.map.uicontroller.VisualAngleMode
import com.mogo.och.common.module.utils.SoundPoolHelper
import org.greenrobot.eventbus.EventBus
import java.util.*
/**
* @author: wangmingjun
* @date: 2023/2/22
*
* 部分鹰眼相关放在了此处处理
*
* @author tongchenfei
*/
abstract class CharterBaseFragment<V : IView?, P : Presenter<V>?>() :
MvpFragment<V, P>(), IMogoMapListener, IMoGoAutopilotRecordListener {
private val TAG = "BaseBusTabFragment"
private var ctvAutopilotStatus: RelativeLayout? = null
private var ctvAutopilotStatusIv: ImageView? = null
private var ctvAutopilotStatusTv: TextView? = null
protected var mSettingBtn: RelativeLayout? = null
protected var mBadcaseBtn: RelativeLayout? = null
protected var mAICollectBtn: RelativeLayout? = null
private var flStationPanelContainer: FrameLayout? = null
private var mapBizView: MapBizView? = null
private var groupTestPanel: Group? = null
private var mTrafficDataView: TrafficDataView? = null
// private BusTrafficLightView mTrafficLightView;
// private BusTrafficLightView mTrafficLightView;
//远景和中景的切换
private var mSwitchMapModeImage: ImageView? = null
private var mSwitchMapModeLayout: LinearLayout? = null
protected var smallMapView: SmallMapView? = null
//消息盒子
private var viewDriverMsgBoxButton: DriverMsgBoxButtonView? = null
private var viewDriverMsgBoxList: DriverMsgBoxListView? = null
private var viewDriverMsgBoxBubble: DriverMsgBoxBubbleView? = null
private var autopilotLoadingAnimator: ObjectAnimator? = null
var isAnimateRunning = false
override fun getLayoutId(): Int {
return R.layout.charter_base_fragment
}
override fun initViews() {
mapBizView = findViewById(R.id.mapBizView)
groupTestPanel = findViewById(R.id.groupTestPanel)
ctvAutopilotStatus = findViewById(R.id.module_mogo_och_autopilot_status)
ctvAutopilotStatusIv = findViewById(R.id.bus_autopilot_btn_iv)
ctvAutopilotStatusTv = findViewById(R.id.bus_autopolot_btn_tv)
flStationPanelContainer = findViewById(R.id.module_mogo_och_station_panel_container)
mTrafficDataView = findViewById<View>(R.id.bus_arc) as TrafficDataView?
LayoutInflater.from(context).inflate(getStationPanelViewId(), flStationPanelContainer)
mSwitchMapModeLayout = findViewById(R.id.bus_switch_model_layout)
mSwitchMapModeImage = findViewById(R.id.bus_switch_model_icon)
updateSwitchMapIcon()
mSwitchMapModeLayout!!.setOnClickListener(object : OnPreventFastClickListener() {
override fun onClickImpl(v: View) {
val controller = getMapUIController()
if (controller != null) {
//切换地图的远近视图
if (controller.currentMapVisualAngle.isLongSight) {
updateLongSightLevel(false)
Objects.requireNonNull(getMapUIController())
?.setLockMode(true)
controller.changeMapVisualAngle(VisualAngleMode.MODE_MEDIUM_SIGHT, null)
mSwitchMapModeImage!!.setImageResource(R.drawable.bus_switch_map_medium)
} else if (controller.currentMapVisualAngle.isMediumSight) {
updateLongSightLevel(true)
if (FunctionBuildConfig.isRomaMode) {
controller.setRomaMode(1)
} else {
Objects.requireNonNull(getMapUIController())
?.setLockMode(false)
controller.changeMapVisualAngle(VisualAngleMode.MODE_LONG_SIGHT, null)
}
mSwitchMapModeImage!!.setImageResource(R.drawable.bus_switch_map_long)
} else {
controller.changeMapVisualAngle(VisualAngleMode.MODE_MEDIUM_SIGHT, null)
mSwitchMapModeImage!!.setImageResource(R.drawable.bus_switch_map_medium)
}
}
}
})
initListener()
setAutopilotBtnStatus(getAutoPilotStatusInfo().state)
ctvAutopilotStatus!!.setOnClickListener(object : OnPreventFastClickListener() {
override fun onClickImpl(v: View) {
restartAutopilot()
}
})
// 模拟 不可自动驾驶目前场景是刚开机adas还未和工控机连接
findViewById<View>(R.id.btnAutopilotDisable)!!.setOnClickListener { view: View? ->
debugAutoPilotStatus(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE
)
}
// 模拟 可自动驾驶,工控机连接正常,且处于人工干预状态
findViewById<View>(R.id.btnAutopilotEnable)!!.setOnClickListener { view: View? ->
debugAutoPilotStatus(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE
)
}
// 模拟 自动驾驶能力,自动驾驶中,可能是停车,可能是行进,但是是机器在处理车的前进后退,不是人
findViewById<View>(R.id.btnAutopilotRunning)!!.setOnClickListener { view: View? ->
debugAutoPilotStatus(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
)
}
// 模拟 自动驾驶网约车回调数据
findViewById<View>(R.id.btnAutopilotRoute)!!.setOnClickListener { view: View? -> debugArrivedRoute() }
mSettingBtn = findViewById(R.id.module_mogo_och_setting_layout)
mSettingBtn!!.setOnClickListener { v: View? ->
// TODO: 2021/12/9
showToolsView()
}
// mBadcaseBtn的visible显示逻辑在showBadcaseEntrance内处理
mBadcaseBtn = findViewById(R.id.module_mogo_och_badcase_rl)
if (mBadcaseBtn != null) {
initBadCase(mBadcaseBtn!!)
CallerAutopilotRecordListenerManager.addListener(TAG, this)
}
mAICollectBtn = findViewById(R.id.module_mogo_och_ai_collet_rl)
if (mAICollectBtn != null) {
initAiCollect(mAICollectBtn!!)
}
//消息盒子
viewDriverMsgBoxButton = findViewById(R.id.viewDriverMsgBoxButton)
viewDriverMsgBoxList = findViewById(R.id.viewDriverMsgBoxList)
viewDriverMsgBoxBubble = findViewById(R.id.viewDriverMsgBoxBubble)
viewDriverMsgBoxButton!!.setClickListener(object : ClickListener {
override fun showMsgBoxList(show: Boolean) {
if (show) {
viewDriverMsgBoxList!!.visibility = View.VISIBLE
viewDriverMsgBoxList!!.notifyData()
viewDriverMsgBoxBubble!!.visibility = View.GONE
viewDriverMsgBoxBubble!!.isShowData(false)
} else {
viewDriverMsgBoxList!!.visibility = View.GONE
viewDriverMsgBoxBubble!!.visibility = View.VISIBLE
viewDriverMsgBoxBubble!!.isShowData(true)
}
}
})
smallMapView = findViewById(R.id.smallMapView)
}
override fun initViews(savedInstanceState: Bundle?) {
super.initViews(savedInstanceState)
mapBizView!!.onCreate(savedInstanceState)
smallMapView!!.onCreateView(savedInstanceState)
}
override fun onResume() {
super.onResume()
mapBizView!!.onResume()
smallMapView!!.onResume()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
): View? {
EventBus.getDefault().register(this)
return super.onCreateView(inflater, container, savedInstanceState)
}
protected abstract fun onArriveStation()
private fun updateSwitchMapIcon() {
val controller = getMapUIController()
if (controller != null) {
if (controller.currentMapVisualAngle.isLongSight) {
mSwitchMapModeImage!!.setImageResource(R.drawable.bus_switch_map_long)
} else if (controller.currentMapVisualAngle.isMediumSight) {
mSwitchMapModeImage!!.setImageResource(R.drawable.bus_switch_map_medium)
} else {
mSwitchMapModeImage!!.setImageResource(R.drawable.bus_switch_map_medium)
}
}
}
private fun debugArrivedRoute() {
// BDRouteDataTestUtils.converToRouteData()
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapBizView!!.onSaveInstanceState(outState)
}
override fun onLowMemory() {
super.onLowMemory()
mapBizView!!.onLowMemory()
}
override fun onPause() {
super.onPause()
mapBizView!!.onPause()
smallMapView!!.onPause()
}
override fun onDestroyView() {
mapBizView!!.onDestroy()
super.onDestroyView()
CallerAutopilotRecordListenerManager.removeListener(TAG)
EventBus.getDefault().unregister(this)
}
private fun initListener() {
mogoMapListenerHandler.registerHostMapListener(TAG, this)
}
open fun playDI() {
SoundPoolHelper.getSoundPoolHelper().playSoundWithRedId(context, R.raw.bus_di)
}
/**
* 改变自动驾驶状态
*
* @param autopilotStatus 0:不可用 1:可用状态 2:自动驾驶中
*/
open fun onAutopilotStatusChanged(autopilotStatus: Int) {
activity?.runOnUiThread {
changeAutopilotBtnView(
autopilotStatus,
isAnimateRunning
)
}
}
open fun setAutopilotBtnStatus(autopilotStatus: Int) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE
== autopilotStatus
) { //0不可用
ctvAutopilotStatusTv!!.setTextColor(resources.getColor(R.color.bus_autopilot_text_color_disable))
ctvAutopilotStatusTv!!.text =
resources.getString(R.string.bus_loading_autopilot_runnig_tv)
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_disable_autopilot_icon)
ctvAutopilotStatus!!.isSelected = false
ctvAutopilotStatus!!.isClickable = true
} else {
ctvAutopilotStatusTv!!.setTextColor(resources.getColor(R.color.bus_autopilot_text_color_normal))
ctvAutopilotStatusTv!!.text =
resources.getString(R.string.bus_loading_autopilot_runnig_tv)
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_ic_autopilot)
ctvAutopilotStatus!!.isClickable = true
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE == autopilotStatus) { //1可用
ctvAutopilotStatus!!.isSelected = false
} else if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == autopilotStatus) {
ctvAutopilotStatus!!.isSelected = true
}
}
}
open fun updateAutopilotStatus(autopilotStatus: Int) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
== autopilotStatus
) { //2 running
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_right_autopilot_icon)
ctvAutopilotStatusTv!!.setTextColor(resources.getColor(R.color.bus_autopilot_text_color_normal))
ctvAutopilotStatusTv!!.text =
resources.getString(R.string.bus_loading_autopilot_success_tv)
ctvAutopilotStatus!!.isSelected = false
ctvAutopilotStatus!!.isClickable = false
} else {
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_wrong_autopilot_icon)
ctvAutopilotStatusTv!!.setTextColor(resources.getColor(R.color.bus_autopilot_text_color_normal))
ctvAutopilotStatusTv!!.text =
resources.getString(R.string.bus_loading_autopilot_failure_tv)
ctvAutopilotStatus!!.isClickable = false
ctvAutopilotStatus!!.isSelected = false
}
UiThreadHandler.postDelayed({ setAutopilotBtnStatus(autopilotStatus) }, 1000)
}
private fun changeAutopilotBtnView(autopilotStatus: Int, isAnimateRunning: Boolean) {
if (isAnimateRunning && IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
!= autopilotStatus
) {
// 主动开启自动驾驶中不为2为0、1则继续loading
return
}
if (isAnimateRunning) {
stopAnimAndUpdateBtnStatus()
} else {
setAutopilotBtnStatus(autopilotStatus)
}
}
open fun stopAnimAndUpdateBtnStatus() {
stopAutopilotAnimation()
updateAutopilotStatus(getAutoPilotStatusInfo().state)
}
/**
* 展示【自动驾驶】按钮
*/
open fun showAutopilotBiz() {
activity?.runOnUiThread { ctvAutopilotStatus!!.visibility = View.VISIBLE }
}
/**
* 获取站点面板view在[.initViews]时候添加到container中
*
* @return 站点面板view
*/
abstract fun getStationPanelViewId(): Int
/**
* 重新开启自动驾驶
*/
abstract fun restartAutopilot()
/**
* 模拟自动驾驶返回状态
*
* @param status
*/
abstract fun debugAutoPilotStatus(status: Int)
/**
* 开启自动驾驶中间动画
*/
@SuppressLint("ObjectAnimatorBinding")
open fun startAutopilotAnimation() {
isAnimateRunning = true
ctvAutopilotStatusTv!!.text = resources.getString(R.string.bus_loading_autopilot_tv)
ctvAutopilotStatusTv!!.setTextColor(resources.getColor(R.color.bus_autopilot_text_color_normal))
ctvAutopilotStatus!!.isSelected = false
ctvAutopilotStatus!!.isClickable = true
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_loading_autopilot_icon)
if (autopilotLoadingAnimator == null) {
autopilotLoadingAnimator =
ObjectAnimator.ofFloat(ctvAutopilotStatusIv, "rotation", 0f, 360f)
autopilotLoadingAnimator?.interpolator = LinearInterpolator()
autopilotLoadingAnimator?.repeatCount = -1 //无限循环
autopilotLoadingAnimator?.duration = 1000 //设置持续时间
}
autopilotLoadingAnimator!!.start() //动画开始
startingAutoApilotCountDown()
}
private fun startingAutoApilotCountDown() {
//10s 若自动驾驶没有开启,则结束动画
UiThreadHandler.postDelayed({
//未启动成功做处理
if (isAnimateRunning) { // 只判断动画是否在进行,根据自动驾驶当前状态去设置自动驾驶状态
stopAutopilotAnimation()
updateAutopilotStatus(getAutoPilotStatusInfo().state)
}
}, CharterConst.TIMER_START_AUTOPILOT_INTERVAL)
}
/**
* 停止自动驾驶中间动画
*/
protected open fun stopAutopilotAnimation() {
if (autopilotLoadingAnimator != null) {
autopilotLoadingAnimator!!.end()
ctvAutopilotStatusIv!!.clearAnimation()
autopilotLoadingAnimator = null
isAnimateRunning = false
}
}
/**
* 迈速表实时更新
*
* @param newSpeed
*/
open fun updateSpeedView(newSpeed: Float) {
val speed = (Math.abs(newSpeed) * 3.6f).toInt() // 倒车时工控机反馈定位信息中speed为负值
if (mTrafficDataView != null) {
mTrafficDataView!!.updateSpeedWithValue(speed)
}
}
override fun onDestroy() {
super.onDestroy()
smallMapView!!.onDestroy()
mogoMapListenerHandler.unregisterHostMapListener(TAG)
}
override fun onMapVisualAngleChanged(visualAngleMode: VisualAngleMode) {
if (visualAngleMode.isMediumSight) {
mSwitchMapModeLayout!!.visibility = View.VISIBLE
} else if (visualAngleMode.isLongSight) {
mSwitchMapModeLayout!!.visibility = View.VISIBLE
} else if (visualAngleMode.isCloseSight) {
mSwitchMapModeLayout!!.visibility = View.GONE
}
}
/**
* bus调试面板打开关闭
*/
open fun debugTestBar() {
if (groupTestPanel!!.visibility == View.VISIBLE) {
groupTestPanel!!.visibility = View.GONE
} else {
groupTestPanel!!.visibility = View.VISIBLE
}
}
/**
* Bus调试信息线路、轨迹等信息
*
*
* START
*/
private var busTestBar: View? = null
private var lineIdTV: TextView? = null
private var trajMd5TV: TextView? = null
private var stopMd5TV: TextView? = null
private var trajMd5DPQPTV: TextView? = null
private var stopMd5DPQPTV: TextView? = null
// open fun showHideTestBar() {
// if (busTestBar == null) {
// busTestBar = findViewById(R.id.module_mogo_och_bus_test_bar)
// lineIdTV = findViewById(R.id.bus_test_bar_current_line_id)
// trajMd5TV = findViewById(R.id.bus_test_bar_current_traj_md5)
// stopMd5TV = findViewById(R.id.bus_test_bar_current_stop_md5)
// trajMd5DPQPTV = findViewById(R.id.bus_test_bar_current_traj_md5_dpqp)
// stopMd5DPQPTV = findViewById(R.id.bus_test_bar_current_stop_md5_dpqp)
// }
// if (busTestBar!!.visibility == View.VISIBLE) {
// busTestBar!!.visibility = View.GONE
// } else {
// val routesResult: BusRoutesResult = BusOrderModel.getInstance().getBusRoutesResult()
// lineIdTV!!.text = "lineId:" + (routesResult.lineId.toString() ?: "")
// trajMd5TV!!.text = "TMd5:" + routesResult.csvFileMd5
// stopMd5TV!!.text = "SMd5:" + routesResult.txtFileMd5
// trajMd5DPQPTV!!.text =
// "TMd5DPQP:" + routesResult.csvFileMd5DPQP
// stopMd5DPQPTV!!.text =
// "SMd5DPQP:" + routesResult.txtFileMd5DPQP
// busTestBar!!.visibility = View.VISIBLE
// }
// }
// open fun updateBusTestBarInfo() {
// if (busTestBar != null && busTestBar!!.visibility == View.VISIBLE) {
// val routesResult: BusRoutesResult = BusOrderModel.getInstance().busRoutesResult
// lineIdTV!!.text = "lineId:" + (routesResult?.lineId?.toString() ?: "")
// trajMd5TV!!.text = "TMd5:" + if (routesResult == null) "" else routesResult.csvFileMd5
// stopMd5TV!!.text = "SMd5:" + if (routesResult == null) "" else routesResult.txtFileMd5
// trajMd5DPQPTV!!.text =
// "TMd5DPQP:" + if (routesResult == null) "" else routesResult.csvFileMd5DPQP
// stopMd5DPQPTV!!.text =
// "SMd5DPQP:" + if (routesResult == null) "" else routesResult.txtFileMd5DPQP
// }
// }
/**
* END
*/
}

View File

@@ -0,0 +1,11 @@
package com.magic.mogo.och.charter.callback;
/**
* Created on 2021/9/8
*
* Model->Presenter回调ADAS相关自动驾驶状态回调到达终点等等
*/
public interface IADASStatusCallback {
//自驾返回失败
void onStartAdasFailure();
}

View File

@@ -0,0 +1,76 @@
package com.magic.mogo.och.charter.constant
/**
* Created on 2021/12/6
*/
class CharterConst {
companion object {
// OCH arouter 路由path
const val PATH = "/och/api"
// 测试用的广播
const val BROADCAST_TEST_BUS_CONTROL_TYPE_EXTRA_KEY = "sceneType"
// 无状态
const val STATION_STATUS_IDLE = 0
// 已过站(历史站)
const val STATION_STATUS_LEAVING = 1
// 到站(当前站)
const val STATION_STATUS_STOPPED = 2
// 未到站(未到站)
const val STATION_STATUS_ARRIVING = 3
// 上报心跳轮询ms
const val LOOP_PERIOD_60S = 60 * 1000L
// 开始服务启动自动驾驶等待时间(埋点上传)
const val LOOP_PERIOD_15S = 15 * 1000L
const val LOOP_PERIOD_1S = 1 * 1000L
const val LOOP_DELAY = 100L
// 下发给MEC轨迹信息间隔时间 10秒
const val LOOP_PERIOD_10S = 10 * 1000L
// 尝试下发给MEC轨迹最多10次
const val LOOP_SEND_TRAJ_TIMES = 10
//起点UUID
const val BUS_START_MAP_MAKER = "bus_start_map_maker";
//终点UUID
const val BUS_END_MAP_MAKER = "bus_end_map_maker";
// 埋点key接管后点击'自动驾驶'按钮启动
const val EVENT_KEY_RESTART_AUTOPILOT = "event_key_och_bus_restart_autopilot"
// 埋点key开始服务开启自动驾驶成功/失败)
const val EVENT_KEY_START_SERVICE = "event_key_och_bus_start_service"
const val EVENT_PARAM_SN = "sn"
const val EVENT_PARAM_TIME = "time"
const val EVENT_PARAM_START_NAME = "start_name"
const val EVENT_PARAM_END_NAME = "end_name"
const val EVENT_PARAM_LINE_ID = "line_id"
const val EVENT_PARAM_START_RESULT = "start_autopilot" // true/false
const val EVENT_PARAM_START_FAILURE_CODE = "start_autopilot_failure_code" // 启动自驾失败code
const val EVENT_PARAM_START_FAILURE_MSG = "start_autopilot_failure_msg" // 启动自驾失败原因
const val EVENT_PARAM_PLATE_NUM = "plate_number" // 车牌号
const val EVENT_PARAM_ENV_ONLINE = "env_online" // 是否线上环境true/false
// 埋点key开启自动驾驶前已识别的异常会导致无法开启自驾
const val EVENT_KEY_AP_UNABLE_START_REASON = "event_key_och_bus_ap_unable_start_reason"
const val EVENT_PARAM_UNABLE_START_REASON = "unable_start_reason";
/**
* 订单起终点Marker类型
*/
const val TYPE_MARKER_BUS_ORDER = "TYPE_MARKER_BUS_ORDER"
const val TIMER_START_AUTOPILOT_INTERVAL = 20 * 1000L
//围栏到站 暂定10米
const val ARRIVE_AT_END_STATION_DISTANCE = 10
// 轮询
const val LOOP_PASSENGER_5S = 5 * 1000L
const val LOOP_PASSENGER_2S = 2 * 1000L
const val LOOP_PASSENGER_1S = 1 * 1000L
const val LOOP_DELAY_500 = 500L
const val DELAY_10S = 10 * 1000L
}
}

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/bus_autopilot_text_color_normal"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 491 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 377 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 402 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_ai_select" android:state_focused="true" android:state_pressed="true" />
<item android:drawable="@drawable/icon_ai_select" android:state_focused="false" android:state_pressed="true" />
<item android:drawable="@drawable/icon_ai_select" android:state_selected="true" />
<item android:drawable="@drawable/icon_ai_select" android:state_focused="true" />
<item android:drawable="@drawable/icon_ai_normal" />
</selector>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/icon_bad_case_select" android:state_focused="true" android:state_pressed="true" />
<item android:drawable="@drawable/icon_bad_case_select" android:state_focused="false" android:state_pressed="true" />
<item android:drawable="@drawable/icon_bad_case_select" android:state_selected="true" />
<item android:drawable="@drawable/icon_bad_case_select" android:state_focused="true" />
<item android:drawable="@drawable/icon_bad_case_normal" />
</selector>

View File

@@ -0,0 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#ff000000"/>
<corners android:radius="@dimen/bus_traffic_light_layout_corner"/>
</shape>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_pressed="true" android:drawable="@drawable/press_start_status">
</item>
<item android:state_selected="true" android:drawable="@drawable/start_success">
</item>
<item android:state_selected="false" android:drawable="@drawable/start_failure">
</item>
<item android:state_focused="true" android:drawable="@drawable/press_start_status">
</item>
<item android:state_focused="false" android:drawable="@drawable/start_failure">
</item>
<item android:drawable="@drawable/start_failure">
</item>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient android:angle="180" android:endColor="#000B4B" android:startColor="#001C83" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<gradient android:angle="180" android:endColor="#0027FF" android:startColor="#4267FF" />
</shape>
</item>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 B

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<!-- <corners android:radius="@dimen/module_mogo_och_autopilot_status_bg_corner" />-->
<gradient
android:startColor="#323C6F"
android:endColor="#323C6F"
android:angle="315"
/>
<size
android:width="120dp"
android:height="120dp"
/>
</shape>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/bus_operation_status_select_bg" android:state_focused="true" android:state_pressed="true" />
<item android:drawable="@drawable/bus_operation_status_select_bg" android:state_focused="false" android:state_pressed="true" />
<item android:drawable="@drawable/bus_operation_status_select_bg" android:state_selected="true" />
<item android:drawable="@drawable/bus_operation_status_select_bg" android:state_focused="true" />
<item android:drawable="@drawable/bus_operation_status_bg" />
</selector>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<!-- <corners android:radius="@dimen/module_mogo_och_autopilot_status_bg_corner" />-->
<gradient
android:startColor="#029DFF"
android:endColor="#0056FF"
android:angle="225"
/>
<size
android:width="120dp"
android:height="120dp"
/>
</shape>

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="#2B6EFF"/>
<corners android:radius="33dp"/>
</shape>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<corners android:radius="27dp" />
<solid android:color="#3B4577"/>
</shape>
</item>
<item
android:bottom="3dp"
android:left="3dp"
android:right="3dp"
android:top="3dp">
<shape>
<corners android:radius="27dp" />
<solid android:color="#3B4577"/>
</shape>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="oval">
<size android:width="26dp" android:height="26dp"/>
<corners android:radius="13dp" />
<gradient
android:angle="225"
android:startColor="#FF0030"
android:endColor="#CF2E00"
android:type="linear" />
</shape>

View File

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

View File

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

Some files were not shown because too many files have changed in this diff Show More