[charter] m1司机端初始化
1
OCH/mogo-och-charter/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
48
OCH/mogo-och-charter/build.gradle
Normal 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")
|
||||
}
|
||||
0
OCH/mogo-och-charter/consumer-rules.pro
Normal file
21
OCH/mogo-och-charter/proguard-rules.pro
vendored
Normal 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
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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->Presenter:VR 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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
}
|
||||
@@ -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 登陆失败
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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()
|
||||
}
|
||||
}
|
||||
5
OCH/mogo-och-charter/src/main/AndroidManifest.xml
Normal 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>
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package com.magic.mogo.och.charter.callback;
|
||||
|
||||
/**
|
||||
* Created on 2021/9/8
|
||||
*
|
||||
* Model->Presenter回调:ADAS相关(自动驾驶状态回调,到达终点等等)
|
||||
*/
|
||||
public interface IADASStatusCallback {
|
||||
//自驾返回失败
|
||||
void onStartAdasFailure();
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 323 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 338 B |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 25 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/bus_line_panel_bg.png
Executable file
|
After Width: | Height: | Size: 53 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/bus_line_panel_bg_1.png
Executable file
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 491 B |
|
After Width: | Height: | Size: 2.5 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/bus_no_line_icon.png
Executable file
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 1004 B |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/bus_switch_map_long.png
Executable file
|
After Width: | Height: | Size: 5.7 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/bus_switch_map_medium.png
Executable file
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/end_maker_icon.png
Executable file
|
After Width: | Height: | Size: 5.0 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_ai_normal.png
Executable file
|
After Width: | Height: | Size: 4.7 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_ai_select.png
Executable file
|
After Width: | Height: | Size: 5.2 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_arrow_blue_bus.png
Executable file
|
After Width: | Height: | Size: 377 B |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_arrow_green_bus.png
Executable file
|
After Width: | Height: | Size: 400 B |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_arrow_grey_bus.png
Executable file
|
After Width: | Height: | Size: 402 B |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_bad_case_normal.png
Executable file
|
After Width: | Height: | Size: 6.9 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_bad_case_select.png
Executable file
|
After Width: | Height: | Size: 6.7 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_no_bus_line.png
Executable file
|
After Width: | Height: | Size: 13 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_point_blue_bus.png
Executable file
|
After Width: | Height: | Size: 1.4 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_point_green_bus.png
Executable file
|
After Width: | Height: | Size: 3.7 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/icon_point_grey_bus.png
Executable file
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 14 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/press_start_status.png
Executable file
|
After Width: | Height: | Size: 15 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/start_failure.png
Executable file
|
After Width: | Height: | Size: 18 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable-xhdpi/start_success.png
Executable file
|
After Width: | Height: | Size: 21 KiB |
8
OCH/mogo-och-charter/src/main/res/drawable/ai_collect_selector.xml
Executable 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>
|
||||
8
OCH/mogo-och-charter/src/main/res/drawable/bad_case_selector.xml
Executable 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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 20 KiB |
@@ -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>
|
||||
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 2.3 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
@@ -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>
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable/bus_dot_line.png
Normal file
|
After Width: | Height: | Size: 323 B |
BIN
OCH/mogo-och-charter/src/main/res/drawable/bus_ic_autopilot.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 338 B |
|
After Width: | Height: | Size: 32 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable/bus_light_red_nor.png
Normal file
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 25 KiB |
@@ -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>
|
||||
@@ -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>
|
||||
BIN
OCH/mogo-och-charter/src/main/res/drawable/bus_line_panel_bg.png
Executable file
|
After Width: | Height: | Size: 53 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable/bus_line_panel_bg_1.png
Executable file
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable/bus_och_dot_line.png
Normal file
|
After Width: | Height: | Size: 1004 B |
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
19
OCH/mogo-och-charter/src/main/res/drawable/bus_panel_bkg.xml
Normal 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>
|
||||
|
After Width: | Height: | Size: 3.3 KiB |
BIN
OCH/mogo-och-charter/src/main/res/drawable/bus_selected_btn.png
Normal file
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||