diff --git a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/model/LineModel.kt b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/model/LineModel.kt index 5e54f38d27..b4af37444e 100644 --- a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/model/LineModel.kt +++ b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/model/LineModel.kt @@ -17,6 +17,7 @@ import com.mogo.och.common.module.manager.loop.BizLoopManager import com.mogo.och.common.module.network.OchCommonServiceCallback import com.mogo.och.common.module.utils.DateTimeUtil import com.mogo.och.common.module.utils.ResourcesUtils +import com.mogo.och.common.module.utils.RxUtils import com.mogo.och.data.bean.BusStationBean import com.mogo.och.shuttle.weaknet.R import com.mogo.och.weaknet.bean.response.CarExecutableTaskResponse @@ -45,7 +46,7 @@ object LineModel { private val mBusLinesCallbackMap: MutableMap = ConcurrentHashMap() - private const val TAG = "BusLineModel" + const val TAG = "BusLineModel" private val context = AbsMogoApplication.getApp() @@ -64,6 +65,11 @@ object LineModel { private val isRequesting = AtomicBoolean(false) private val loopQueryInfo = Runnable { queryCarExecutableTaskList(true) } + private var searchTaskBylineIdDisposable:Disposable?=null + private var searchLineDisposable:Disposable?=null + private var startTaskDisposable:Disposable?=null + private var endTaskDisposable:Disposable?=null + // 当前站点 @JvmStatic var startStationIndex: Int = 0 //A->B 此处值是A站点索引 @@ -173,24 +179,30 @@ object LineModel { */ @JvmStatic fun queryBusLines() { + RxUtils.disposeSubscribe(endTaskDisposable) RepositoryManager.queryCanUseLine() + ?.subscribeOn(Schedulers.io()) + ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe(object : Observer?> { override fun onSubscribe(d: Disposable) { - d(TAG, "onSubscribe") + endTaskDisposable = d + d(TAG, "queryBusLines onSubscribe") } override fun onError(e: Throwable) { - d(TAG, "onError${e.printStackTrace()}") + d(TAG, "queryBusLines onError${e.printStackTrace()}") } override fun onComplete() { - d(TAG, "onComplete") + d(TAG, "queryBusLines onComplete") } override fun onNext(data: List) { + d(TAG, "queryBusLines onNext ${data}") mBusLinesCallbackMap.forEach { it.value.onBusLinesChange(data) } + RxUtils.disposeSubscribe(endTaskDisposable) } }) @@ -202,31 +214,35 @@ object LineModel { */ @JvmStatic fun queryBusLineTasksById(lineId: Long) { + RxUtils.disposeSubscribe(searchTaskBylineIdDisposable) + d(TAG, "queryBusLineTasksById 查询线路的任务线路id:${lineId}") RepositoryManager.queryCanUserTask(lineId) ?.subscribeOn(Schedulers.io()) ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe(object : Observer?> { override fun onSubscribe(d: Disposable) { - d(TAG, "onSubscribe") + searchTaskBylineIdDisposable = d + d(TAG, "queryBusLineTasksById onSubscribe") } override fun onError(e: Throwable) { - d(TAG, "onError${e.printStackTrace()}") + d(TAG, "queryBusLineTasksById onError${e.printStackTrace()}") mBusLinesCallbackMap.forEach { it.value.onBusLineTasksError() } } override fun onComplete() { - d(TAG, "onComplete") + d(TAG, "queryBusLineTasksById onComplete") } override fun onNext(data: List) { + d(TAG, "queryBusLineTasksById onNext ${data}") mBusLinesCallbackMap.forEach { it.value.onBusLineTasks(data) } + RxUtils.disposeSubscribe(searchTaskBylineIdDisposable) } - }) } @@ -235,6 +251,7 @@ object LineModel { */ @JvmStatic fun commitSwitchLineId(task: TaskDataBean, line: LineDataBean) { + RxUtils.disposeSubscribe(startTaskDisposable) line.getLineIdAndName { lineId, lineName -> task.getLineIdAndName { taskId, taskTime -> RepositoryManager.startTask(taskId, lineId, taskTime, lineName) @@ -242,11 +259,12 @@ object LineModel { ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe(object : Observer { override fun onSubscribe(d: Disposable) { - d(TAG, "onSubscribe") + startTaskDisposable = d + d(TAG, "commitSwitchLineId onSubscribe") } override fun onError(e: Throwable) { - d(TAG, "onError${e.printStackTrace()}") + d(TAG, "commitSwitchLineId onError${e.printStackTrace()}") if (e is DataException) { OchChainLogManager.writeChainLog("开始任务", "${e.message}") ToastUtils.showShort("选择任务失败:${e.message}") @@ -257,10 +275,11 @@ object LineModel { } override fun onComplete() { - d(TAG, "onComplete") + d(TAG, "commitSwitchLineId onComplete") } override fun onNext(data: Boolean) { + d(TAG, "commitSwitchLineId onNext ${data}") if (data) { EventDb.saveEventTaskStart(taskId, lineId, taskTime, lineName) OrderModel.queryBusRoutes() @@ -268,6 +287,7 @@ object LineModel { it.value.onChangeLineIdSuccess() } } + RxUtils.disposeSubscribe(startTaskDisposable) } }) } @@ -325,21 +345,23 @@ object LineModel { ?.observeOn(AndroidSchedulers.mainThread()) ?.subscribe(object : Observer { override fun onSubscribe(d: Disposable) { - d(TAG, "onSubscribe") + startTaskDisposable + d(TAG, "endTask onSubscribe") } override fun onError(e: Throwable) { - d(TAG, "onError${e.printStackTrace()}") + d(TAG, "endTask onError${e.printStackTrace()}") if (e is DataException) { } } override fun onComplete() { - + d(TAG, "endTask onComplete") } override fun onNext(data: Boolean) { + d(TAG, "endTask onNext ${data}") if (data) { currentTask = null LineManager.setLineInfo(null) @@ -352,6 +374,7 @@ object LineModel { val changeInfo = "taskId:${currentTask?.taskId}--lineInfo:${LineManager.lineInfos}" OchChainLogManager.writeChainLog("结束任务", changeInfo) } + onComplete() } }) } diff --git a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/model/OrderModel.kt b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/model/OrderModel.kt index dae568828d..03906c4e3f 100644 --- a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/model/OrderModel.kt +++ b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/model/OrderModel.kt @@ -160,9 +160,6 @@ object OrderModel { */ @JvmStatic fun completeTask() { - - RepositoryManager - OCHThreadPoolManager.getsInstance().execute { d(M_BUS + TAG, "结束当前路线abortTask") diff --git a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/bizswitch/SwitchBizView.kt b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/bizswitch/SwitchBizView.kt index 676d20f861..4c0bda28a9 100644 --- a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/bizswitch/SwitchBizView.kt +++ b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/bizswitch/SwitchBizView.kt @@ -81,7 +81,7 @@ class SwitchBizView: WindowRelativeLayout, SwtichBizeModel.SwtichLineViewCallbac val endLoading = System.currentTimeMillis() val dex = (100-(endLoading - startLoading)).takeIf { it>=0 }?:0 - CallerLogger.d(TAG,"展示线路任务 lading 展示了 ${dex}毫秒") + CallerLogger.d(TAG,"展示任务 lading 展示了 ${dex}毫秒") ThreadUtils.runOnUiThreadDelayed({ loading_biz.visibility = GONE @@ -108,7 +108,7 @@ class SwitchBizView: WindowRelativeLayout, SwtichBizeModel.SwtichLineViewCallbac override fun loadRunningTask() { val endLoading = System.currentTimeMillis() val dex = (100-(endLoading - startLoading)).takeIf { it>=0 }?:0 - CallerLogger.d(TAG,"展示线路 lading 展示了 ${dex}毫秒") + CallerLogger.d(TAG,"展示运行中任务 lading 展示了 ${dex}毫秒") ThreadUtils.runOnUiThreadDelayed({ loading_biz.visibility = GONE swtichLine.visibility = GONE diff --git a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/bizswitch/SwtichBizeModel.kt b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/bizswitch/SwtichBizeModel.kt index a6e3d88eea..3b8eff028a 100644 --- a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/bizswitch/SwtichBizeModel.kt +++ b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/bizswitch/SwtichBizeModel.kt @@ -2,11 +2,14 @@ package com.mogo.och.weaknet.ui.bizswitch import androidx.lifecycle.ViewModel import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d import com.mogo.eagle.core.utilcode.util.ThreadUtils import com.mogo.och.weaknet.callback.IBusLinesCallback import com.mogo.och.weaknet.model.LineModel import com.mogo.och.weaknet.model.OrderModel import com.mogo.och.weaknet.repository.db.bean.LineDataBean +import com.mogo.och.weaknet.ui.switchtask.SwitchTaskView +import com.mogo.och.weaknet.ui.switchtask.SwitchTaskView.Companion /** * @author XuXinChao @@ -34,6 +37,7 @@ class SwtichBizeModel : ViewModel(), IBusLinesCallback { } fun loadingSwitchTask(lineInfo: LineDataBean) { + d(LineModel.TAG, "loadingSwitchTask 查询线路的任务线路信息:${lineInfo}") viewCallback?.showSwitchTaskByLineInfo(lineInfo) } @@ -76,10 +80,7 @@ class SwtichBizeModel : ViewModel(), IBusLinesCallback { override fun onCompleteTask() { - super.onCompleteTask() - ThreadUtils.getIoPool().execute { - OrderModel.queryBusRoutes() - } + OrderModel.queryBusRoutes() } } diff --git a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchline/SwitchLineView.kt b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchline/SwitchLineView.kt index c4a4f6fc03..a3bd075ad1 100644 --- a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchline/SwitchLineView.kt +++ b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchline/SwitchLineView.kt @@ -17,6 +17,7 @@ import com.mogo.och.common.module.manager.loop.BizLoopManager import com.mogo.och.common.module.utils.ResourcesUtils import com.mogo.och.common.module.wigets.WindowRelativeLayout import com.mogo.och.shuttle.weaknet.R +import com.mogo.och.weaknet.model.LineModel import com.mogo.och.weaknet.repository.db.bean.LineDataBean import com.mogo.och.weaknet.ui.bizswitch.SwtichBizeModel import kotlinx.android.synthetic.main.shuttle_wadk_task_running.view.no_order_data_view @@ -72,6 +73,7 @@ class SwitchLineView: WindowRelativeLayout, SwtichLineModel.SwtichLineViewCallba //设置item 点击事件 mAdapter.setOnLineItemClickListener(object : SwitchLineAdapter.LineItemClickListener{ override fun onItemClick(data: LineDataBean) { + CallerLogger.d(LineModel.TAG,"选择线路 线路信息:${data}") viewbizModel?.loadingSwitchTask(data) } }) diff --git a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchtask/SwitchLineTaskAdapter.kt b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchtask/SwitchLineTaskAdapter.kt index 55ff7d88dd..2df1e1db99 100644 --- a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchtask/SwitchLineTaskAdapter.kt +++ b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchtask/SwitchLineTaskAdapter.kt @@ -29,9 +29,7 @@ class SwitchLineTaskAdapter( // 如果新旧列表一致,则直接返回 return } - checkTask = null - val diffResult = DiffUtil.calculateDiff(MyDiffCallback(this.mData, dataList)) this.mData.clear() this.mData.addAll(dataList) @@ -42,12 +40,6 @@ class SwitchLineTaskAdapter( return checkTask } - private var mTaskItemClickListener: TaskItemClickListener? = null - - fun setOnLineItemClickListener(mTaskItemClickListener: TaskItemClickListener?) { - this.mTaskItemClickListener = mTaskItemClickListener - } - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SwitchLineTaskViewHolder { val view = LayoutInflater.from(mContext).inflate( R.layout.shuttle_weak_switch_task_item, parent, false @@ -61,38 +53,38 @@ class SwitchLineTaskAdapter( val taskStartTime = TimeUtils.millis2String(task.taskStartTime?:System.currentTimeMillis(), "HH:mm") holder.taskTime.text = taskStartTime - holder.taskTime.isChecked = if(checkTask!=null) checkTask!!.taskId == task.taskId else false + if(checkTask==null){ + holder.taskTime.isChecked = false + }else{ + holder.taskTime.isChecked = task==checkTask + } holder.taskTime.setOnClickListener { + var preCheckIndex = -1 if(checkTask==null){ - resetOther() checkTask = task - mTaskItemClickListener?.onItemClick(currentPosition,true) }else{ - if(checkTask!!.taskId==task.taskId){ + if(checkTask==task){ checkTask = null - mTaskItemClickListener?.onItemClick(currentPosition,false) - notifyItemChanged(currentPosition) }else { resetOther() + mData.forEachIndexed { index, result -> + if(checkTask == result){ + checkTask = null + preCheckIndex = index + } + } checkTask = task - mTaskItemClickListener?.onItemClick(currentPosition,true) - notifyItemChanged(currentPosition) } } - notifyItemChanged(currentPosition) + if(preCheckIndex>=0){ + notifyItemChanged(preCheckIndex) + } } - } private fun resetOther() { - mData.forEachIndexed { index, result -> - if(checkTask!=null && result.taskId==checkTask!!.taskId){ - checkTask = null - notifyItemChanged(index) - return - } - } + } override fun getItemCount(): Int { @@ -103,10 +95,6 @@ class SwitchLineTaskAdapter( val taskTime: AppCompatCheckedTextView = itemView.findViewById(R.id.actv_task_time) // 时间 } - interface TaskItemClickListener { - fun onItemClick(position: Int,isCheck:Boolean) - } - inner class MyDiffCallback(private val oldData:List, private val newData:List): Callback(){ override fun getOldListSize(): Int { diff --git a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchtask/SwitchTaskView.kt b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchtask/SwitchTaskView.kt index 52bd1df5f9..22ee3b81a5 100644 --- a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchtask/SwitchTaskView.kt +++ b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/switchtask/SwitchTaskView.kt @@ -8,15 +8,17 @@ import androidx.lifecycle.findViewTreeViewModelStoreOwner import androidx.recyclerview.widget.GridLayoutManager import androidx.recyclerview.widget.LinearLayoutManager import com.mogo.eagle.core.utilcode.kotlin.onClick +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d import com.mogo.eagle.core.utilcode.util.ToastUtils import com.mogo.och.common.module.manager.loop.BizLoopManager import com.mogo.och.common.module.utils.ResourcesUtils import com.mogo.och.common.module.wigets.WindowRelativeLayout import com.mogo.och.shuttle.weaknet.R +import com.mogo.och.weaknet.model.LineModel import com.mogo.och.weaknet.repository.db.bean.LineDataBean import com.mogo.och.weaknet.repository.db.bean.TaskDataBean import com.mogo.och.weaknet.ui.bizswitch.SwtichBizeModel -import com.mogo.och.weaknet.ui.switchtask.SwitchLineTaskAdapter.TaskItemClickListener import kotlinx.android.synthetic.main.shuttle_weak_error_view.view.tv_error_msg import kotlinx.android.synthetic.main.shuttle_weak_switch_task.view.actvLineEndStationName import kotlinx.android.synthetic.main.shuttle_weak_switch_task.view.actv_cancle_task @@ -62,12 +64,6 @@ class SwitchTaskView: WindowRelativeLayout, SwtichTaskModel.SwtichLineViewCallba rv_switch_task.setLayoutManager(linearLayoutManager) mAdapter = SwitchLineTaskAdapter(context,null, mutableListOf()) rv_switch_task.setAdapter(mAdapter) - mAdapter.setOnLineItemClickListener(object : TaskItemClickListener{ - override fun onItemClick(position: Int, isCheck: Boolean) { - - } - }) - rv_switch_task.addItemDecoration( TaskBottomDecoration( AutoSizeUtils.dp2px(context, 174f) @@ -87,6 +83,7 @@ class SwitchTaskView: WindowRelativeLayout, SwtichTaskModel.SwtichLineViewCallba } tv_error_msg.onClick { viewModel?.tasksBelongLine?.let { + d(LineModel.TAG,"刷新线路 线路信息:${it}") viewbizModel?.loadingSwitchTask(it) } } @@ -105,6 +102,7 @@ class SwitchTaskView: WindowRelativeLayout, SwtichTaskModel.SwtichLineViewCallba } fun queryTaskByLineInfo(lineInfo: LineDataBean) { + d(LineModel.TAG, "queryTaskByLineInfo 查询线路的任务线路id:${lineInfo}") viewModel?.queryBusLineTasksById(lineInfo) busLineName.text = lineInfo.lineName actvLineEndStationName.text = "往${lineInfo.endStationName}方向" diff --git a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/taskrunning/TaskRunningAdapter.kt b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/taskrunning/TaskRunningAdapter.kt index d8af00fd85..c45a5c082c 100644 --- a/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/taskrunning/TaskRunningAdapter.kt +++ b/OCH/shuttle/driver_weaknet/src/main/java/com/mogo/och/weaknet/ui/taskrunning/TaskRunningAdapter.kt @@ -1,7 +1,9 @@ package com.mogo.och.weaknet.ui.taskrunning -import android.annotation.SuppressLint +import android.animation.ArgbEvaluator import android.content.Context +import android.graphics.Color +import android.graphics.drawable.GradientDrawable import android.util.TypedValue import android.view.LayoutInflater import android.view.View @@ -9,6 +11,7 @@ import android.view.ViewGroup import androidx.appcompat.widget.AppCompatImageView import androidx.appcompat.widget.AppCompatTextView import androidx.recyclerview.widget.RecyclerView +import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger import com.mogo.och.common.module.utils.ResourcesUtils import com.mogo.och.data.bean.BusStationBean import com.mogo.och.shuttle.weaknet.R @@ -28,12 +31,23 @@ class TaskRunningAdapter( } private var startStationIndex:Int = -1 + private val argbEvaluator: ArgbEvaluator = ArgbEvaluator() + private val startColor = ResourcesUtils.getColor(R.color.shuttle_driver_1970FF) + private val endColor = ResourcesUtils.getColor(R.color.shuttle_driver_19FF7F) + private val heightItem = 100f + private val halfHeight = 16.5f + private var totalHeight = 0f + fun setDataList(dataList: List, startStationIndex:Int) { this.startStationIndex = startStationIndex - val tempData = this.mData this.mData.clear() this.mData.addAll(dataList) - notifyDataSetChanged() + if(startStationIndex==0){ + totalHeight = 33 + (dataList.size-2)*heightItem + }else{ + totalHeight = (halfHeight+(dataList.size-1-startStationIndex)*heightItem).toFloat() + } + notifyItemRangeChanged(0,dataList.size,true) } override fun onCreateViewHolder( @@ -50,22 +64,28 @@ class TaskRunningAdapter( val currentPosition = holder.bindingAdapterPosition val line = mData[currentPosition] holder.actvStationName.text = line.name + if (startStationIndex>0) { + CallerLogger.d(TAG, "位置:$currentPosition 当前站${mData[startStationIndex]} ") + } if(currentPosition { holder.acivStationHeadBig.visibility = View.VISIBLE holder.acivStationHead.visibility = View.INVISIBLE holder.acivStationHeadBig.setImageResource(R.drawable.bus_runnint_task_end) + holder.bgPassBg.visibility = View.GONE + holder.bgPassBottomBg.visibility = View.GONE + holder.bgPassHeadBg.visibility = View.VISIBLE + if(startStationIndex==itemCount-1){ + if(line.isLeaving){ + holder.bgPassHeadBg.setBackgroundResource(R.color.shuttle_driver_4DFFFFFF) + holder.itemView.setBackgroundResource(R.drawable.bus_task_current_station_bg) + }else{ + holder.itemView.setBackgroundResource(R.drawable.bus_task_current_station_bg) + holder.bgPassHeadBg.setBackgroundResource(R.color.shuttle_driver_4DFFFFFF) + } + }else{ + // 上端 彩色 + holder.itemView.background = null + val startColorTemp = argbEvaluator.evaluate(((totalHeight-halfHeight)/totalHeight).toFloat(),startColor,endColor) as Int + val endColorTemp = argbEvaluator.evaluate(1f,startColor,endColor) as Int + val orientation = GradientDrawable.Orientation.TOP_BOTTOM + val temp01 = GradientDrawable(orientation, intArrayOf( + startColorTemp, + endColorTemp + )) + holder.bgPassHeadBg.background = temp01 + } } else -> { holder.acivStationHeadBig.visibility = View.GONE holder.acivStationHead.visibility = View.VISIBLE - holder.acivStationHead.setImageResource(R.drawable.bus_runnint_task_middle) + holder.bgPassBg.visibility = View.VISIBLE + holder.bgPassBottomBg.visibility = View.GONE + holder.bgPassHeadBg.visibility = View.GONE + if(currentPosition==startStationIndex){ + if(line.isLeaving){ + // 灰色 + holder.bgPassBg.setBackgroundResource(R.color.shuttle_driver_4DFFFFFF) + holder.itemView.background = null + }else{ + // 彩色 + holder.itemView.setBackgroundResource(R.drawable.bus_task_current_station_bg) + val startColorTemp = argbEvaluator.evaluate(0f,startColor,endColor) as Int + val endColorTemp = argbEvaluator.evaluate(100f/totalHeight,startColor,endColor) as Int + val orientation = GradientDrawable.Orientation.TOP_BOTTOM + val temp01 = GradientDrawable(orientation, intArrayOf( + startColorTemp, + endColorTemp + )) + holder.bgPassBg.background = temp01 + } + }else if(currentPosition + + + + + + + #BF1E2E89 #D4D4D4 #80FFFFFF + #4D000000 + #1970FF + #19FF7F \ No newline at end of file