[6.9.0]
[fea] [访客模式]
@@ -27,6 +27,12 @@
|
||||
<color name="common_B3000000">#B3000000</color>
|
||||
<color name="common_5F6582">#5F6582</color>
|
||||
<color name="common_A0B3DA">#A0B3DA</color>
|
||||
<color name="common_CCB9C3E9">#CCB9C3E9</color>
|
||||
<color name="common_4DFFFFFF">#4DFFFFFF</color>
|
||||
<color name="common_1970FF">#1970FF</color>
|
||||
<color name="common_19FF7F">#19FF7F</color>
|
||||
|
||||
<color name="common_2EACFF">#2EACFF</color>
|
||||
|
||||
<color name="common_3B4577">#3B4577</color>
|
||||
<color name="common_232A3F">#232A3F</color>
|
||||
@@ -39,4 +45,6 @@
|
||||
<color name="common_3B3D44">#3B3D44</color>
|
||||
<color name="common_2E323A">#2E323A</color>
|
||||
<color name="common_ffffffff">#ffffffff</color>
|
||||
|
||||
|
||||
</resources>
|
||||
@@ -62,9 +62,7 @@ abstract class BaseLineDb {
|
||||
needMinusDatas.forEach { minusLine->
|
||||
minusLine.lineId?.let { lineId->
|
||||
// 删除线路对应的站点
|
||||
|
||||
deleteSitesTaskAndContraiDb(lineId)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ android {
|
||||
useBuildCache = false
|
||||
arguments {
|
||||
arg("AROUTER_MODULE_NAME", "offline"+project.getName())
|
||||
arg("room.schemaLocation", "$projectDir/schemas".toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,6 +62,11 @@ dependencies {
|
||||
implementation rootProject.ext.dependencies.androidxrecyclerview
|
||||
compileOnly rootProject.ext.dependencies.recyclerviewadapterhelper
|
||||
|
||||
implementation rootProject.ext.dependencies.roomRxjava
|
||||
implementation rootProject.ext.dependencies.androidxroomruntime
|
||||
kapt rootProject.ext.dependencies.androidxroomcompiler
|
||||
|
||||
|
||||
implementation project(":OCH:common:common")
|
||||
implementation project(":OCH:common:data")
|
||||
compileOnly project(":libraries:mogo-map")
|
||||
|
||||
@@ -2,10 +2,7 @@
|
||||
package="com.mogo.och.offline">
|
||||
|
||||
<application>
|
||||
<activity android:name=".ui.BusSwitchLineActivity"
|
||||
android:theme="@style/SwitchLineDialogStyle"
|
||||
android:launchMode="singleTask"
|
||||
android:screenOrientation="landscape" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -6,11 +6,13 @@ import androidx.fragment.app.Fragment
|
||||
import com.alibaba.android.arouter.facade.annotation.Route
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
|
||||
import com.mogo.och.offline.fragment.ShuttleFragment
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_OFFLINE
|
||||
import com.mogo.och.common.module.constant.OchCommonConst
|
||||
import com.mogo.och.common.module.biz.provider.CommonServiceImpl
|
||||
import com.mogo.och.bridge.autopilot.autopilot.OchAutopilotAnalytics
|
||||
import com.mogo.och.bridge.ui.autopilot.AutopilotState
|
||||
import com.mogo.och.offline.ui.bizswitch.SwitchBizView
|
||||
import com.mogo.och.offline.ui.fragment.OfflineFragment
|
||||
import com.mogo.och.offline.util.BusAnalyticsManager
|
||||
import com.mogo.och.offline.util.OffLineTrajectoryManager
|
||||
|
||||
@@ -22,8 +24,8 @@ import com.mogo.och.offline.util.OffLineTrajectoryManager
|
||||
@Route(path = OchCommonConst.OFFLINE_DRIVER)
|
||||
class ShuttleDriverProvider : CommonServiceImpl() {
|
||||
|
||||
private val TAG = ShuttleDriverProvider::class.java.simpleName
|
||||
private var busFragment: ShuttleFragment?=null
|
||||
private val TAG = M_OFFLINE+ShuttleDriverProvider::class.java.simpleName
|
||||
private var busFragment: OfflineFragment?=null
|
||||
|
||||
override fun init(context: Context) {
|
||||
d(SceneConstant.M_TAXI + TAG, "init")
|
||||
@@ -31,7 +33,7 @@ class ShuttleDriverProvider : CommonServiceImpl() {
|
||||
|
||||
override fun getFragment(): Fragment {
|
||||
if(busFragment==null){
|
||||
busFragment = ShuttleFragment()
|
||||
busFragment = OfflineFragment()
|
||||
}
|
||||
OchAutopilotAnalytics.ochEventKey = BusAnalyticsManager.getInstance()
|
||||
OffLineTrajectoryManager.load()
|
||||
@@ -44,6 +46,13 @@ class ShuttleDriverProvider : CommonServiceImpl() {
|
||||
busFragment = null
|
||||
}
|
||||
|
||||
override fun createOchBusinessView(context: Context?): View? {
|
||||
d(TAG, "createOchBusinessView")
|
||||
return context?.let {
|
||||
SwitchBizView(it)
|
||||
}
|
||||
}
|
||||
|
||||
override fun createStartAutopilotView(context: Context?): View? {
|
||||
return context?.let {
|
||||
AutopilotState(it)
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
package com.mogo.och.offline.bean
|
||||
|
||||
import com.mogo.eagle.core.data.BaseData
|
||||
import com.mogo.och.data.bean.BusRoutesResult
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
data class BindLineListResponse(val data: List<Result>?) : BaseData(){
|
||||
|
||||
data class Result(
|
||||
var line: LineInfo?,
|
||||
var siteList: List<BusStationBean>?,//站点名称
|
||||
val contrail: Contrail?,//站点名称
|
||||
)
|
||||
|
||||
data class LineInfo(
|
||||
val lineId:Long?,
|
||||
var lineName:String?,
|
||||
)
|
||||
|
||||
data class Contrail(
|
||||
val csvFileUrl:String?,
|
||||
val csvFileMd5:String?,
|
||||
val txtFileUrl:String?,
|
||||
val txtFileMd5:String?,
|
||||
val contrailSaveTime:Long?,
|
||||
)
|
||||
companion object{
|
||||
@JvmStatic
|
||||
fun getCommonLineInfo(dataItem:Result):BusRoutesResult?{
|
||||
val result = BusRoutesResult()
|
||||
dataItem.siteList?.forEach {
|
||||
it.drivingStatus = 3
|
||||
}
|
||||
result.setSite(dataItem.siteList)
|
||||
result.csvFileUrl = dataItem.contrail?.csvFileUrl
|
||||
result.csvFileMd5 = dataItem.contrail?.csvFileMd5
|
||||
result.txtFileUrl = dataItem.contrail?.txtFileUrl
|
||||
result.txtFileMd5 = dataItem.contrail?.txtFileMd5
|
||||
result.contrailSaveTime = dataItem.contrail?.contrailSaveTime?:0
|
||||
result.name = dataItem.line?.lineName?:""
|
||||
result.lineId = dataItem.line?.lineId?.toInt()?:0
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
package com.mogo.och.offline.callback;
|
||||
|
||||
/**
|
||||
* Created on 2021/9/8
|
||||
*
|
||||
* Model->Presenter回调:ADAS相关(自动驾驶状态回调,到达终点等等)
|
||||
*/
|
||||
public interface IBusADASStatusCallback {
|
||||
//自驾返回失败
|
||||
void onStartAdasFailure();
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
package com.mogo.och.offline.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 IBusControllerStatusCallback {
|
||||
// 自车定位
|
||||
void onCarLocationChanged(MogoLocation location);
|
||||
//开始开启自动驾驶
|
||||
void startOpenAutopilot();
|
||||
}
|
||||
@@ -1,12 +1,30 @@
|
||||
package com.mogo.och.offline.callback;
|
||||
|
||||
import com.mogo.och.offline.bean.BindLineListResponse;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/9
|
||||
*/
|
||||
public interface IBusLinesCallback {
|
||||
void onBusLinesChange(BindLineListResponse lines);
|
||||
void onChangeLineIdSuccess(BindLineListResponse.Result checkLineInfo);
|
||||
|
||||
default void onChangeLineIdSuccess(){}
|
||||
|
||||
default void onRefreshSuccess(long currentTimeStamp){}
|
||||
|
||||
default void onRefreshSuccessWIthData(){}
|
||||
|
||||
default void onChangeLineIdFail(){}
|
||||
|
||||
default void onNoRunningTask(){}
|
||||
|
||||
default void onRunningTask(){}
|
||||
|
||||
default void onLeaveStaionSuccess(){}
|
||||
|
||||
default void onArriveStationSuccess(){}
|
||||
|
||||
default void onCompleteTask(){}
|
||||
|
||||
default void onCompleteTaskFail(){}
|
||||
|
||||
default void onEndTaskByOther(long taskId,String plateNumber){}
|
||||
}
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
package com.mogo.och.offline.callback;
|
||||
|
||||
import com.mogo.och.data.bean.BusStationBean;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2021/10/22
|
||||
*/
|
||||
public interface IRefreshBusStationsCallback {
|
||||
void updateBusTaskStatus(String lineName,String lintTime,
|
||||
List<BusStationBean> stationList,
|
||||
int arrivingOrArrivedIndex,
|
||||
boolean isArrived);
|
||||
|
||||
/**
|
||||
* 结束清理一遍、选择任务后清理一遍
|
||||
*/
|
||||
void clearBusStationsMarkers();
|
||||
|
||||
void updateEmptyUi();
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package com.mogo.och.offline.callback;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2021/10/22
|
||||
*/
|
||||
public interface ISlidePannelHideCallback {
|
||||
void hideSlidePanel();
|
||||
}
|
||||
@@ -36,6 +36,8 @@ class BusConst {
|
||||
//终点UUID
|
||||
const val BUS_END_MAP_MAKER = "bus_end_map_maker";
|
||||
|
||||
const val SEND_OUTVOICE_DISTANCES_TARTSTATIONE = 15
|
||||
|
||||
|
||||
/**
|
||||
* 订单起终点Marker类型
|
||||
|
||||
@@ -1,558 +0,0 @@
|
||||
package com.mogo.och.offline.fragment;
|
||||
|
||||
import static com.mogo.och.offline.constant.BusConst.TIMER_START_AUTOPILOT_INTERVAL;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.animation.LinearInterpolator;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.constraintlayout.widget.Group;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
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.data.config.HdMapBuildConfig;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager;
|
||||
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager;
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager;
|
||||
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.DriverMsgBoxListView;
|
||||
import com.mogo.eagle.core.function.smp.view.SmallMapView;
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils;
|
||||
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
import com.mogo.map.MogoMap;
|
||||
import com.mogo.map.uicontroller.IMogoMapUIController;
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils;
|
||||
import com.mogo.och.offline.R;
|
||||
import com.mogo.och.offline.model.OrderModel;
|
||||
import com.mogo.och.offline.view.BizMapView;
|
||||
import com.mogo.och.data.bean.BusRoutesResult;
|
||||
import com.mogo.och.offline.view.SlidePanelView;
|
||||
import com.mogo.och.common.module.utils.SoundPoolHelper;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
/**
|
||||
* 网约车基础Fragment,主要负责布局通用界面,处理站点面板和通话面板互斥情况
|
||||
* <p>
|
||||
* 部分业务放在了此处处理
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public abstract class BaseShuttleTabFragment<V extends IView, P extends Presenter<V>> extends MvpFragment<V, P> {
|
||||
|
||||
private static final String TAG = "BaseBusTabFragment";
|
||||
|
||||
protected SlidePanelView slidePanelView;
|
||||
private RelativeLayout ctvAutopilotStatus;
|
||||
private ImageView ctvAutopilotStatusIv;
|
||||
private TextView ctvAutopilotStatusTv;
|
||||
protected TextView tvArrived;
|
||||
private FrameLayout flStationPanelContainer;
|
||||
private BizMapView mapBizView;
|
||||
private Group groupTestPanel;
|
||||
|
||||
protected SmallMapView smallMapView;
|
||||
|
||||
//消息盒子
|
||||
private DriverMsgBoxButtonView viewDriverMsgBoxButton;
|
||||
private DriverMsgBoxListView viewDriverMsgBoxList;
|
||||
private DriverMsgBoxBubbleView viewDriverMsgBoxBubble;
|
||||
|
||||
private ObjectAnimator autopilotLoadingAnimator;
|
||||
|
||||
public boolean isAnimateRunning = false;
|
||||
|
||||
/**
|
||||
* 滑动按钮触发的事件
|
||||
*/
|
||||
private final SlidePanelView.OnSlidePanelMoveToEndListener onSlideToEndListener = () -> {
|
||||
// 此处做一个代理,处理一下共有情况
|
||||
if (getSlidePanelOnEndListener() != null) {
|
||||
getSlidePanelOnEndListener().moveToEnd();
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
protected int getLayoutId() {
|
||||
return R.layout.offline_base_fragment;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews() {
|
||||
mapBizView = findViewById(R.id.mapBizView);
|
||||
groupTestPanel = findViewById(R.id.groupTestPanel);
|
||||
slidePanelView = findViewById(R.id.module_mogo_och_slide_panel);
|
||||
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);
|
||||
|
||||
tvArrived = findViewById(R.id.module_mogo_och_arrived_tv);
|
||||
|
||||
FrameLayout flSpeed = findViewById(R.id.fl_speed);
|
||||
if (flSpeed != null) {
|
||||
CallerDevaToolsManager.INSTANCE.attachAutopilotBeforeLaunchView(flSpeed.getContext(), flSpeed);
|
||||
}
|
||||
|
||||
LayoutInflater.from(getContext()).inflate(getStationPanelViewId(), flStationPanelContainer);
|
||||
slidePanelView.setOnSlidePanelMoveToEndListener(onSlideToEndListener);
|
||||
|
||||
updateSwitchMapIcon();
|
||||
|
||||
initListener();
|
||||
setAutopilotBtnStatus(CallerAutoPilotStatusListenerManager.INSTANCE.getState(),
|
||||
CallerAutoPilotControlManager.INSTANCE.isCanStartAutopilot(false, 0));
|
||||
ctvAutopilotStatus.setOnClickListener(new OnPreventFastClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClickImpl(View v) {
|
||||
restartAutopilot();
|
||||
}
|
||||
});
|
||||
|
||||
// 模拟 不可自动驾驶,目前场景是刚开机,adas还未和工控机连接
|
||||
findViewById(R.id.btnAutopilotDisable).setOnClickListener(view ->
|
||||
debugAutoPilotStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE)
|
||||
);
|
||||
|
||||
// 模拟 可自动驾驶,工控机连接正常,且处于人工干预状态
|
||||
findViewById(R.id.btnAutopilotEnable).setOnClickListener(view ->
|
||||
debugAutoPilotStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE)
|
||||
);
|
||||
|
||||
// 模拟 自动驾驶能力,自动驾驶中,可能是停车,可能是行进,但是是机器在处理车的前进后退,不是人
|
||||
findViewById(R.id.btnAutopilotRunning).setOnClickListener(view ->
|
||||
debugAutoPilotStatus(IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING)
|
||||
);
|
||||
|
||||
findViewById(R.id.btnAutopilotPingxing).setOnClickListener(view ->
|
||||
debugAutoPilotStatus(IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING)
|
||||
);
|
||||
|
||||
// 模拟 自动驾驶网约车回调数据
|
||||
findViewById(R.id.btnAutopilotArrive).setOnClickListener(view ->
|
||||
debugArrivedStation()
|
||||
);
|
||||
|
||||
tvArrived.setOnClickListener(view -> {
|
||||
onArriveStation();
|
||||
});
|
||||
|
||||
//消息盒子
|
||||
viewDriverMsgBoxButton = findViewById(R.id.viewDriverMsgBoxButton);
|
||||
viewDriverMsgBoxList = findViewById(R.id.viewDriverMsgBoxList);
|
||||
viewDriverMsgBoxBubble = findViewById(R.id.viewDriverMsgBoxBubble);
|
||||
viewDriverMsgBoxButton.setClickListener(show -> {
|
||||
if(show){
|
||||
viewDriverMsgBoxList.setVisibility(View.VISIBLE);
|
||||
viewDriverMsgBoxList.notifyData();
|
||||
viewDriverMsgBoxBubble.setVisibility(View.GONE);
|
||||
viewDriverMsgBoxBubble.isShowData(false);
|
||||
}else{
|
||||
viewDriverMsgBoxList.setVisibility(View.GONE);
|
||||
viewDriverMsgBoxBubble.setVisibility(View.VISIBLE);
|
||||
viewDriverMsgBoxBubble.isShowData(true);
|
||||
}
|
||||
});
|
||||
|
||||
smallMapView = findViewById(R.id.smallMapView);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews(Bundle savedInstanceState) {
|
||||
super.initViews(savedInstanceState);
|
||||
mapBizView.onCreate(savedInstanceState);
|
||||
smallMapView.onCreateView(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
mapBizView.onResume();
|
||||
smallMapView.onResume();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container
|
||||
, @Nullable Bundle savedInstanceState) {
|
||||
EventBus.getDefault().register(this);
|
||||
return super.onCreateView(inflater, container, savedInstanceState);
|
||||
}
|
||||
|
||||
protected abstract void onArriveStation();
|
||||
|
||||
private void updateSwitchMapIcon() {
|
||||
|
||||
IMogoMapUIController mapUIController = CallerMapUIServiceManager.INSTANCE.getMapUIController(MogoMap.DEFAULT);
|
||||
if(mapUIController!=null){
|
||||
if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
|
||||
mapUIController.changeCurrentIcon(R.raw.m2);
|
||||
HdMapBuildConfig.currentCarVrIconRes = R.raw.m2;
|
||||
}else if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
|
||||
mapUIController.changeCurrentIcon(R.raw.xiaoba);
|
||||
HdMapBuildConfig.currentCarVrIconRes = R.raw.xiaoba;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(@NonNull Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
mapBizView.onSaveInstanceState(outState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLowMemory() {
|
||||
super.onLowMemory();
|
||||
mapBizView.onLowMemory();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
super.onPause();
|
||||
mapBizView.onPause();
|
||||
smallMapView.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
mapBizView.onDestroy();
|
||||
if(smallMapView != null){
|
||||
smallMapView.onDestroy();
|
||||
}
|
||||
super.onDestroyView();
|
||||
CallerAutopilotRecordListenerManager.INSTANCE.removeListener(TAG);
|
||||
EventBus.getDefault().unregister(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试到站
|
||||
*/
|
||||
protected abstract void debugArrivedStation();
|
||||
|
||||
private void initListener() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示滑动按钮
|
||||
*
|
||||
* @param text 指定的文字
|
||||
*/
|
||||
public void showSlidePanel(String text) {
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
slidePanelView.setText(text);
|
||||
slidePanelView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
setArrivedClikable(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置进站按钮状态
|
||||
*
|
||||
* @param isClickable
|
||||
*/
|
||||
public void setArrivedClikable(boolean isClickable) {
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
tvArrived.setEnabled(isClickable);
|
||||
if (isClickable) {
|
||||
tvArrived.setTextColor(ContextCompat.getColor(AbsMogoApplication.getApp(),R.color.bus_white));
|
||||
} else {
|
||||
tvArrived.setTextColor(ContextCompat.getColor(AbsMogoApplication.getApp(),R.color.bus_arrived_btn_un_clickable_color));
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏滑动按钮
|
||||
*/
|
||||
public void hideSlidePanel() {
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
slidePanelView.setVisibility(View.GONE);
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
|
||||
public void playDI() {
|
||||
SoundPoolHelper.getSoundPoolHelper().playSoundWithRedId(getContext(), R.raw.bus_di);
|
||||
}
|
||||
|
||||
/**
|
||||
* 改变自动驾驶状态
|
||||
*
|
||||
* @param autopilotStatus 0:不可用 1:可用状态 2:自动驾驶中
|
||||
*/
|
||||
public void onAutopilotStatusChanged(int autopilotStatus,boolean canStartAuto) {
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
changeAutopilotBtnView(autopilotStatus, isAnimateRunning,canStartAuto);
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
|
||||
public void setAutopilotBtnStatus(int autopilotStatus,boolean canStartAuto) {
|
||||
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE == autopilotStatus) {//0不可用
|
||||
ctvAutopilotStatusTv.setTextColor(ResourcesUtils.getColor(R.color.bus_autopilot_text_color_disable));
|
||||
ctvAutopilotStatusTv.setText(ResourcesUtils.getString(R.string.bus_loading_autopilot_runnig_tv));
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.bus_disable_autopilot_icon);
|
||||
ctvAutopilotStatus.setClickable(true);
|
||||
ctvAutopilotStatus.setBackgroundResource(R.drawable.common_autopilot_start_fail);
|
||||
} else {
|
||||
ctvAutopilotStatusTv.setTextColor(AbsMogoApplication.getApp().getColor(R.color.bus_autopilot_text_color_normal));
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.bus_ic_autopilot);
|
||||
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE == autopilotStatus) { //1可用
|
||||
ctvAutopilotStatusTv.setText(ResourcesUtils.getString(R.string.bus_loading_autopilot_runnig_tv));
|
||||
if(canStartAuto){
|
||||
ctvAutopilotStatus.setClickable(true);
|
||||
ctvAutopilotStatus.setBackgroundResource(R.drawable.common_autopilot_press);
|
||||
}else {
|
||||
ctvAutopilotStatusTv.setTextColor(ResourcesUtils.getColor(R.color.bus_autopilot_text_color_disable));
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.bus_disable_autopilot_icon);
|
||||
ctvAutopilotStatus.setClickable(true);
|
||||
ctvAutopilotStatus.setBackgroundResource(R.drawable.common_autopilot_start_fail);
|
||||
}
|
||||
} else if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING == autopilotStatus) {
|
||||
ctvAutopilotStatusTv.setText(R.string.bus_loading_autopilot_runnig_tv);
|
||||
ctvAutopilotStatus.setClickable(true);
|
||||
ctvAutopilotStatus.setBackgroundResource(R.drawable.common_autopilot_in_autopilot);
|
||||
} else if (IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING
|
||||
== autopilotStatus){
|
||||
ctvAutopilotStatusTv.setText(R.string.bus_pingxing_driver);
|
||||
ctvAutopilotStatus.setClickable(false);
|
||||
ctvAutopilotStatus.setBackgroundResource(R.drawable.common_autopilot_pxjs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void updateAutopilotStatus(int autopilotStatus) {
|
||||
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
|
||||
== autopilotStatus) {//2 running
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.bus_right_autopilot_icon);
|
||||
ctvAutopilotStatusTv.setTextColor(ResourcesUtils.getColor(R.color.bus_autopilot_text_color_normal));
|
||||
ctvAutopilotStatusTv.setText(ResourcesUtils.getString(R.string.bus_loading_autopilot_success_tv));
|
||||
// ctvAutopilotStatus.setSelected(false);
|
||||
ctvAutopilotStatus.setClickable(false);
|
||||
} else {
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.bus_wrong_autopilot_icon);
|
||||
ctvAutopilotStatusTv.setTextColor(ResourcesUtils.getColor(R.color.bus_autopilot_text_color_normal));
|
||||
ctvAutopilotStatusTv.setText(ResourcesUtils.getString(R.string.bus_loading_autopilot_failure_tv));
|
||||
ctvAutopilotStatus.setClickable(false);
|
||||
// ctvAutopilotStatus.setSelected(false);
|
||||
}
|
||||
UiThreadHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setAutopilotBtnStatus(autopilotStatus,CallerAutoPilotControlManager.INSTANCE.isCanStartAutopilot(false, 0));
|
||||
}
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
private void changeAutopilotBtnView(int autopilotStatus, boolean isAnimateRunning,boolean canStartAuto) {
|
||||
if (isAnimateRunning && IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
|
||||
!= autopilotStatus) {
|
||||
// 主动开启自动驾驶中,不为2(为0、1)则继续loading
|
||||
return;
|
||||
}
|
||||
if (isAnimateRunning) {
|
||||
stopAnimAndUpdateBtnStatus();
|
||||
} else {
|
||||
setAutopilotBtnStatus(autopilotStatus,canStartAuto);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void stopAnimAndUpdateBtnStatus() {
|
||||
stopAutopilotAnimation();
|
||||
updateAutopilotStatus(CallerAutoPilotStatusListenerManager.INSTANCE.getState());
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏【自动驾驶】按钮
|
||||
*/
|
||||
public void hideAutopilotBiz() {
|
||||
}
|
||||
|
||||
/**
|
||||
* 展示【自动驾驶】按钮
|
||||
*/
|
||||
public void showAutopilotBiz() {
|
||||
}
|
||||
|
||||
public SlidePanelView.OnSlidePanelMoveToEndListener getSlidePanelOnEndListener() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取站点面板view,在{@link #initViews()}时候添加到container中
|
||||
*
|
||||
* @return 站点面板view
|
||||
*/
|
||||
public abstract int getStationPanelViewId();
|
||||
|
||||
/**
|
||||
* 重新开启自动驾驶
|
||||
*/
|
||||
public abstract void restartAutopilot();
|
||||
|
||||
/**
|
||||
* 模拟自动驾驶返回状态
|
||||
*
|
||||
* @param status
|
||||
*/
|
||||
public abstract void debugAutoPilotStatus(int status);
|
||||
|
||||
/**
|
||||
* 开启自动驾驶中间动画
|
||||
*/
|
||||
public void startAutopilotAnimation() {
|
||||
isAnimateRunning = true;
|
||||
ctvAutopilotStatusTv.setText(ResourcesUtils.getString(R.string.bus_loading_autopilot_tv));
|
||||
ctvAutopilotStatusTv.setTextColor(ResourcesUtils.getColor(R.color.bus_autopilot_text_color_normal));
|
||||
ctvAutopilotStatus.setClickable(true);
|
||||
ctvAutopilotStatusIv.setImageResource(R.drawable.bus_loading_autopilot_icon);
|
||||
if (autopilotLoadingAnimator == null) {
|
||||
autopilotLoadingAnimator = ObjectAnimator.ofFloat(ctvAutopilotStatusIv, "rotation", 0f, 360f);
|
||||
autopilotLoadingAnimator.setInterpolator(new LinearInterpolator());
|
||||
autopilotLoadingAnimator.setRepeatCount(-1);//无限循环
|
||||
autopilotLoadingAnimator.setDuration(1000);//设置持续时间
|
||||
}
|
||||
autopilotLoadingAnimator.start();//动画开始
|
||||
|
||||
startingAutoApilotCountDown();
|
||||
|
||||
}
|
||||
|
||||
private void startingAutoApilotCountDown() {
|
||||
//10s 若自动驾驶没有开启,则结束动画
|
||||
UiThreadHandler.postDelayed(new Runnable() {
|
||||
@Override
|
||||
public void run() { //未启动成功做处理
|
||||
if (isAnimateRunning) {// 只判断动画是否在进行,根据自动驾驶当前状态去设置自动驾驶状态
|
||||
stopAutopilotAnimation();
|
||||
updateAutopilotStatus(CallerAutoPilotStatusListenerManager.INSTANCE.getState());
|
||||
}
|
||||
}
|
||||
}, TIMER_START_AUTOPILOT_INTERVAL);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止自动驾驶中间动画
|
||||
*/
|
||||
protected void stopAutopilotAnimation() {
|
||||
if (autopilotLoadingAnimator != null) {
|
||||
autopilotLoadingAnimator.end();
|
||||
ctvAutopilotStatusIv.clearAnimation();
|
||||
autopilotLoadingAnimator = null;
|
||||
isAnimateRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
// /**
|
||||
// * 迈速表实时更新
|
||||
// *
|
||||
// * @param newSpeed
|
||||
// */
|
||||
// public void updateSpeedView(float newSpeed) {
|
||||
// int speed = (int) (Math.abs(newSpeed) * 3.6F); // 倒车时工控机反馈定位信息中speed为负值
|
||||
// if (mTrafficDataView != null) {
|
||||
// mTrafficDataView.updateSpeedWithValue(speed);
|
||||
// }
|
||||
// }
|
||||
|
||||
@Override
|
||||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
/**
|
||||
* bus调试面板打开关闭
|
||||
*/
|
||||
public void debugTestBar() {
|
||||
if (groupTestPanel.getVisibility() == View.VISIBLE) {
|
||||
groupTestPanel.setVisibility(View.GONE);
|
||||
} else {
|
||||
groupTestPanel.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Bus调试信息:线路、轨迹等信息
|
||||
* <p>
|
||||
* START
|
||||
*/
|
||||
private View busTestBar;
|
||||
private TextView lineIdTV;
|
||||
private TextView lineNameTV;
|
||||
private TextView trajMd5TV;
|
||||
private TextView stopMd5TV;
|
||||
private TextView trajMd5DPQPTV;
|
||||
private TextView stopMd5DPQPTV;
|
||||
|
||||
public void showHideTestBar() {
|
||||
if (busTestBar == null) {
|
||||
busTestBar = findViewById(R.id.module_mogo_och_bus_test_bar);
|
||||
lineIdTV = findViewById(R.id.bus_test_bar_current_line_id);
|
||||
lineNameTV = findViewById(R.id.bus_test_bar_current_line_name);
|
||||
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.getVisibility() == View.VISIBLE) {
|
||||
busTestBar.setVisibility(View.GONE);
|
||||
} else {
|
||||
BusRoutesResult routesResult = OrderModel.getInstance().getBusRoutesResult();
|
||||
lineIdTV.setText("lineId:" + (routesResult == null ? "" : String.valueOf(routesResult.getLineId())));
|
||||
lineNameTV.setText("lineName:" + (routesResult == null ? "" : routesResult.getName()));
|
||||
trajMd5TV.setText("TMd5:" + (routesResult == null ? "" : routesResult.csvFileMd5));
|
||||
stopMd5TV.setText("SMd5:" + (routesResult == null ? "" : routesResult.txtFileMd5));
|
||||
trajMd5DPQPTV.setText("TMd5DPQP:" + (routesResult == null ? "" : routesResult.csvFileMd5DPQP));
|
||||
stopMd5DPQPTV.setText("SMd5DPQP:" + (routesResult == null ? "" : routesResult.txtFileMd5DPQP));
|
||||
busTestBar.setVisibility(View.VISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
public void updateBusTestBarInfo() {
|
||||
if (busTestBar != null && busTestBar.getVisibility() == View.VISIBLE) {
|
||||
BusRoutesResult routesResult = OrderModel.getInstance().getBusRoutesResult();
|
||||
lineIdTV.setText("lineId:" + (routesResult == null ? "" : String.valueOf(routesResult.getLineId())));
|
||||
lineNameTV.setText("lineName:" + (routesResult == null ? "" : routesResult.getName()));
|
||||
trajMd5TV.setText("TMd5:" + (routesResult == null ? "" : routesResult.csvFileMd5));
|
||||
stopMd5TV.setText("SMd5:" + (routesResult == null ? "" : routesResult.txtFileMd5));
|
||||
trajMd5DPQPTV.setText("TMd5DPQP:" + (routesResult == null ? "" : routesResult.csvFileMd5DPQP));
|
||||
stopMd5DPQPTV.setText("SMd5DPQP:" + (routesResult == null ? "" : routesResult.txtFileMd5DPQP));
|
||||
}
|
||||
}
|
||||
/**
|
||||
* END
|
||||
*/
|
||||
}
|
||||
@@ -1,554 +0,0 @@
|
||||
package com.mogo.och.offline.fragment;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
|
||||
import static com.mogo.map.MogoMap.DEFAULT;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.constraintlayout.widget.Group;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.commons.storage.SharedPrefsMgr;
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
|
||||
import com.mogo.eagle.core.data.temp.EventLogout;
|
||||
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
|
||||
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant;
|
||||
import com.mogo.eagle.core.utilcode.util.ActivityUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.ImageUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
import com.mogo.map.overlay.IMoGoOverlayManager;
|
||||
import com.mogo.map.overlay.core.Level;
|
||||
import com.mogo.map.overlay.point.Point;
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils;
|
||||
import com.mogo.och.offline.R;
|
||||
import com.mogo.och.offline.presenter.BusPresenter;
|
||||
import com.mogo.och.offline.ui.BusStationCommonItem;
|
||||
import com.mogo.och.offline.ui.BusSwitchLineActivity;
|
||||
import com.mogo.och.data.bean.BusStationBean;
|
||||
import com.mogo.och.offline.constant.BusConst;
|
||||
import com.mogo.och.offline.view.SlidePanelView;
|
||||
import com.mogo.och.common.module.utils.BlinkAnimationUtil;
|
||||
import com.mogo.och.common.module.utils.OCHThreadPoolManager;
|
||||
import com.mogo.och.common.module.utils.QRUtilsKt;
|
||||
import com.mogo.och.common.module.wigets.BindQRCodeDialog;
|
||||
import com.mogo.och.common.module.wigets.MarqueeTextView;
|
||||
import com.mogo.och.common.module.wigets.OCHCommitDialog;
|
||||
import com.mogo.skin.utils.SkinResources;
|
||||
|
||||
import org.greenrobot.eventbus.Subscribe;
|
||||
import org.greenrobot.eventbus.ThreadMode;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils;
|
||||
|
||||
|
||||
/**
|
||||
* 网约车小巴界面
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class ShuttleFragment extends BaseShuttleTabFragment<ShuttleFragment, BusPresenter>
|
||||
implements SlidePanelView.OnSlidePanelMoveToEndListener, View.OnClickListener {
|
||||
public static final String TAG = "BusFragment";
|
||||
|
||||
private TextView mSwitchLine; //切换路线
|
||||
private MarqueeTextView mLineName;
|
||||
private TextView mTaskTime;
|
||||
private Group groupStationsPanel;
|
||||
private ConstraintLayout noDataView;
|
||||
|
||||
private BusStationBean startStation = null;
|
||||
private BusStationBean endStation = null;
|
||||
private BusStationCommonItem firstStationItem;
|
||||
private BusStationCommonItem secondStationItem;
|
||||
private BusStationCommonItem thirdStationItem;
|
||||
|
||||
|
||||
@Override
|
||||
public String getTagName() {
|
||||
return "BusFragment";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
}
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
if (mPresenter != null) {
|
||||
mPresenter.onDestroy(this);
|
||||
}
|
||||
super.onDestroyView();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initViews() {
|
||||
super.initViews();
|
||||
|
||||
mSwitchLine = findViewById(R.id.switch_line_btn);
|
||||
mSwitchLine.setTag(0);
|
||||
mLineName = findViewById(R.id.module_och_bus_line_name);
|
||||
|
||||
firstStationItem = findViewById(R.id.bus_panel_first_station);
|
||||
secondStationItem = findViewById(R.id.bus_panel_second_station);
|
||||
thirdStationItem = findViewById(R.id.bus_panel_third_station);
|
||||
mTaskTime = findViewById(R.id.bus_task_time_tv);
|
||||
groupStationsPanel = findViewById(R.id.group_stations_panel);
|
||||
noDataView = findViewById(R.id.no_line_data_view);
|
||||
|
||||
CallerLogger.d(M_BUS + TAG, "initView: " + CallerAutoPilotStatusListenerManager.INSTANCE.getState());
|
||||
// 初始化的时候设置 UI 按钮状态
|
||||
showAutopilotBiz();
|
||||
|
||||
mSwitchLine.setOnClickListener(this);
|
||||
|
||||
mLineName.setOnLongClickListener(new View.OnLongClickListener() {
|
||||
@Override
|
||||
public boolean onLongClick(View v) {
|
||||
showHideTestBar();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
public void changeOverview(EventLogout eventLogout){
|
||||
if (eventLogout.getMessgae() == EventLogout.LOGOUT_TYPE){
|
||||
CallerLogger.d(M_BUS + TAG,"changeOverview Event消息去登出");
|
||||
mPresenter.logout();
|
||||
}else if (eventLogout.getMessgae() == EventLogout.SHOW_QR_TYPE){ //显示二维码
|
||||
CallerLogger.d(M_BUS + TAG,"changeOverview Event qrcode,sn = "
|
||||
+ SharedPrefsMgr.getInstance().getSn());
|
||||
String qrUrl = String.format(FunctionBuildConfig.urlJson.getBindDriverQRUrl(),
|
||||
SharedPrefsMgr.getInstance().getSn());
|
||||
|
||||
Drawable qrCenterLogoDrawable =
|
||||
SkinResources.getInstance().getDrawable(R.drawable.icon_qr_center_logo);
|
||||
Bitmap qrCenterLogoBitmap = ImageUtils.drawable2Bitmap(qrCenterLogoDrawable);
|
||||
|
||||
Bitmap bmQr = QRUtilsKt.createQRCodeWithPicture(
|
||||
qrCenterLogoBitmap
|
||||
,qrUrl, AutoSizeUtils.dp2px(getContext(),340f),
|
||||
AutoSizeUtils.dp2px(getContext(),340f),true);
|
||||
if (bmQr != null){
|
||||
BindQRCodeDialog.Builder builder = new BindQRCodeDialog.Builder();
|
||||
builder.title(getString(R.string.bind_driver_qr_title))
|
||||
.cancelStr(getString(R.string.qr_cancel))
|
||||
.qrBm(bmQr).build(getContext()).show();
|
||||
}else {
|
||||
CallerLogger.d(M_BUS + TAG,"bmQr = null ");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onArriveStation() {
|
||||
mPresenter.onAutopilotArriveAtStation(null);
|
||||
mPresenter.arriveStation(null,"点击进站触发进站操作");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void debugArrivedStation() {
|
||||
mPresenter.onAutopilotArriveAtStation(null);
|
||||
mPresenter.arriveStation(null,"点击debug进站按钮触发进站操作");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
protected BusPresenter createPresenter() {
|
||||
return new BusPresenter(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
}
|
||||
|
||||
public void hideStationsPanel(){
|
||||
groupStationsPanel.setVisibility(View.GONE);
|
||||
noDataView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
public void showStationsPanel(){
|
||||
groupStationsPanel.setVisibility(View.VISIBLE);
|
||||
noDataView.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
public void updateLineEmptyUI(){
|
||||
setArrivedClikable(false);
|
||||
showOrHideSwitchLineBtn(true);
|
||||
hideStationsPanel();
|
||||
hideSlidePanel();
|
||||
resetStationBlinkAnim();
|
||||
}
|
||||
|
||||
private void resetStationBlinkAnim() {
|
||||
BlinkAnimationUtil.clearAnimation(firstStationItem.getCircleImageView());
|
||||
BlinkAnimationUtil.clearAnimation(secondStationItem.getCircleImageView());
|
||||
BlinkAnimationUtil.clearAnimation(thirdStationItem.getCircleImageView());
|
||||
}
|
||||
|
||||
public void updateBusTaskStatus(String lineName, String lineTime,
|
||||
List<BusStationBean> stationList,
|
||||
int arrivingOrArrivedIndex,
|
||||
boolean isArrived){
|
||||
|
||||
if (getActivity() == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (stationList == null) {
|
||||
// 获取小巴数据失败
|
||||
return;
|
||||
}
|
||||
|
||||
showStationsPanel();
|
||||
showOrHideSwitchLineBtn(false);
|
||||
|
||||
mLineName.setText(lineName);
|
||||
mTaskTime.setText(getString(R.string.bus_line_time_tag)+ lineTime);
|
||||
// 渲染小巴路线数据
|
||||
updateBusStationStatus(stationList,arrivingOrArrivedIndex,isArrived);
|
||||
}
|
||||
},UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
|
||||
private void updateBusStationStatus(List<BusStationBean> stationList,
|
||||
int arrivingOrArrivedIndex,
|
||||
boolean isArrived) {
|
||||
|
||||
startStation = stationList.get(0);
|
||||
endStation = stationList.get(stationList.size() - 1);
|
||||
|
||||
if (arrivingOrArrivedIndex == stationList.size() - 1 && isArrived){
|
||||
//切换路线和结束路线按钮切换
|
||||
showSlidePanel("单程结束");
|
||||
|
||||
setOrRemoveMapMaker(false, BusConst.BUS_END_MAP_MAKER, endStation.getLat()
|
||||
, endStation.getLon(),R.raw.end_marker);
|
||||
}else if (arrivingOrArrivedIndex == 0 && isArrived){
|
||||
|
||||
showSlidePanel("滑动出发");
|
||||
|
||||
setOrRemoveMapMaker(true, BusConst.BUS_START_MAP_MAKER,
|
||||
startStation.getLat(), startStation.getLon(),R.raw.star_marker);
|
||||
setOrRemoveMapMaker(true, BusConst.BUS_END_MAP_MAKER,
|
||||
endStation.getLat(), endStation.getLon(),R.raw.end_marker);
|
||||
}else{
|
||||
if (isArrived){
|
||||
// 重置滑动按钮文字
|
||||
showSlidePanel("滑动出发");
|
||||
}
|
||||
|
||||
setOrRemoveMapMaker(false, BusConst.BUS_START_MAP_MAKER, startStation.getLat()
|
||||
, startStation.getLon(),R.raw.star_marker);
|
||||
setOrRemoveMapMaker(true, BusConst.BUS_END_MAP_MAKER, endStation.getLat()
|
||||
, endStation.getLon(),R.raw.end_marker);
|
||||
}
|
||||
|
||||
if (stationList.size() > 2){ //只有两个站点
|
||||
updateMoreThanTwoStationsUI(stationList,arrivingOrArrivedIndex,isArrived);
|
||||
}else {
|
||||
updateTwoStationsUI(stationList,arrivingOrArrivedIndex,isArrived);
|
||||
}
|
||||
|
||||
updateBusTestBarInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* 有两个以上站点的路线
|
||||
* @param stationList
|
||||
* @param arrivingOrArrivedIndex
|
||||
* @param isArrived
|
||||
*/
|
||||
private void updateMoreThanTwoStationsUI(List<BusStationBean> stationList,
|
||||
int arrivingOrArrivedIndex,
|
||||
boolean isArrived) {
|
||||
secondStationItem.setStationTag("");
|
||||
secondStationItem.showOrHideStationArrowBg(true);
|
||||
thirdStationItem.setStationTag("");
|
||||
secondStationItem.setVisibility(View.VISIBLE);
|
||||
thirdStationItem.showOrHideStationArrowBg(false);
|
||||
|
||||
if (arrivingOrArrivedIndex == 0 || arrivingOrArrivedIndex -1 == 0
|
||||
|| (arrivingOrArrivedIndex -2 == 0 && stationList.size() == 3)){
|
||||
firstStationItem.setStationTag(ResourcesUtils.getString(R.string.bus_station_txt_tag_start));
|
||||
}else {
|
||||
firstStationItem.setStationTag("");
|
||||
}
|
||||
|
||||
if (arrivingOrArrivedIndex + 1 == stationList.size() - 1 || arrivingOrArrivedIndex == stationList.size() - 1
|
||||
|| (arrivingOrArrivedIndex == 0 && arrivingOrArrivedIndex + 2 == stationList.size() - 1)){ //确认是否显示 "终"
|
||||
thirdStationItem.setStationTag(ResourcesUtils.getString(R.string.bus_station_txt_tag_end));
|
||||
}else {
|
||||
thirdStationItem.setStationTag("");
|
||||
}
|
||||
|
||||
//圆点: 0:灰色 过站 1:绿色 到站或者即将到站 2:蓝色:未到站
|
||||
if (arrivingOrArrivedIndex == 0 && isArrived){
|
||||
firstStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_line_station_color_selected));
|
||||
secondStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_arrived_station_name_text_color));
|
||||
thirdStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_arrived_station_name_text_color));
|
||||
|
||||
firstStationItem.setStationName(stationList.get(0).getName());
|
||||
secondStationItem.setStationName(stationList.get(1).getName());
|
||||
thirdStationItem.setStationName(stationList.get(2).getName());
|
||||
|
||||
firstStationItem.setStationPointBg(1);
|
||||
secondStationItem.setStationPointBg(2);
|
||||
thirdStationItem.setStationPointBg(2);
|
||||
|
||||
firstStationItem.setStationArrowBg(2);
|
||||
secondStationItem.setStationArrowBg(2);
|
||||
|
||||
}else if (arrivingOrArrivedIndex == stationList.size() - 1){
|
||||
firstStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_station_tag_txt_un_color));
|
||||
secondStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_station_tag_txt_un_color));
|
||||
thirdStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_line_station_color_selected));
|
||||
|
||||
firstStationItem.setStationName(stationList.get(arrivingOrArrivedIndex -2).getName());
|
||||
secondStationItem.setStationName(stationList.get(arrivingOrArrivedIndex -1).getName());
|
||||
thirdStationItem.setStationName(stationList.get(arrivingOrArrivedIndex).getName());
|
||||
|
||||
firstStationItem.setStationPointBg(0);
|
||||
secondStationItem.setStationPointBg(0);
|
||||
thirdStationItem.setStationPointBg(1);
|
||||
|
||||
firstStationItem.setStationArrowBg(0);
|
||||
if (isArrived){
|
||||
secondStationItem.setStationArrowBg(0);
|
||||
}else {
|
||||
secondStationItem.setStationArrowBg(1);
|
||||
}
|
||||
|
||||
}else {
|
||||
firstStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_station_tag_txt_un_color));
|
||||
secondStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_line_station_color_selected));
|
||||
thirdStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_arrived_station_name_text_color));
|
||||
|
||||
firstStationItem.setStationName(stationList.get(arrivingOrArrivedIndex -1).getName());
|
||||
secondStationItem.setStationName(stationList.get(arrivingOrArrivedIndex).getName());
|
||||
thirdStationItem.setStationName(stationList.get(arrivingOrArrivedIndex + 1).getName());
|
||||
|
||||
firstStationItem.setStationPointBg(0);
|
||||
secondStationItem.setStationPointBg(1);
|
||||
thirdStationItem.setStationPointBg(2);
|
||||
|
||||
secondStationItem.setStationArrowBg(2);
|
||||
if (isArrived){
|
||||
firstStationItem.setStationArrowBg(0);
|
||||
}else {
|
||||
firstStationItem.setStationArrowBg(1);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 只有两个站点的路线
|
||||
* @param stationList
|
||||
* @param arrivingOrArrivedIndex
|
||||
* @param isArrived
|
||||
*/
|
||||
private void updateTwoStationsUI(List<BusStationBean> stationList,
|
||||
int arrivingOrArrivedIndex,
|
||||
boolean isArrived) {
|
||||
|
||||
secondStationItem.setVisibility(View.GONE);
|
||||
secondStationItem.showOrHideStationArrowBg(false);
|
||||
thirdStationItem.showOrHideStationArrowBg(false);
|
||||
|
||||
firstStationItem.setStationTag(ResourcesUtils.getString(R.string.bus_station_txt_tag_start));
|
||||
thirdStationItem.setStationTag(ResourcesUtils.getString(R.string.bus_station_txt_tag_end));
|
||||
|
||||
firstStationItem.setStationName(stationList.get(0).getName());
|
||||
thirdStationItem.setStationName(stationList.get(1).getName());
|
||||
|
||||
//圆点: 0:灰色 过站 1:绿色 到站或者即将到站 2:蓝色:未到站
|
||||
if (arrivingOrArrivedIndex == 0 && isArrived){//到站
|
||||
firstStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_line_station_color_selected));
|
||||
thirdStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_arrived_station_name_text_color));
|
||||
firstStationItem.setStationPointBg(1);
|
||||
firstStationItem.setStationArrowBg(2);
|
||||
thirdStationItem.setStationPointBg(0);
|
||||
|
||||
}else {
|
||||
firstStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_station_tag_txt_un_color));
|
||||
thirdStationItem.setStationNameColor(ResourcesUtils.getColor(R.color.bus_line_station_color_selected));
|
||||
if (isArrived){ //到终点
|
||||
firstStationItem.setStationPointBg(0);
|
||||
firstStationItem.setStationArrowBg(0);
|
||||
thirdStationItem.setStationPointBg(1);
|
||||
|
||||
}else { //到终点途中
|
||||
firstStationItem.setStationPointBg(0);
|
||||
firstStationItem.setStationArrowBg(1);
|
||||
thirdStationItem.setStationPointBg(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void showOrHideSwitchLineBtn(boolean isShow) {
|
||||
if (isShow){//显示切换路线
|
||||
mSwitchLine.setTag(0);
|
||||
mSwitchLine.setText(ResourcesUtils.getString(R.string.bus_switch_line_btn));
|
||||
}else {//显示结束路线
|
||||
mSwitchLine.setTag(1);
|
||||
mSwitchLine.setText(ResourcesUtils.getString(R.string.bus_close_line_btn));
|
||||
}
|
||||
}
|
||||
|
||||
public void hideOchBus() {
|
||||
// tvNotice.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStationPanelViewId() {
|
||||
return R.layout.offline_fragment_och;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void restartAutopilot() {
|
||||
if (!isAnimateRunning) {
|
||||
mPresenter.restartAutopilot();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public SlidePanelView.OnSlidePanelMoveToEndListener getSlidePanelOnEndListener() {
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveToEnd() {
|
||||
// 开启自动驾驶到下一站
|
||||
if (isAnimateRunning){
|
||||
stopAutopilotAnimation();
|
||||
}
|
||||
mPresenter.autoDriveToNextStation();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自动驾驶可用状态
|
||||
*/
|
||||
public void onAutopilotEnableChange(boolean isEnable) {
|
||||
if (isEnable) {
|
||||
showAutopilotBiz();
|
||||
} else {
|
||||
hideAutopilotBiz();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearBusStationsMarkers(){
|
||||
CallerLogger.d(M_BUS + TAG,"clearBusStationsMarkers()");
|
||||
if (null != startStation) {
|
||||
setOrRemoveMapMaker(false, BusConst.BUS_START_MAP_MAKER, startStation.getLat()
|
||||
, startStation.getLon(),R.raw.star_marker);
|
||||
}
|
||||
if (null != endStation) {
|
||||
setOrRemoveMapMaker(false, BusConst.BUS_END_MAP_MAKER, endStation.getLat()
|
||||
, endStation.getLon(),R.raw.end_marker);
|
||||
}
|
||||
|
||||
//清除鹰眼右下角小地图轨迹
|
||||
CallerLogger.d(SceneConstant.M_BUS, "clearBusStationsMarkers --------->");
|
||||
smallMapView.clearPolyline();
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制地图起点终点
|
||||
*
|
||||
* @param isAdd
|
||||
* @param uuid
|
||||
*/
|
||||
private void setOrRemoveMapMaker(boolean isAdd, String uuid, double lat, double longi,int resourceId) {
|
||||
if (isAdd) {
|
||||
Runnable setMapMarkerRunnable = () -> {
|
||||
CallerLogger.d(M_BUS + "setMapMaker= "+Thread.currentThread().getName(),
|
||||
uuid + "=latitude=" + lat + ",longitude=" + longi);
|
||||
|
||||
Point.Options.Builder builder = new Point.Options.Builder(BusConst.TYPE_MARKER_BUS_ORDER, Level.MAP_MARKER)
|
||||
.setId(uuid)
|
||||
.anchor(0.5f, 0.5f)
|
||||
.set3DMode(true)
|
||||
.isUseGps(true)
|
||||
.controlAngle(false)
|
||||
.icon3DRes(resourceId)
|
||||
.latitude(lat)
|
||||
.longitude(longi);
|
||||
IMoGoOverlayManager overlayManager = CallerMapUIServiceManager.INSTANCE.getOverlayManager();
|
||||
if (overlayManager != null) {
|
||||
overlayManager.showOrUpdatePoint(builder.build(),DEFAULT);
|
||||
}
|
||||
};
|
||||
|
||||
OCHThreadPoolManager.getsInstance().execute(setMapMarkerRunnable);
|
||||
|
||||
}else {
|
||||
Runnable removeMapMarkerRunnable = () -> {
|
||||
CallerLogger.d(M_BUS + "RemoveMapMaker="+Thread.currentThread().getName(),
|
||||
uuid+"=latitude="+lat+",longitude="+longi);
|
||||
Objects.requireNonNull(CallerMapUIServiceManager.INSTANCE.getOverlayManager()).removePoint(uuid);
|
||||
};
|
||||
OCHThreadPoolManager.getsInstance().execute(removeMapMarkerRunnable);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void debugAutoPilotStatus(int status) {
|
||||
mPresenter.debugAutoPilotStatus(status);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (v.getId() == R.id.switch_line_btn) {//切换路线条件: 自动驾驶过程中,点击则toast提示:自动驾驶中,不可切换路线
|
||||
//本次行程未结束,不支持切换路线。点击则toast提示:当前行程未完成,不可切换路线
|
||||
if (CallerAutoPilotStatusListenerManager.INSTANCE.getState()
|
||||
== IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
|
||||
ToastUtils.showLong(ResourcesUtils.getString(R.string.bus_switch_line_btn_warning1));
|
||||
return;
|
||||
}
|
||||
if ((int)mSwitchLine.getTag() == 0){//切换路线
|
||||
Intent intent = new Intent(getContext(), BusSwitchLineActivity.class);
|
||||
ActivityUtils.startActivity(intent);
|
||||
}else {//结束任务
|
||||
OCHCommitDialog.Builder builder = new OCHCommitDialog.Builder();
|
||||
OCHCommitDialog closeLineConfirmDialog = builder
|
||||
.title(getString(R.string.bus_dialog_title))
|
||||
.tips(getString(R.string.bus_dialog_tips))
|
||||
.confirmStr(getString(R.string.bus_dialog_confirm))
|
||||
.cancelStr(getString(R.string.bus_dialog_cancel))
|
||||
.build(getContext());
|
||||
closeLineConfirmDialog.setClickListener(new OCHCommitDialog.ClickListener() {
|
||||
@Override
|
||||
public void confirm() {
|
||||
mPresenter.abortTask();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
closeLineConfirmDialog.dismiss();
|
||||
}
|
||||
});
|
||||
closeLineConfirmDialog.show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,105 +0,0 @@
|
||||
package com.mogo.och.offline.model
|
||||
|
||||
import com.mogo.commons.storage.SharedPrefsMgr
|
||||
import com.mogo.eagle.core.utilcode.util.GsonUtils
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.manager.loop.LoopInfo
|
||||
import com.mogo.och.common.module.network.OchCommonServiceCallback
|
||||
import com.mogo.och.offline.bean.BindLineListResponse
|
||||
import com.mogo.och.offline.callback.IBusLinesCallback
|
||||
import com.mogo.och.offline.net.OrderServiceManager
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/9
|
||||
*/
|
||||
object BusLineModel {
|
||||
private var mBusLinesCallback: IBusLinesCallback? = null
|
||||
|
||||
private const val Catche4AllLines = "Catche4AllLines"
|
||||
private const val TAG = "BusLineModel"
|
||||
|
||||
private var lastAllLinesJson = ""
|
||||
|
||||
@JvmStatic
|
||||
fun setBusLinesCallback(callback: IBusLinesCallback?) {
|
||||
mBusLinesCallback = callback
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun queryBusLines() {
|
||||
val catche4AllLines = SharedPrefsMgr.getInstance().getString(Catche4AllLines)
|
||||
val bindLineListResponse =
|
||||
GsonUtils.fromJson(catche4AllLines, BindLineListResponse::class.java)
|
||||
if (bindLineListResponse != null && mBusLinesCallback != null) {
|
||||
mBusLinesCallback!!.onBusLinesChange(bindLineListResponse)
|
||||
}
|
||||
lastAllLinesJson = catche4AllLines
|
||||
OrderServiceManager.queryBindLineListBySn(object : OchCommonServiceCallback<BindLineListResponse> {
|
||||
override fun onSuccess(data: BindLineListResponse) {
|
||||
if (null == data && mBusLinesCallback != null) {
|
||||
mBusLinesCallback?.onBusLinesChange(null)
|
||||
return
|
||||
}
|
||||
mBusLinesCallback?.onBusLinesChange(data)
|
||||
val toJson = GsonUtils.toJson(data)
|
||||
if(lastAllLinesJson==toJson){
|
||||
return
|
||||
}else{
|
||||
lastAllLinesJson = toJson
|
||||
SharedPrefsMgr.getInstance().putString(Catche4AllLines, toJson)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError() {
|
||||
}
|
||||
|
||||
override fun onFail(code: Int, failMsg: String) {
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
@JvmStatic
|
||||
fun queryBusLinesByIo() {
|
||||
OrderServiceManager.queryBindLineListBySn(object : OchCommonServiceCallback<BindLineListResponse> {
|
||||
override fun onSuccess(data: BindLineListResponse) {
|
||||
if (null == data) {
|
||||
return
|
||||
}
|
||||
|
||||
val toJson = GsonUtils.toJson(data)
|
||||
if(lastAllLinesJson==toJson){
|
||||
return
|
||||
}else{
|
||||
lastAllLinesJson = toJson
|
||||
SharedPrefsMgr.getInstance().putString(Catche4AllLines, toJson)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError() {
|
||||
}
|
||||
|
||||
override fun onFail(code: Int, failMsg: String) {
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@JvmStatic
|
||||
fun commitSwitchLineId(checkLineInfo: BindLineListResponse.Result?) {
|
||||
if (mBusLinesCallback != null) {
|
||||
mBusLinesCallback!!.onChangeLineIdSuccess(checkLineInfo)
|
||||
}
|
||||
}
|
||||
@JvmStatic
|
||||
fun startLoopAllLine() {
|
||||
BizLoopManager.setLoopFunction(TAG, LoopInfo(60,::queryBusLinesByIo, scheduler = Schedulers.io()))
|
||||
}
|
||||
@JvmStatic
|
||||
fun stopLoopAllLine() {
|
||||
BizLoopManager.removeLoopFunction(TAG)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,509 @@
|
||||
package com.mogo.och.offline.model
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.commons.storage.SharedPrefsMgr
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.data.map.SiteMarkerBean
|
||||
import com.mogo.eagle.core.data.och.OchInfo
|
||||
import com.mogo.eagle.core.data.v2x.Point
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager
|
||||
import com.mogo.eagle.core.function.call.datacenter.CallerDataCenterBizListener
|
||||
import com.mogo.eagle.core.network.utils.digest.DigestUtils
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.eagle.core.utilcode.util.NetworkUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.mogo.och.bridge.autopilot.line.LineManager
|
||||
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
|
||||
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffResultMsg
|
||||
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.data.db.bean.LineDataBean
|
||||
import com.mogo.och.offline.R
|
||||
import com.mogo.och.offline.callback.IBusLinesCallback
|
||||
import com.mogo.och.offline.model.OrderModel.isGoingToNextStation
|
||||
import com.mogo.och.offline.repository.RepositoryManager
|
||||
import com.mogo.och.offline.repository.db.bean.TaskDataBean
|
||||
import com.mogo.och.offline.repository.db.bean.TaskSiteDataBean
|
||||
import com.mogo.och.offline.repository.db.repository.SiteDb
|
||||
import com.mogo.och.offline.repository.exception.DataException
|
||||
import com.mogo.och.offline.repository.net.bean.BindLineListResponse
|
||||
import com.mogo.och.offline.util.ShuttleVoiceManager
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
import java.util.concurrent.atomic.AtomicBoolean
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/9
|
||||
*/
|
||||
@SuppressLint("StaticFieldLeak")
|
||||
object LineModel {
|
||||
private var mContext: Context? = null
|
||||
|
||||
private val mBusLinesCallbackMap: MutableMap<String, IBusLinesCallback> = ConcurrentHashMap()
|
||||
|
||||
const val TAG = "${M_BUS}BusLineModel"
|
||||
|
||||
private val context = AbsMogoApplication.getApp()
|
||||
|
||||
// 判断接口是否变化
|
||||
private const val EXECUTABLECHANGEMD5 = "EXECUTABLECHANGEMD5"
|
||||
|
||||
// 展示上一次刷新时间
|
||||
const val EXECUTABLECHANGETIME = "executablechangetime"
|
||||
|
||||
var currentTask: TaskDataBean? = null
|
||||
|
||||
// 当前任务的站点列表
|
||||
var stationList: MutableList<BusStationBean>? = mutableListOf()
|
||||
|
||||
|
||||
private val isRequesting = AtomicBoolean(false)
|
||||
private var startTaskDisposable: Disposable? = null
|
||||
|
||||
private var queryCarInfo: Disposable? = null
|
||||
|
||||
// 当前站点
|
||||
@JvmStatic
|
||||
var startStationIndex: Int = 0 //A->B 此处值是A站点索引
|
||||
|
||||
@JvmStatic
|
||||
fun init() {
|
||||
d(TAG, "init")
|
||||
mContext = AbsMogoApplication.getApp()
|
||||
queryCarExecutableTaskList(true)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Synchronized
|
||||
fun release() {
|
||||
d(TAG, "release")
|
||||
mContext = null
|
||||
isRequesting.set(false)
|
||||
mBusLinesCallbackMap.clear()
|
||||
RxUtils.disposeSubscribe(queryCarInfo)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun setBusLinesCallback(tag: String?, callback: IBusLinesCallback?) {
|
||||
if (tag == null || "" == tag) return
|
||||
if (callback == null) {
|
||||
mBusLinesCallbackMap.remove(tag)
|
||||
return
|
||||
}
|
||||
mBusLinesCallbackMap[tag] = callback
|
||||
}
|
||||
|
||||
fun refreshTask() {
|
||||
RxUtils.disposeSubscribe(queryCarInfo)
|
||||
queryCarExecutableTaskList(false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 同步基础信息
|
||||
*/
|
||||
private fun queryCarExecutableTaskList(isBackground: Boolean) {
|
||||
if (isRequesting.get()) {
|
||||
d(TAG, "正在同步请稍等")
|
||||
val lastUpdateTime = SharedPrefsMgr.getInstance().getLong(EXECUTABLECHANGETIME, 0)
|
||||
mBusLinesCallbackMap.forEach { callback ->
|
||||
callback.value.onRefreshSuccess(lastUpdateTime)
|
||||
}
|
||||
return
|
||||
}
|
||||
isRequesting.set(true)
|
||||
d(TAG, "开始同步数据")
|
||||
RepositoryManager.queryCarExecutableTaskList(
|
||||
object : OchCommonServiceCallback<BindLineListResponse> {
|
||||
override fun onSuccess(data: BindLineListResponse) {
|
||||
isRequesting.set(false)
|
||||
d(TAG, "同步数据成功")
|
||||
RxUtils.disposeSubscribe(queryCarInfo)
|
||||
queryCarInfo = RxUtils.createSubscribe(60_000) {
|
||||
queryCarExecutableTaskList(true)
|
||||
}
|
||||
// 第一次过滤 请求返回值的md5
|
||||
val currentRequest = DigestUtils.md5Hex(data.data.toString())
|
||||
val lastChangeMd5 = SharedPrefsMgr.getInstance().getString(EXECUTABLECHANGEMD5)
|
||||
val lastUpdateTime =
|
||||
SharedPrefsMgr.getInstance().getLong(EXECUTABLECHANGETIME, 0)
|
||||
val currentTimeStamp = DateTimeUtil.getCurrentTimeStamp()
|
||||
|
||||
SharedPrefsMgr.getInstance().putLong(EXECUTABLECHANGETIME, currentTimeStamp)
|
||||
val sameDay = DateTimeUtil.isSameDay(currentTimeStamp, lastUpdateTime)
|
||||
mBusLinesCallbackMap.forEach { callback ->
|
||||
callback.value.onRefreshSuccess(currentTimeStamp)
|
||||
}
|
||||
if (isBackground) {
|
||||
if (currentRequest == lastChangeMd5 && sameDay) {
|
||||
return
|
||||
}
|
||||
}
|
||||
SharedPrefsMgr.getInstance().putString(EXECUTABLECHANGEMD5, currentRequest)
|
||||
OchChainLogManager.writeChainLog(
|
||||
"数据发生变化",
|
||||
"接口信息发生变化 $lastChangeMd5 new md5${currentRequest}"
|
||||
)
|
||||
val startTime = System.currentTimeMillis()
|
||||
BindLineListResponse.save2Db(data)
|
||||
d(TAG, "更新数据耗时${System.currentTimeMillis() - startTime}")
|
||||
RxUtils.createSubscribe(800) {
|
||||
// 等待写入数据库
|
||||
mBusLinesCallbackMap.forEach { callback ->
|
||||
callback.value.onRefreshSuccessWIthData()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onError() {
|
||||
isRequesting.set(false)
|
||||
d(TAG, "同步数据失败 onError")
|
||||
RxUtils.disposeSubscribe(queryCarInfo)
|
||||
queryCarInfo = RxUtils.createSubscribe(60_000) {
|
||||
queryCarExecutableTaskList(true)
|
||||
}
|
||||
if (!isBackground) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort(ResourcesUtils.getString(R.string.network_error_tip))
|
||||
} else {
|
||||
ToastUtils.showShort(ResourcesUtils.getString(R.string.request_error_tip))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFail(code: Int, failMsg: String) {
|
||||
isRequesting.set(false)
|
||||
d(TAG, "同步数据失败 onFail")
|
||||
RxUtils.disposeSubscribe(queryCarInfo)
|
||||
queryCarInfo = RxUtils.createSubscribe(60_000) {
|
||||
queryCarExecutableTaskList(true)
|
||||
}
|
||||
if (!isBackground) {
|
||||
if (!NetworkUtils.isConnected(mContext)) {
|
||||
ToastUtils.showShort("网络异常,请稍后重试")
|
||||
} else {
|
||||
ToastUtils.showShort(failMsg)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始任务
|
||||
*/
|
||||
@JvmStatic
|
||||
fun commitSwitchLineId(task: TaskDataBean, line: LineDataBean) {
|
||||
RxUtils.disposeSubscribe(startTaskDisposable)
|
||||
line.getLineIdAndName { lineId, lineName ->
|
||||
RepositoryManager.startTask(task.taskId?:0, lineId, lineName)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : Observer<Boolean> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
startTaskDisposable = d
|
||||
d(TAG, "commitSwitchLineId onSubscribe")
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
d(TAG, "commitSwitchLineId onError${e.printStackTrace()}")
|
||||
if (e is DataException) {
|
||||
OchChainLogManager.writeChainLog("开始任务", "${e.message}")
|
||||
ToastUtils.showShort("选择任务失败:${e.message}")
|
||||
mBusLinesCallbackMap.forEach {
|
||||
it.value.onChangeLineIdFail()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
d(TAG, "commitSwitchLineId onComplete")
|
||||
}
|
||||
|
||||
override fun onNext(data: Boolean) {
|
||||
d(TAG, "commitSwitchLineId onNext ${data}")
|
||||
if (data) {
|
||||
OrderModel.queryBusRoutes()
|
||||
BizLoopManager.runInIoThread {
|
||||
val querySiteByLineId = SiteDb.querySiteByLineId(lineId)
|
||||
querySiteByLineId?.forEach {
|
||||
if (it.seq == 1) {
|
||||
LanSocketManager.sendMsgToClient(
|
||||
WriteOffResultMsg(
|
||||
-99,
|
||||
"",
|
||||
"",
|
||||
System.currentTimeMillis(),
|
||||
LineManager.lineInfos?.lineId ?: 0,
|
||||
it.siteId ?: 0L
|
||||
)
|
||||
)
|
||||
}
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
mBusLinesCallbackMap.forEach {
|
||||
it.value.onChangeLineIdSuccess()
|
||||
}
|
||||
}
|
||||
RxUtils.disposeSubscribe(startTaskDisposable)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun haveRunningTask() {
|
||||
mBusLinesCallbackMap.forEach { callback ->
|
||||
callback.value.onRunningTask()
|
||||
}
|
||||
}
|
||||
|
||||
fun haveNoRunningTask() {
|
||||
mBusLinesCallbackMap.forEach { callback ->
|
||||
callback.value.onNoRunningTask()
|
||||
}
|
||||
}
|
||||
|
||||
fun leaveStationSuccess() {
|
||||
mBusLinesCallbackMap.forEach { map ->
|
||||
map.value.onLeaveStaionSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
fun arrivedStationSuccess() {
|
||||
LanSocketManager.sendMsgToClient(
|
||||
WriteOffResultMsg(
|
||||
-99,
|
||||
"",
|
||||
"",
|
||||
System.currentTimeMillis(),
|
||||
LineManager.lineInfos?.lineId ?: 0,
|
||||
LineManager.getStations()?.first?.siteId?.toLong() ?: 0L
|
||||
)
|
||||
)
|
||||
mBusLinesCallbackMap.forEach { callback ->
|
||||
callback.value.onArriveStationSuccess()
|
||||
}
|
||||
}
|
||||
|
||||
fun isLastStation(): Boolean? {
|
||||
return if (stationList.isNullOrEmpty()) {
|
||||
null
|
||||
} else {
|
||||
startStationIndex == stationList!!.size - 1
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun getTaskTime(): String {
|
||||
return DateTimeUtil.formatLongToString(
|
||||
currentTask?.startTime ?: System.currentTimeMillis(),
|
||||
DateTimeUtil.HH_mm
|
||||
)
|
||||
}
|
||||
|
||||
fun endTask() {
|
||||
currentTask?.taskId?.let { taskId ->
|
||||
RepositoryManager.endTask(taskId)
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : Observer<Boolean> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
startTaskDisposable
|
||||
d(TAG, "endTask onSubscribe")
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
d(TAG, "endTask onError${e.printStackTrace()}")
|
||||
if (e is DataException) {
|
||||
|
||||
}
|
||||
isGoingToNextStation = false
|
||||
|
||||
ThirdDeviceData.endTask()
|
||||
ThirdDeviceData.sendTaskDetailsToClients()
|
||||
ShuttleVoiceManager.endOrderBus()
|
||||
// 取消自驾
|
||||
CallerAutoPilotControlManager.cancelAutoPilot()
|
||||
currentTask = null
|
||||
LineManager.setLineInfo(null)
|
||||
LineManager.setStartAndEndStation(null, null)
|
||||
LanSocketManager.sendMsgToClient(
|
||||
WriteOffResultMsg(
|
||||
-99,
|
||||
"",
|
||||
"",
|
||||
System.currentTimeMillis(),
|
||||
LineManager.lineInfos?.lineId ?: 0,
|
||||
LineManager.getStations()?.first?.siteId?.toLong() ?: 0L
|
||||
)
|
||||
)
|
||||
LineModel.callEyeMap(1)
|
||||
stationList = mutableListOf()
|
||||
startStationIndex = 0
|
||||
mBusLinesCallbackMap.forEach {
|
||||
it.value.onCompleteTask()
|
||||
}
|
||||
val changeInfo =
|
||||
"taskId:${currentTask?.taskId}--lineInfo:${LineManager.lineInfos}"
|
||||
OchChainLogManager.writeChainLog("结束任务", changeInfo)
|
||||
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
d(TAG, "endTask onComplete")
|
||||
}
|
||||
|
||||
override fun onNext(data: Boolean) {
|
||||
d(TAG, "endTask onNext ${data}")
|
||||
if (data) {
|
||||
isGoingToNextStation = false
|
||||
|
||||
ThirdDeviceData.endTask()
|
||||
ThirdDeviceData.sendTaskDetailsToClients()
|
||||
ShuttleVoiceManager.endOrderBus()
|
||||
// 取消自驾
|
||||
CallerAutoPilotControlManager.cancelAutoPilot()
|
||||
currentTask = null
|
||||
LineManager.setLineInfo(null)
|
||||
LineManager.setStartAndEndStation(null, null)
|
||||
LanSocketManager.sendMsgToClient(
|
||||
WriteOffResultMsg(
|
||||
-99,
|
||||
"",
|
||||
"",
|
||||
System.currentTimeMillis(),
|
||||
LineManager.lineInfos?.lineId ?: 0,
|
||||
LineManager.getStations()?.first?.siteId?.toLong() ?: 0L
|
||||
)
|
||||
)
|
||||
stationList = mutableListOf()
|
||||
startStationIndex = 0
|
||||
LineModel.callEyeMap(2)
|
||||
mBusLinesCallbackMap.forEach {
|
||||
it.value.onCompleteTask()
|
||||
}
|
||||
val changeInfo =
|
||||
"taskId:${currentTask?.taskId}--lineInfo:${LineManager.lineInfos}"
|
||||
OchChainLogManager.writeChainLog("结束任务", changeInfo)
|
||||
}
|
||||
onComplete()
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fun startTaskMessage(): Boolean {
|
||||
if (!stationList.isNullOrEmpty()) {
|
||||
return startStationIndex == 0 && stationList!!.first().drivingStatus == TaskSiteDataBean.drivingStatusCurrent && !stationList!!.first().isLeaving
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
fun setDemoMode() {
|
||||
// 美化是否开始
|
||||
if (FunctionBuildConfig.isDemoMode) { //行驶过程中设置美化
|
||||
val (startStation, _) = LineManager.getStations()
|
||||
if (startStation != null && startStation.isLeaving) {
|
||||
OrderModel.startBeautificationMode()
|
||||
d(TAG, "美化模式-ignore:置为true(每次滑动出发)")
|
||||
} else if (startStationIndex > 0 && startStationIndex < stationList!!.size - 1) {
|
||||
//美化模式下 中间站点到站 引导线要一直绘制,所以此处不出强制绘制不传false
|
||||
CallerAutoPilotControlManager.setIPCDemoMode(false)
|
||||
d(TAG, "美化模式-ignore:false(到达中间站)")
|
||||
} else {
|
||||
OrderModel.closeBeautificationMode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun callEyeMap(index: Int) {
|
||||
d(TAG, "执行${index} callEyeMap${stationList?.size}")
|
||||
if (stationList.isNullOrEmpty()) {
|
||||
val ochInfo = OchInfo(1, mutableListOf())
|
||||
ochInfo.siteMarkerList = mutableListOf()
|
||||
CallerDataCenterBizListener.invokeOchInfo(ochInfo)
|
||||
OchChainLogManager.writeChainLogMap("地图", "站点信息:${ochInfo}")
|
||||
} else {
|
||||
val siteList = mutableListOf<SiteMarkerBean>()
|
||||
var temp: SiteMarkerBean? = null
|
||||
stationList?.let {
|
||||
it.forEachIndexed { index, busStationBean ->
|
||||
if (index == 0) {
|
||||
temp = SiteMarkerBean(
|
||||
Point(busStationBean.gcjLon, busStationBean.gcjLat),
|
||||
R.drawable.offline_map_start,
|
||||
0.5f,
|
||||
0.87f
|
||||
)
|
||||
} else if (index == it.size - 1) {
|
||||
temp = SiteMarkerBean(
|
||||
Point(busStationBean.gcjLon, busStationBean.gcjLat),
|
||||
R.drawable.offline_map_end,
|
||||
0.5f,
|
||||
0.87f
|
||||
)
|
||||
} else {
|
||||
if (busStationBean.drivingStatus == 1) {
|
||||
temp = SiteMarkerBean(
|
||||
Point(busStationBean.gcjLon, busStationBean.gcjLat),
|
||||
R.drawable.offline_map_pass,
|
||||
0.5f,
|
||||
0.478f
|
||||
)
|
||||
} else if (busStationBean.drivingStatus == 3) {
|
||||
temp = SiteMarkerBean(
|
||||
Point(busStationBean.gcjLon, busStationBean.gcjLat),
|
||||
R.drawable.offline_map_notarrive,
|
||||
0.5f,
|
||||
0.478f
|
||||
)
|
||||
} else if (busStationBean.drivingStatus == 2) {
|
||||
if (busStationBean.isLeaving) {
|
||||
temp = SiteMarkerBean(
|
||||
Point(
|
||||
busStationBean.gcjLon,
|
||||
busStationBean.gcjLat
|
||||
), R.drawable.offline_map_pass, 0.5f, 0.478f
|
||||
)
|
||||
} else {
|
||||
temp = SiteMarkerBean(
|
||||
Point(
|
||||
busStationBean.gcjLon,
|
||||
busStationBean.gcjLat
|
||||
), R.drawable.offline_map_notarrive, 0.5f, 0.478f
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
temp?.let { temp ->
|
||||
siteList.add(temp)
|
||||
}
|
||||
}
|
||||
}
|
||||
val (start, end) = LineManager.getStations()
|
||||
if (start != null && end != null) {
|
||||
val ochInfo =
|
||||
OchInfo(1, mutableListOf(start.toMogoLocation(), end.toMogoLocation()))
|
||||
ochInfo.siteMarkerList = siteList
|
||||
CallerDataCenterBizListener.invokeOchInfo(ochInfo)
|
||||
OchChainLogManager.writeChainLogMap("地图", "站点信息:${ochInfo}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
package com.mogo.och.offline.model
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.eagle.core.utilcode.util.GsonUtils
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
|
||||
import com.mogo.och.common.module.biz.login.LoginStatusManager
|
||||
import com.mogo.och.bridge.autopilot.line.LineManager
|
||||
import com.mogo.och.common.module.manager.socket.cloud.AbnormalFactorsLoopManager
|
||||
import com.mogo.och.common.module.manager.socket.cloud.OCHSocketMessageManager
|
||||
import com.mogo.och.common.module.manager.socket.cloud.action.OperateAction
|
||||
import com.mogo.och.common.module.manager.socket.lan.ILanMessageListener
|
||||
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
|
||||
import com.mogo.och.common.module.manager.socket.lan.LedScreenManager
|
||||
import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType
|
||||
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
|
||||
import com.mogo.och.common.module.manager.socket.lan.bean.TaskDetailsMsg
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.data.bean.BusRoutesResult
|
||||
import com.mogo.och.data.bean.BusTransferData
|
||||
import com.mogo.och.offline.R
|
||||
import com.mogo.och.offline.constant.BusConst
|
||||
import com.mogo.och.offline.util.ShuttleVoiceManager
|
||||
|
||||
object ThirdDeviceData {
|
||||
|
||||
const val TAG = M_BUS+"ThirdDeviceData"
|
||||
|
||||
@JvmStatic
|
||||
val busRoutesResult: BusRoutesResult = BusRoutesResult()
|
||||
|
||||
fun init() {
|
||||
//监听运营消息
|
||||
OCHSocketMessageManager.registerSocketMessageListener(
|
||||
OCHSocketMessageManager.msgMonitorType,
|
||||
OperateAction(true)
|
||||
)
|
||||
|
||||
// 长链接监听
|
||||
AbnormalFactorsLoopManager.startLoopAbnormalFactors(AbsMogoApplication.getApp())
|
||||
|
||||
//监听乘客屏发来的消息
|
||||
LanSocketManager.registerSocketMessageListener(
|
||||
DPMsgType.TYPE_TASK_DETAILS.type,
|
||||
taskDetailsMsgListener
|
||||
)
|
||||
}
|
||||
|
||||
fun release() {
|
||||
|
||||
OCHSocketMessageManager.releaseSocketMessageListener(OCHSocketMessageManager.msgMonitorType)
|
||||
|
||||
AbnormalFactorsLoopManager.stopLoopAbnormalFactors()
|
||||
|
||||
//监听乘客屏发来的消息
|
||||
LanSocketManager.unRegisterSocketMessageListener(
|
||||
DPMsgType.TYPE_TASK_DETAILS.type,
|
||||
taskDetailsMsgListener
|
||||
)
|
||||
}
|
||||
|
||||
// 乘客屏请求线路信息
|
||||
private val taskDetailsMsgListener = object : ILanMessageListener<TaskDetailsMsg> {
|
||||
override fun targetLan(): Class<TaskDetailsMsg> = TaskDetailsMsg::class.java
|
||||
override fun onLanMsgReceived(taskDetailsMsg: TaskDetailsMsg?) = sendTaskDetailsToClients()
|
||||
}
|
||||
|
||||
private var delayedTts:Runnable?=null
|
||||
|
||||
// 离站
|
||||
fun leaveStation() {
|
||||
LineManager.getStationsWithLine { start, end, lineInfo ->
|
||||
delayedTts = object :Runnable{
|
||||
override fun run() {
|
||||
ShuttleVoiceManager.leaveStationBus(end.name, end.nameKr)
|
||||
}
|
||||
}
|
||||
UiThreadHandler.postDelayed(delayedTts, BusConst.DELAY_10S)
|
||||
//给bus外屏发送
|
||||
LedScreenManager.sendTripInfo2Led(
|
||||
LedScreenManager.LEAVE_STATION,
|
||||
lineInfo.lineName,
|
||||
start.name,
|
||||
end.name,
|
||||
LineModel.isLastStation() == true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//到站
|
||||
fun arriveStation() {
|
||||
delayedTts?.let {
|
||||
UiThreadHandler.removeCallbacks(delayedTts)
|
||||
}
|
||||
LineManager.getStationsWithLine { start, end, lineInfo ->
|
||||
ShuttleVoiceManager.arrivedStationBus(end.name, end.nameKr)
|
||||
// 收到正在进站的决策信息时播报,每个站点仅播报1次
|
||||
ShuttleVoiceManager.arrivedStationOut(ResourcesUtils.getString(R.string.m2_voice_out_arrive_station))
|
||||
//给bus外屏发送
|
||||
LedScreenManager.sendTripInfo2Led(
|
||||
LedScreenManager.ARRIVE_STATION,
|
||||
lineInfo.lineName,
|
||||
start.name,
|
||||
end.name,
|
||||
LineModel.isLastStation() == true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
//结束任务
|
||||
fun endTask() {
|
||||
delayedTts?.let {
|
||||
UiThreadHandler.removeCallbacks(delayedTts)
|
||||
}
|
||||
LineManager.getLineInfo {lineInfo ->
|
||||
LedScreenManager.sendTripInfo2Led(
|
||||
LedScreenManager.END_TRIP,
|
||||
lineInfo.lineName,
|
||||
"",
|
||||
"",
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun sendTaskDetailsToClients() {
|
||||
if (LineManager.lineInfos == null || LineModel.currentTask == null || LineModel.stationList.isNullOrEmpty()) {
|
||||
val data = BusTransferData(if (LoginStatusManager.isLogin()) 1 else 0, null)
|
||||
val msg = TaskDetailsMsg(GsonUtils.toJson(data), BusinessType.shuttle)
|
||||
d(TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg))
|
||||
LanSocketManager.sendMsgToClient(msg)
|
||||
} else {
|
||||
LineManager.getLineInfo {lineInfo ->
|
||||
busRoutesResult.setSite(LineModel.stationList)
|
||||
busRoutesResult.lineId = lineInfo.lineId.toInt()
|
||||
busRoutesResult.name = lineInfo.lineName
|
||||
busRoutesResult.taskId = LineModel.currentTask!!.taskId!!.toInt()
|
||||
busRoutesResult.taskTime = LineModel.currentTask!!.startTime
|
||||
busRoutesResult.writeVersion = System.currentTimeMillis()
|
||||
val data = BusTransferData(if (LoginStatusManager.isLogin()) 1 else 0, busRoutesResult)
|
||||
val msg = TaskDetailsMsg(GsonUtils.toJson(data), BusinessType.shuttle)
|
||||
d(TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg))
|
||||
LanSocketManager.sendMsgToClient(msg)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
package com.mogo.och.offline.presenter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
|
||||
import com.mogo.commons.mvp.Presenter;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
import com.mogo.och.offline.bean.BindLineListResponse;
|
||||
import com.mogo.och.offline.ui.BusSwitchLineView;
|
||||
import com.mogo.och.offline.callback.IBusLinesCallback;
|
||||
import com.mogo.och.offline.model.BusLineModel;
|
||||
import com.mogo.och.offline.model.OrderModel;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/9
|
||||
*/
|
||||
public class BusLinePresenter extends Presenter<BusSwitchLineView> implements IBusLinesCallback {
|
||||
|
||||
public BusLinePresenter(BusSwitchLineView view) {
|
||||
super(view);
|
||||
OrderModel.getInstance().init();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@NonNull LifecycleOwner owner) {
|
||||
super.onCreate(owner);
|
||||
initListener();
|
||||
}
|
||||
|
||||
private void initListener() {
|
||||
BusLineModel.setBusLinesCallback(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBusLinesChange(BindLineListResponse lines) {
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.onBusLinesChange(lines);
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChangeLineIdSuccess(BindLineListResponse.Result checkLineInfo) {
|
||||
OrderModel.getInstance().pushCacheTransferData(BindLineListResponse.getCommonLineInfo(checkLineInfo));
|
||||
OrderModel.getInstance().clearBusStationDatas();
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.onChangeLineIdSuccess();
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
|
||||
public void queryBusLines(){
|
||||
BusLineModel.queryBusLines();
|
||||
}
|
||||
|
||||
public void commitSwitchLineId(BindLineListResponse.Result checkLineInfo){
|
||||
BusLineModel.commitSwitchLineId(checkLineInfo);
|
||||
}
|
||||
|
||||
public void removeListener(){
|
||||
BusLineModel.setBusLinesCallback(null);
|
||||
}
|
||||
|
||||
public void queryBusRoutes(){
|
||||
OrderModel.getInstance().queryBusRoutes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy(@NonNull LifecycleOwner owner) {
|
||||
super.onDestroy(owner);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,329 +0,0 @@
|
||||
package com.mogo.och.offline.presenter;
|
||||
|
||||
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
|
||||
|
||||
import android.os.Looper;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.commons.mvp.Presenter;
|
||||
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.call.autopilot.CallerAutoPilotControlManager;
|
||||
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
import com.mogo.och.bridge.autopilot.OCHAdasAbilityManager;
|
||||
import com.mogo.och.bridge.autopilot.autopilot.IOchAutopilotStatusListener;
|
||||
import com.mogo.och.bridge.autopilot.autopilot.OchAutoPilotStatusListenerManager;
|
||||
import com.mogo.och.bridge.autopilot.autopilot.bean.ArrivedStation;
|
||||
import com.mogo.och.common.module.biz.login.LoginStatusEnum;
|
||||
import com.mogo.och.data.bean.BusStationBean;
|
||||
import com.mogo.och.offline.callback.IBusADASStatusCallback;
|
||||
import com.mogo.och.offline.callback.IBusControllerStatusCallback;
|
||||
import com.mogo.och.offline.callback.IRefreshBusStationsCallback;
|
||||
import com.mogo.och.offline.callback.ISlidePannelHideCallback;
|
||||
import com.mogo.och.offline.fragment.ShuttleFragment;
|
||||
import com.mogo.och.offline.model.BusLineModel;
|
||||
import com.mogo.och.offline.model.OrderModel;
|
||||
import com.mogo.och.offline.util.OffLineTrajectoryManager;
|
||||
import com.mogo.och.common.module.biz.login.ILoginCallback;
|
||||
import com.mogo.och.common.module.biz.login.LoginStatusManager;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* 网约车小巴
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class BusPresenter extends Presenter<ShuttleFragment>
|
||||
implements IRefreshBusStationsCallback, ISlidePannelHideCallback
|
||||
, IOchAutopilotStatusListener, IBusControllerStatusCallback, ILoginCallback, IBusADASStatusCallback {
|
||||
|
||||
private static final String TAG = "BusPresenter";
|
||||
|
||||
private final List<BusStationBean> mStationList = new ArrayList<>();
|
||||
private int mCurrentStation = 0;
|
||||
|
||||
public BusPresenter(ShuttleFragment view) {
|
||||
super(view);
|
||||
//2021.11.1 鹰眼架构整合,由IMoGoAutopilotStatusListener逐步替代IMogoAdasOCHCallback接口
|
||||
OrderModel.getInstance().init();
|
||||
OCHAdasAbilityManager.getInstance().init(AbsMogoApplication.getApp());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(@NonNull LifecycleOwner owner) {
|
||||
super.onCreate(owner);
|
||||
initModelListener();
|
||||
|
||||
OrderModel.getInstance().queryBusCacheRoutes();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy(@NonNull LifecycleOwner owner) {
|
||||
super.onDestroy(owner);
|
||||
OrderModel.getInstance().release();
|
||||
releaseListener();
|
||||
}
|
||||
|
||||
public void initModelListener() {
|
||||
OrderModel.getInstance().setRefreshBusStationsCallback(this);
|
||||
OrderModel.getInstance().setSlidePanelHideCallback(this);
|
||||
OrderModel.getInstance().setControllerStatusCallback(this);
|
||||
OrderModel.getInstance().setAdasStatusCallback(this);
|
||||
OchAutoPilotStatusListenerManager.INSTANCE.addListener(TAG,this);
|
||||
LoginStatusManager.INSTANCE.addListener(TAG,this);
|
||||
}
|
||||
|
||||
public void releaseListener() {
|
||||
OrderModel.getInstance().setRefreshBusStationsCallback(null);
|
||||
OrderModel.getInstance().setSlidePanelHideCallback(null);
|
||||
OrderModel.getInstance().setControllerStatusCallback(null);
|
||||
OrderModel.getInstance().setAdasStatusCallback(null);
|
||||
OCHAdasAbilityManager.getInstance().release();
|
||||
OchAutoPilotStatusListenerManager.INSTANCE.removeListener(TAG);
|
||||
LoginStatusManager.INSTANCE.removeListener(TAG);
|
||||
}
|
||||
|
||||
public void abortTask() {
|
||||
OrderModel.getInstance().abortTask();
|
||||
}
|
||||
|
||||
public void autoDriveToNextStation() {
|
||||
OrderModel.getInstance().autoDriveToNextStation();
|
||||
}
|
||||
|
||||
public void restartAutopilot() {
|
||||
if (OrderModel.getInstance().isGoingToNextStation()){
|
||||
OrderModel.getInstance().restartAutopilot();
|
||||
}
|
||||
}
|
||||
|
||||
// 登出
|
||||
public void logout() {
|
||||
OrderModel.getInstance().logout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateBusTaskStatus(String lineName,String lineTime,
|
||||
List<BusStationBean> stationList,
|
||||
int arrivingOrArrivedIndex,
|
||||
boolean isArrived) {
|
||||
mStationList.clear();
|
||||
mStationList.addAll(stationList);
|
||||
if (arrivingOrArrivedIndex == 0 || isArrived){
|
||||
mCurrentStation = arrivingOrArrivedIndex;
|
||||
}else {
|
||||
mCurrentStation = arrivingOrArrivedIndex -1;
|
||||
}
|
||||
CallerLogger.d(M_BUS + "BusOrderModel =", " mCurrentStation =" + mCurrentStation);
|
||||
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.updateBusTaskStatus(lineName,lineTime,
|
||||
stationList, arrivingOrArrivedIndex, isArrived);
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void updateEmptyUi() {
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.updateLineEmptyUI();
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearBusStationsMarkers() {
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.clearBusStationsMarkers();
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hideSlidePanel() {
|
||||
if (mView != null) {
|
||||
mView.hideSlidePanel();
|
||||
mView.setArrivedClikable(true);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotArriveAtStation(ArrivedStation arrivedStation) {
|
||||
CallerLogger.e( M_BUS + TAG, "行程日志-onAutopilotArriveAtStation arrive");
|
||||
arriveStation(arrivedStation,"底盘触发进站");
|
||||
}
|
||||
|
||||
public void arriveStation(ArrivedStation arrivedStation,String type){
|
||||
OrderModel.getInstance().onArriveAt(arrivedStation,type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotStatusResponse(int state) {
|
||||
switch (state) {
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE:
|
||||
case IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING:
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE:
|
||||
if (FunctionBuildConfig.isDemoMode
|
||||
&& (
|
||||
(mCurrentStation >= 0 && mCurrentStation <= mStationList.size() - 1)
|
||||
&& OrderModel.getInstance().isGoingToNextStation()
|
||||
)
|
||||
) {
|
||||
CallerLogger.d(M_BUS + "BusOrderModel=", "有美化功能");
|
||||
return;
|
||||
}
|
||||
// 改变UI自动驾驶状态
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.onAutopilotStatusChanged(state, CallerAutoPilotControlManager.INSTANCE.isCanStartAutopilot(false,0));
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
break;
|
||||
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING:
|
||||
OrderModel.getInstance().triggerStartServiceEvent(
|
||||
OrderModel.getInstance().isRestartAutopilot(), true,0,"");
|
||||
// 改变UI自动驾驶状态
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.onAutopilotStatusChanged(state, CallerAutoPilotControlManager.INSTANCE.isCanStartAutopilot(false,0));
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
break;
|
||||
default:
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.onAutopilotEnableChange(false);
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAutopilotStatusResponseFromCan(int state) {
|
||||
if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
|
||||
OrderModel.getInstance().triggerStartServiceEvent(
|
||||
OrderModel.getInstance().isRestartAutopilot(), true,1,"");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCarLocationChanged(MogoLocation location) {
|
||||
// if (null != location) {
|
||||
// runOnUIThread(() -> mView.updateSpeedView(location.getGnssSpeed()));
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startOpenAutopilot() {
|
||||
//非美化模式下启动动画
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.startAutopilotAnimation();
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
|
||||
//中间站点再次开启自驾时, 自动驾驶状态是2未改变, 此次鹰眼底层不再返给业务,需优化按钮动画显示
|
||||
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
|
||||
== CallerAutoPilotStatusListenerManager.INSTANCE.getState()&&mView!=null){
|
||||
mView.onAutopilotStatusChanged(CallerAutoPilotStatusListenerManager.INSTANCE.getState(),
|
||||
CallerAutoPilotControlManager.INSTANCE.isCanStartAutopilot(false,0));
|
||||
}
|
||||
}
|
||||
|
||||
private void runOnUIThread(Runnable executor) {
|
||||
if (executor == null) {
|
||||
return;
|
||||
}
|
||||
if (Looper.myLooper() != Looper.getMainLooper()) {
|
||||
UiThreadHandler.post(executor);
|
||||
} else {
|
||||
executor.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 测试使用
|
||||
*/
|
||||
public void debugAutoPilotStatus(int status) {
|
||||
onAutopilotStatusResponse(status);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onStatusChange(LoginStatusEnum currentStatus) {
|
||||
CallerLogger.d(M_BUS + TAG, " loginStatus =" + LoginStatusManager.isLogin());
|
||||
if(LoginStatusManager.isLogin()){
|
||||
// OrderModel.getInstance().queryBusRoutes();
|
||||
OrderModel.getInstance().queryBusCacheRoutes();
|
||||
BusLineModel.startLoopAllLine();
|
||||
}else {
|
||||
BusLineModel.stopLoopAllLine();
|
||||
OffLineTrajectoryManager.INSTANCE.stopTrajReqLoop();
|
||||
clearBusStationsMarkers();
|
||||
if(mView!=null) {
|
||||
mView.hideSlidePanel();
|
||||
}
|
||||
OrderModel.getInstance().closeBeautificationMode();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartAdasFailure() {
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.stopAnimAndUpdateBtnStatus();
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void canStartAutopilot(boolean canStart) {
|
||||
UiThreadHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if(mView!=null) {
|
||||
mView.onAutopilotStatusChanged(CallerAutoPilotStatusListenerManager.INSTANCE.getState(),canStart);
|
||||
}
|
||||
}
|
||||
}, UiThreadHandler.MODE.QUEUE);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
package com.mogo.och.offline.repository
|
||||
|
||||
import com.google.gson.reflect.TypeToken
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.eagle.core.utilcode.util.GsonUtils
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.mogo.och.bridge.autopilot.line.LineManager
|
||||
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
|
||||
import com.mogo.och.common.module.network.OchCommonServiceCallback
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.data.bean.ContraiInfo
|
||||
import com.mogo.och.data.bean.LineInfo
|
||||
import com.mogo.och.data.bean.SiteIntroduce
|
||||
import com.mogo.och.data.db.bean.LineDataBean
|
||||
import com.mogo.och.offline.model.LineModel
|
||||
import com.mogo.och.offline.model.LineModel.currentTask
|
||||
import com.mogo.och.offline.repository.db.bean.TaskSiteDataBean
|
||||
import com.mogo.och.offline.repository.db.repository.ContraiDb
|
||||
import com.mogo.och.offline.repository.db.repository.LineDb
|
||||
import com.mogo.och.offline.repository.db.repository.TaskDb
|
||||
import com.mogo.och.offline.repository.db.repository.TaskSiteDb
|
||||
import com.mogo.och.offline.repository.net.OrderServiceManager
|
||||
import com.mogo.och.offline.repository.net.bean.BindLineListResponse
|
||||
import io.reactivex.Observable
|
||||
|
||||
|
||||
object RepositoryManager {
|
||||
|
||||
const val TAG = "${M_BUS}RepositoryManager"
|
||||
|
||||
fun queryCanUseLine(): Observable<List<LineDataBean>?>? {
|
||||
return LineDb.queryCanUseLineRx()
|
||||
}
|
||||
|
||||
fun startTask(taskId:Long,lineId:Long,lineName:String): Observable<Boolean>? {
|
||||
return TaskDb.startTask(taskId, lineId, lineName)
|
||||
}
|
||||
|
||||
fun queryCarExecutableTaskList(ochCommonServiceCallback: OchCommonServiceCallback<BindLineListResponse>) {
|
||||
OrderServiceManager.queryBindLineListBySn(ochCommonServiceCallback)
|
||||
}
|
||||
|
||||
fun endTask(taskId: Long): Observable<Boolean>? {
|
||||
return Observable.just(taskId).flatMap {
|
||||
currentTask?.let {task->
|
||||
if (task.taskId!=null&&task.lineId!=null) {
|
||||
TaskDb.endTask(task.taskId!!)
|
||||
}
|
||||
}
|
||||
return@flatMap Observable.just(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun loadCurrentTaskInfo(): Observable<Boolean>? {
|
||||
return Observable.just(123)
|
||||
.flatMap {
|
||||
// 获取正在运行的任务
|
||||
val runningTaskInfo = TaskDb.queryRunningTask()
|
||||
if (runningTaskInfo.isNullOrEmpty()) {
|
||||
// 本地没有进行中的任务
|
||||
CallerLogger.d(TAG, "loadCurrentTaskInfo 没有查询到正在运行的任务")
|
||||
return@flatMap Observable.just(false)
|
||||
} else if (runningTaskInfo.size > 1) {
|
||||
// 本地有多条正在进行的任务 需要check event
|
||||
// 1 比对event表 1 清理错误数据 2 加载后台数据
|
||||
CallerLogger.d(TAG, "loadCurrentTaskInfo 查询到多个正在执行的任务")
|
||||
return@flatMap Observable.just(false)
|
||||
} else {
|
||||
// 只有一条进行中的任务
|
||||
currentTask = runningTaskInfo.first()
|
||||
// 恢复站点信息
|
||||
currentTask?.taskId?.let {
|
||||
// 获取正在进行中的具体信息
|
||||
val runnintTaskAndSites = TaskSiteDb.queryRunningTask(it)
|
||||
if(runnintTaskAndSites.isNullOrEmpty()||runnintTaskAndSites.size<2){
|
||||
CallerLogger.d(TAG, "异常情况:有任务:${runningTaskInfo} runningTask 表格没有对应的数据:${runnintTaskAndSites}")
|
||||
OchChainLogManager.writeChainLogDb("加载任务", "异常情况:有任务:${runningTaskInfo} runningTask 表格没有对应的数据:${runnintTaskAndSites}")
|
||||
TaskSiteDb.deleteErrorData(it)
|
||||
return@flatMap Observable.just(false)
|
||||
}
|
||||
val db2Beans = db2Beans(runnintTaskAndSites)
|
||||
LineModel.stationList = db2Beans.first
|
||||
LineModel.startStationIndex = db2Beans.second
|
||||
LineModel.stationList?.let { stationlist->
|
||||
val startStation = stationlist[LineModel.startStationIndex]
|
||||
if (LineModel.startStationIndex < stationlist.size-1) {
|
||||
val endStation = stationlist[LineModel.startStationIndex + 1]
|
||||
LineManager.setStartAndEndStation(startStation,endStation)
|
||||
LineModel.callEyeMap(8)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// 设置自动驾驶信息
|
||||
currentTask?.lineId?.let {
|
||||
ContraiDb.queryAutopilotInfoByLineid(it)?.apply {
|
||||
if (lineId == null || lineId!! < 0L||csvFileUrl.isNullOrEmpty()||csvFileMd5.isNullOrEmpty()||txtFileUrl.isNullOrEmpty()||txtFileMd5.isNullOrEmpty()) {
|
||||
ToastUtils.showLong("请设置轨迹信息")
|
||||
OchChainLogManager.writeChainLogAutopilot("轨迹错误",this.toString())
|
||||
CallerLogger.d(TAG,"轨迹错误,$this")
|
||||
}
|
||||
LineManager.setContraiInfo(ContraiInfo(lineId!!,csvFileUrl!!,csvFileMd5!!,txtFileUrl!!,txtFileMd5!!,contrailSaveTime!!))
|
||||
}
|
||||
}
|
||||
return@flatMap Observable.just(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
fun leaveStation(
|
||||
taskId: Long
|
||||
): Observable<Boolean>?{
|
||||
return Observable.just(taskId)
|
||||
.flatMap {
|
||||
//开始站点: leaving false->true
|
||||
LineManager.getStartStation {
|
||||
TaskSiteDb.updateLeave(taskId, it.siteId.toLong(), true)
|
||||
OchChainLogManager.writeChainLogDb(
|
||||
"滑动出发",
|
||||
"task:${currentTask}__taskId:${currentTask?.taskId}"
|
||||
)
|
||||
CallerLogger.d(TAG,"滑动出发:task:${currentTask}__taskId:${currentTask?.taskId}")
|
||||
}
|
||||
val (startStation, endStation) = LineManager.getStations()
|
||||
val changeInfo =
|
||||
"taskId:${currentTask?.taskId}--lineId:${currentTask?.lineId}--currentStationName:${startStation?.name}--finalNextStationName:${endStation?.name}"
|
||||
OchChainLogManager.writeChainLog("滑动出发", changeInfo)
|
||||
CallerLogger.d(TAG,"滑动出发:$changeInfo")
|
||||
// 开始任务成功
|
||||
return@flatMap Observable.just(true)
|
||||
}
|
||||
}
|
||||
|
||||
fun arriveStation(taskId: Long): Observable<Boolean>? {
|
||||
// 开始站点:leaving true->false drivingStatus 2->1
|
||||
return Observable.just(taskId)
|
||||
.flatMap {
|
||||
LineManager.getStations { start, end ->
|
||||
if (currentTask != null && currentTask!!.taskId != null) {
|
||||
currentTask?.let { task ->
|
||||
if (task.taskId != null && task.lineId != null) {
|
||||
TaskSiteDb.updateDrivingStatusAndLeave(
|
||||
task.taskId!!,
|
||||
start.siteId.toLong(),
|
||||
TaskSiteDataBean.drivingStatusPassed,
|
||||
false
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
OchChainLogManager.writeChainLog(
|
||||
"到站_数据更新_error",
|
||||
"task:${currentTask}__taskId:${currentTask?.taskId}"
|
||||
)
|
||||
CallerLogger.d(TAG,"到站_数据更新_error:task:${currentTask}__taskId:${currentTask?.taskId}")
|
||||
}
|
||||
// 结束站点: drivingStatus 3-2
|
||||
if (currentTask != null && currentTask!!.taskId != null) {
|
||||
currentTask?.taskId?.let { taskId ->
|
||||
TaskSiteDb.updateDrivingStatus(
|
||||
taskId,
|
||||
end.siteId.toLong(),
|
||||
TaskSiteDataBean.drivingStatusCurrent
|
||||
)
|
||||
}
|
||||
} else {
|
||||
OchChainLogManager.writeChainLog(
|
||||
"到站_数据更新_error",
|
||||
"task:${currentTask}__taskId:${currentTask?.taskId}"
|
||||
)
|
||||
CallerLogger.d(TAG,"到站_数据更新_error:task:${currentTask}__taskId:${currentTask?.taskId}")
|
||||
}
|
||||
val changeInfo =
|
||||
"taskId:${currentTask?.taskId}--lineId:${currentTask?.lineId}--currentStationName:${start.name}--finalNextStationName:${end.name}"
|
||||
OchChainLogManager.writeChainLog("到站", changeInfo)
|
||||
CallerLogger.d(TAG,"到站:$changeInfo")
|
||||
}
|
||||
return@flatMap Observable.just(true)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun db2Beans(runnintTaskAndSites: List<TaskSiteDataBean>?): Pair<MutableList<BusStationBean>,Int> {
|
||||
val result = mutableListOf<BusStationBean>()
|
||||
var temp: BusStationBean? = null
|
||||
var currentStationIndex = -1
|
||||
var lineInfo: LineInfo?=null
|
||||
if (runnintTaskAndSites.isNullOrEmpty()) {
|
||||
LineManager.setLineInfo(lineInfo)
|
||||
return Pair(result,currentStationIndex)
|
||||
}
|
||||
runnintTaskAndSites.forEachIndexed { index, taskAndsite ->
|
||||
temp = BusStationBean()
|
||||
temp?.drivingStatus = (taskAndsite.drivingStatus ?: 0)
|
||||
temp?.lat = (taskAndsite.lat ?: 0.0)
|
||||
temp?.lon = (taskAndsite.lon ?: 0.0)
|
||||
temp?.gcjLat = (taskAndsite.gcjLat ?: 0.0)
|
||||
temp?.gcjLon = (taskAndsite.gcjLon ?: 0.0)
|
||||
temp?.introduction = taskAndsite.introduction
|
||||
temp?.isLeaving = java.lang.Boolean.TRUE == taskAndsite.leaving
|
||||
temp?.name = taskAndsite.name
|
||||
temp?.nameKr = taskAndsite.nameKr
|
||||
temp?.isPlayTts = java.lang.Boolean.TRUE == taskAndsite.isPlayTts
|
||||
temp?.seq = (taskAndsite.seq ?: 0)
|
||||
temp?.siteId = if (taskAndsite.siteId == null) 0 else taskAndsite.siteId!!.toInt()
|
||||
if(!taskAndsite.videoList.isNullOrEmpty()){
|
||||
try {
|
||||
val list = GsonUtils.fromJson<List<SiteIntroduce>>(
|
||||
taskAndsite.videoList,
|
||||
object : TypeToken<List<SiteIntroduce?>?>() {}.type
|
||||
)
|
||||
temp?.videoList = list.toMutableList()
|
||||
}catch (e:Exception){
|
||||
temp?.videoList = null
|
||||
}
|
||||
|
||||
}
|
||||
result.add(temp!!)
|
||||
// 正在进行中的任务
|
||||
if (temp!!.drivingStatus == TaskSiteDataBean.drivingStatusCurrent) {
|
||||
currentStationIndex = index
|
||||
}
|
||||
// 线路信息
|
||||
if (lineInfo == null && taskAndsite.lineId != null && taskAndsite.lineName != null) {
|
||||
lineInfo = LineInfo(taskAndsite.lineId!!, taskAndsite.lineName!!, orderId = taskAndsite.taskId.toString())
|
||||
}
|
||||
lineInfo?.multiMap?.put("taskInfo",LineModel.getTaskTime())
|
||||
}
|
||||
LineManager.setLineInfo(lineInfo)
|
||||
|
||||
return Pair(result,currentStationIndex)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package com.mogo.och.offline.repository.db
|
||||
|
||||
interface IDbRepository {
|
||||
fun register(){
|
||||
MyDataBase.instance?.register(this)
|
||||
}
|
||||
fun release()
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.mogo.och.offline.repository.db
|
||||
|
||||
import androidx.room.Database
|
||||
import androidx.room.Room
|
||||
import androidx.room.RoomDatabase
|
||||
import androidx.sqlite.db.SupportSQLiteOpenHelper
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.commons.env.Project
|
||||
import com.mogo.commons.env.ProjectUtils
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.och.data.db.bean.ContrailDataBean
|
||||
import com.mogo.och.data.db.bean.LineDataBean
|
||||
import com.mogo.och.data.db.bean.SiteDataBean
|
||||
import com.mogo.och.data.db.dao.ContrailDataDao
|
||||
import com.mogo.och.data.db.dao.LineDataDao
|
||||
import com.mogo.och.data.db.dao.SiteDataDao
|
||||
import com.mogo.och.offline.repository.db.bean.TaskSiteDataBean
|
||||
import com.mogo.och.offline.repository.db.dao.TaskDataDao
|
||||
import com.mogo.och.offline.repository.db.dao.TaskSiteDataDao
|
||||
|
||||
//注解Database告诉系统这是Room数据库对象
|
||||
//entities指定该数据库有哪些表,多张表就逗号分隔
|
||||
//version指定数据库版本号,升级时需要用到
|
||||
//数据库继承自RoomDatabase
|
||||
@Database(entities = [ContrailDataBean::class, LineDataBean::class, SiteDataBean::class, TaskSiteDataBean::class], version = 6)
|
||||
abstract class MyDataBase : RoomDatabase() {
|
||||
|
||||
override fun getOpenHelper(): SupportSQLiteOpenHelper {
|
||||
return super.getOpenHelper()
|
||||
}
|
||||
|
||||
private val dbRepositorys = mutableListOf<IDbRepository>()
|
||||
|
||||
override fun close() {
|
||||
super.close()
|
||||
dbRepositorys.forEach {
|
||||
it.release()
|
||||
}
|
||||
dbRepositorys.clear()
|
||||
}
|
||||
|
||||
fun register(iDbRepository: IDbRepository) {
|
||||
dbRepositorys.add(iDbRepository)
|
||||
}
|
||||
|
||||
abstract val contrailDataDao: ContrailDataDao?
|
||||
abstract val lineDataDao: LineDataDao?
|
||||
abstract val siteDataDao: SiteDataDao?
|
||||
|
||||
abstract val taskDataDao: TaskDataDao?
|
||||
abstract val taskSiteDataDao: TaskSiteDataDao?
|
||||
|
||||
companion object {
|
||||
|
||||
fun getDBName():MyDataBase{
|
||||
val roomName = when (ProjectUtils.getProjectType()) {
|
||||
Project.SAAS -> {
|
||||
"saas_offline_db"
|
||||
}
|
||||
Project.DALI -> {
|
||||
"dali_offline_db"
|
||||
}
|
||||
else->{
|
||||
FunctionBuildConfig.appIdentityMode
|
||||
}
|
||||
}
|
||||
|
||||
val dbFile = AbsMogoApplication.getApp().getDatabasePath(roomName)
|
||||
|
||||
return Room.databaseBuilder(
|
||||
AbsMogoApplication.getApp()!!.applicationContext,
|
||||
MyDataBase::class.java,
|
||||
dbFile.path
|
||||
)
|
||||
.fallbackToDestructiveMigration()
|
||||
.build()
|
||||
}
|
||||
|
||||
var instance: MyDataBase? = getDBName()
|
||||
get() {
|
||||
if(field==null){
|
||||
field = getDBName()
|
||||
}
|
||||
return field
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.mogo.och.offline.repository.db.bean
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.google.gson.annotations.SerializedName
|
||||
|
||||
@Entity(tableName = TaskDataBean.tableName)
|
||||
data class TaskDataBean(
|
||||
|
||||
@PrimaryKey(autoGenerate = true)
|
||||
@SerializedName("idtemp")
|
||||
var id: Int = 0,
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
@ColumnInfo(name = "task_id", typeAffinity = ColumnInfo.INTEGER, index = true)
|
||||
@SerializedName("id", alternate = ["shiftsId"])
|
||||
var taskId: Long? = null,
|
||||
|
||||
/**
|
||||
* 任务所属线路
|
||||
*/
|
||||
@ColumnInfo(name = "line_id", typeAffinity = ColumnInfo.INTEGER, index = true)
|
||||
var lineId: Long? = null,
|
||||
|
||||
/**
|
||||
* 任务开始时间
|
||||
*/
|
||||
@ColumnInfo(name = "start_time", typeAffinity = ColumnInfo.INTEGER)
|
||||
var startTime: Long = System.currentTimeMillis(),
|
||||
|
||||
/**
|
||||
* 任务结束时间
|
||||
*/
|
||||
@ColumnInfo(name = "end_time", typeAffinity = ColumnInfo.INTEGER)
|
||||
var endtime: Long? = null,
|
||||
|
||||
/**
|
||||
* 任务状态 (0 未使用) (1 运行中) (2 已使用)
|
||||
*/
|
||||
@ColumnInfo(name = "status", typeAffinity = ColumnInfo.INTEGER)
|
||||
var status: Long? = unUse,
|
||||
) {
|
||||
companion object {
|
||||
const val tableName: String = "temp_task_data_table"
|
||||
|
||||
const val unUse = 0L //未使用
|
||||
const val useing = 1L //运行中
|
||||
const val used = 2L //已使用
|
||||
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as TaskDataBean
|
||||
|
||||
if (taskId != other.taskId) return false
|
||||
if (lineId != other.lineId) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = taskId?.hashCode() ?: 0
|
||||
result = 31 * result + (lineId?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.mogo.och.offline.repository.db.bean
|
||||
|
||||
import androidx.room.ColumnInfo
|
||||
import androidx.room.Entity
|
||||
import androidx.room.PrimaryKey
|
||||
import com.mogo.och.data.db.bean.SiteDataBean
|
||||
|
||||
@Entity(tableName = TaskSiteDataBean.tableName)
|
||||
data class TaskSiteDataBean(
|
||||
|
||||
@PrimaryKey(autoGenerate = true) var id: Int = 0,
|
||||
|
||||
/**
|
||||
* 任务id
|
||||
*/
|
||||
@ColumnInfo(name = "task_id", typeAffinity = ColumnInfo.INTEGER)
|
||||
var taskId: Long? = null,
|
||||
|
||||
/**
|
||||
* 线路id
|
||||
*/
|
||||
@ColumnInfo(name = "line_id", typeAffinity = ColumnInfo.INTEGER)
|
||||
var lineId: Long? = null,
|
||||
|
||||
/**
|
||||
* 站点id
|
||||
*/
|
||||
@ColumnInfo(name = "site_id", typeAffinity = ColumnInfo.INTEGER)
|
||||
var siteId: Long? = null,
|
||||
|
||||
/**
|
||||
* 线路名称 删除线路 特殊情况下要展示线路的冗余
|
||||
*/
|
||||
@ColumnInfo(name = "line_name", typeAffinity = ColumnInfo.TEXT)
|
||||
var lineName: String? = null,
|
||||
|
||||
/**
|
||||
* 站点名称
|
||||
*/
|
||||
@ColumnInfo(name = "name", typeAffinity = ColumnInfo.TEXT)
|
||||
var name: String? = null,
|
||||
|
||||
/**
|
||||
* 站点韩文
|
||||
*/
|
||||
@ColumnInfo(name = "name_kr", typeAffinity = ColumnInfo.TEXT)
|
||||
var nameKr: String? = null,
|
||||
|
||||
/**
|
||||
* 站点排序
|
||||
*/
|
||||
@ColumnInfo(name = "seq", typeAffinity = ColumnInfo.INTEGER)
|
||||
var seq: Int? = null,
|
||||
|
||||
/**
|
||||
* 高德坐标
|
||||
*/
|
||||
@ColumnInfo(name = "gcj_lon", typeAffinity = ColumnInfo.REAL)
|
||||
var gcjLon: Double? = null,
|
||||
|
||||
/**
|
||||
* 高德坐标
|
||||
*/
|
||||
@ColumnInfo(name = "gcj_lat", typeAffinity = ColumnInfo.REAL)
|
||||
var gcjLat: Double? = null,
|
||||
|
||||
/**
|
||||
* 高精坐标
|
||||
*/
|
||||
@ColumnInfo(name = "lon", typeAffinity = ColumnInfo.REAL)
|
||||
var lon: Double? = null,
|
||||
|
||||
/**
|
||||
* 高精坐标
|
||||
*/
|
||||
@ColumnInfo(name = "lat", typeAffinity = ColumnInfo.REAL)
|
||||
var lat: Double? = null,
|
||||
|
||||
/**
|
||||
* 当前站点状态 行驶信息,0初始值;1已经过;2当前站;3未到站
|
||||
*/
|
||||
@ColumnInfo(name = "driving_status", typeAffinity = ColumnInfo.INTEGER)
|
||||
var drivingStatus: Int? = null,
|
||||
|
||||
/**
|
||||
* 是否离站
|
||||
*/
|
||||
@ColumnInfo(name = "leaving", typeAffinity = ColumnInfo.INTEGER)
|
||||
var leaving: Boolean? = null,
|
||||
|
||||
/**
|
||||
* 到站时间
|
||||
*/
|
||||
@ColumnInfo(name = "arrived_time", typeAffinity = ColumnInfo.INTEGER)
|
||||
var arrivedTime: Long? = null,
|
||||
|
||||
/**
|
||||
* 离站时间
|
||||
*/
|
||||
@ColumnInfo(name = "leave_time", typeAffinity = ColumnInfo.INTEGER)
|
||||
var leaveTime: Long? = null,
|
||||
|
||||
/**
|
||||
* 站点介绍
|
||||
*/
|
||||
@ColumnInfo(name = "introduction", typeAffinity = ColumnInfo.TEXT)
|
||||
var introduction: String? = null,
|
||||
|
||||
/**
|
||||
* 是否播放站点介绍
|
||||
*/
|
||||
@ColumnInfo(name = "is_play_tts", typeAffinity = ColumnInfo.INTEGER)
|
||||
var isPlayTts: Boolean? = null,
|
||||
|
||||
/**
|
||||
* 任务保存到数据库的时间 用来第二天删除前几天的任务
|
||||
*/
|
||||
@ColumnInfo(name = "event_save_time", typeAffinity = ColumnInfo.INTEGER)
|
||||
var eventSaveTime: Long = System.currentTimeMillis(),
|
||||
|
||||
/**
|
||||
* 站点视频
|
||||
*/
|
||||
@ColumnInfo(name = "videoList", typeAffinity = ColumnInfo.TEXT)
|
||||
var videoList: String? = null,
|
||||
|
||||
) {
|
||||
companion object {
|
||||
/**
|
||||
* 开始任务 并把第一站置为 2 当前站
|
||||
*/
|
||||
fun toTaskSiteDatas(querySites: List<SiteDataBean>, lineName: String): MutableList<TaskSiteDataBean> {
|
||||
val result = mutableListOf<TaskSiteDataBean>()
|
||||
var temp: TaskSiteDataBean?
|
||||
querySites.forEach {
|
||||
temp = TaskSiteDataBean()
|
||||
temp?.lineId = it.lineId
|
||||
temp?.lineName = lineName
|
||||
temp?.siteId = it.siteId
|
||||
temp?.name = it.name
|
||||
temp?.nameKr = it.nameKr
|
||||
temp?.seq = it.seq
|
||||
temp?.gcjLon = it.gcjLon
|
||||
temp?.gcjLat = it.gcjLat
|
||||
temp?.lon = it.lon
|
||||
temp?.lat = it.lat
|
||||
if(it.seq==1){
|
||||
temp?.drivingStatus = drivingStatusCurrent
|
||||
}else{
|
||||
temp?.drivingStatus = drivingStatusNotArrived
|
||||
}
|
||||
temp?.leaving = false
|
||||
temp?.introduction = it.introduction
|
||||
temp?.isPlayTts = it.isPlayTts
|
||||
temp?.videoList = it.videoListDB
|
||||
result.add(temp!!)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
const val tableName: String = "used_line_data_table"
|
||||
|
||||
const val drivingStatusInit = 0//0初始值
|
||||
const val drivingStatusPassed = 1//1已经过
|
||||
const val drivingStatusCurrent = 2//2当前站
|
||||
const val drivingStatusNotArrived = 3//3未到站
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.mogo.och.offline.repository.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.mogo.och.common.module.utils.DateTimeUtil
|
||||
import com.mogo.och.offline.repository.db.bean.TaskDataBean
|
||||
import io.reactivex.Observable
|
||||
|
||||
@Dao
|
||||
interface TaskDataDao {
|
||||
//插入数据
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(vararg lineDataBean: TaskDataBean)
|
||||
|
||||
//删除数据
|
||||
@Delete
|
||||
fun delete(vararg lineDataBean: TaskDataBean)
|
||||
|
||||
@Query("UPDATE ${TaskDataBean.tableName} SET start_time = :currentTimeMillis ,status = :useing WHERE id = :id")
|
||||
fun updateStatus(currentTimeMillis: Long, useing: Long, id: Int)
|
||||
|
||||
//删除非昨天添加的数据
|
||||
@Query("DELETE FROM ${TaskDataBean.tableName} WHERE start_time < :zeroTime")
|
||||
fun deleteDataByZero(zeroTime: Long): Int
|
||||
|
||||
@Query("UPDATE ${TaskDataBean.tableName} SET end_time = :endTime,status = ${TaskDataBean.used} WHERE task_id = :taskId")
|
||||
fun endTask(taskId: Long, endTime: Long = DateTimeUtil.getCurrentTimeStamp())
|
||||
|
||||
//查询当天插入的所有数据
|
||||
@Query("SELECT * FROM ${TaskDataBean.tableName} WHERE start_time > :zeroTime")
|
||||
fun loadAllData(zeroTime: Long): List<TaskDataBean>?
|
||||
|
||||
// 查询当天特定线路正在执行的任务
|
||||
@Query("SELECT * FROM ${TaskDataBean.tableName} WHERE task_get_time > :zeroTime and status = ${TaskDataBean.useing} and line_id = :lineId")
|
||||
fun queryRunningTaskByLineId(
|
||||
lineId: Long,
|
||||
zeroTime: Long = DateTimeUtil.getCurrentDateZero()
|
||||
): List<TaskDataBean>?
|
||||
|
||||
// 查询当天特定线路正在执行的任务
|
||||
@Query("SELECT * FROM ${TaskDataBean.tableName} WHERE task_get_time > :zeroTime and status = ${TaskDataBean.useing}")
|
||||
fun queryRunningTaskByStatus(zeroTime: Long = DateTimeUtil.getCurrentDateZero()): List<TaskDataBean>?
|
||||
|
||||
@Query("SELECT * FROM ${TaskDataBean.tableName} WHERE task_get_time > :zeroTime and status = ${TaskDataBean.unUse} and line_id = :lineId order by task_start_time")
|
||||
fun queryUnuseTask(
|
||||
lineId: Long,
|
||||
zeroTime: Long = DateTimeUtil.getCurrentDateZero()
|
||||
): Observable<List<TaskDataBean>?>
|
||||
|
||||
@Query("DELETE FROM ${TaskDataBean.tableName} WHERE start_time > :zeroTime and line_id = :lineId")
|
||||
fun deleteByLineId(lineId: Long, zeroTime: Long = DateTimeUtil.getCurrentDateZero())
|
||||
|
||||
@Query("SELECT * FROM ${TaskDataBean.tableName} WHERE line_id = :lineId and start_time > :zeroTime")
|
||||
fun querySitesByLineId(
|
||||
lineId: Long?,
|
||||
zeroTime: Long = DateTimeUtil.getCurrentDateZero()
|
||||
): List<TaskDataBean>?
|
||||
|
||||
//查询线路对应的轨迹信息
|
||||
@Query("SELECT * FROM ${TaskDataBean.tableName} WHERE task_id = :taskId")
|
||||
fun queryContrailByLineId(taskId: Long): List<TaskDataBean>?
|
||||
|
||||
//查询线路对应的轨迹信息
|
||||
@Query("SELECT * FROM ${TaskDataBean.tableName}")
|
||||
fun queryAllTask(): List<TaskDataBean>?
|
||||
|
||||
|
||||
// 删除过时数据
|
||||
@Query("DELETE FROM ${TaskDataBean.tableName} WHERE start_time < :zeroTime")
|
||||
fun deleteObsoleteData(zeroTime: Long = DateTimeUtil.getCurrentDateZero()): Int
|
||||
|
||||
|
||||
//查询线路对应的轨迹信息 只要一个结果
|
||||
fun queryTaskByTaskIdOne(taskId: Long): TaskDataBean? {
|
||||
val queryContrailByLineId = queryContrailByLineId(taskId)
|
||||
return if (queryContrailByLineId.isNullOrEmpty()) {
|
||||
null
|
||||
} else {
|
||||
queryContrailByLineId.first()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.mogo.och.offline.repository.db.dao
|
||||
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
import com.mogo.och.common.module.utils.DateTimeUtil
|
||||
import com.mogo.och.offline.repository.db.bean.TaskSiteDataBean
|
||||
|
||||
@Dao
|
||||
interface TaskSiteDataDao {
|
||||
//插入数据
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insert(vararg lineDataBean: TaskSiteDataBean):List<Long>
|
||||
|
||||
//查询当天插入的所有数据
|
||||
@Query("SELECT * FROM ${TaskSiteDataBean.tableName} WHERE task_id = :taskId order by seq")
|
||||
fun queryRunningTask(taskId: Long): List<TaskSiteDataBean>?
|
||||
|
||||
@Query("UPDATE ${TaskSiteDataBean.tableName} SET leaving = :leave WHERE task_id = :taskId and site_id = :siteId")
|
||||
fun updateLeave(taskId: Long, siteId: Long, leave: Int)
|
||||
|
||||
@Query("UPDATE ${TaskSiteDataBean.tableName} SET leaving = :leave , driving_status = :drivingStatusCurrent WHERE task_id = :taskId and site_id = :siteId")
|
||||
fun updateDrivingStatusANdLeave(taskId: Long, siteId: Long, drivingStatusCurrent: Int, leave: Int)
|
||||
|
||||
@Query("UPDATE ${TaskSiteDataBean.tableName} SET driving_status = :drivingStatusCurrent WHERE task_id = :taskId and site_id = :siteId")
|
||||
fun updateDrivingStatus(taskId: Long, siteId: Long, drivingStatusCurrent: Int)
|
||||
|
||||
// 删除过时数据
|
||||
@Query("DELETE FROM ${TaskSiteDataBean.tableName} WHERE event_save_time < :zeroTime")
|
||||
fun deleteObsoleteData(zeroTime: Long = DateTimeUtil.getCurrentDateZero()):Int
|
||||
|
||||
// 根据taskId删除所属站点信息
|
||||
@Query("DELETE FROM ${TaskSiteDataBean.tableName} WHERE task_id = :taskId")
|
||||
fun deleteErrorDataByTaskId(taskId: Long)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.mogo.och.offline.repository.db.repository
|
||||
|
||||
import com.mogo.och.data.db.dao.ContrailDataDao
|
||||
import com.mogo.och.data.db.repository.BaseContraiDb
|
||||
import com.mogo.och.offline.repository.db.IDbRepository
|
||||
import com.mogo.och.offline.repository.db.MyDataBase
|
||||
|
||||
object ContraiDb : IDbRepository, BaseContraiDb() {
|
||||
|
||||
override var contrailDao: ContrailDataDao?=null
|
||||
get() {
|
||||
if(field==null){
|
||||
field = MyDataBase.instance?.contrailDataDao
|
||||
register()
|
||||
}
|
||||
return field
|
||||
}
|
||||
|
||||
override fun release(){
|
||||
contrailDao = null
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package com.mogo.och.offline.repository.db.repository
|
||||
|
||||
import com.mogo.och.data.db.dao.LineDataDao
|
||||
import com.mogo.och.data.db.repository.BaseLineDb
|
||||
import com.mogo.och.offline.repository.db.IDbRepository
|
||||
import com.mogo.och.offline.repository.db.MyDataBase
|
||||
|
||||
object LineDb: IDbRepository, BaseLineDb() {
|
||||
|
||||
override var lineDao: LineDataDao?=null
|
||||
get() {
|
||||
if(field==null){
|
||||
field = MyDataBase.instance?.lineDataDao
|
||||
register()
|
||||
}
|
||||
return field
|
||||
}
|
||||
|
||||
override fun deleteSitesTaskAndContraiDb(lineId: Long) {
|
||||
SiteDb.deleteByLineId(lineId)
|
||||
}
|
||||
|
||||
|
||||
override fun release() {
|
||||
lineDao = null
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
package com.mogo.och.offline.repository.db.repository
|
||||
|
||||
import com.mogo.och.data.db.dao.SiteDataDao
|
||||
import com.mogo.och.data.db.repository.BaseSiteDb
|
||||
import com.mogo.och.offline.repository.db.IDbRepository
|
||||
import com.mogo.och.offline.repository.db.MyDataBase
|
||||
|
||||
object SiteDb: IDbRepository, BaseSiteDb() {
|
||||
|
||||
override var siteDataDao: SiteDataDao? = null
|
||||
get() {
|
||||
if(field==null){
|
||||
field = MyDataBase.instance?.siteDataDao
|
||||
register()
|
||||
}
|
||||
return field
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
siteDataDao = null
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
package com.mogo.och.offline.repository.db.repository
|
||||
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.common.module.utils.DateTimeUtil
|
||||
import com.mogo.och.data.db.exception.DbException
|
||||
import com.mogo.och.offline.repository.db.IDbRepository
|
||||
import com.mogo.och.offline.repository.db.MyDataBase
|
||||
import com.mogo.och.offline.repository.db.bean.TaskDataBean
|
||||
import com.mogo.och.offline.repository.db.dao.TaskDataDao
|
||||
import com.mogo.och.offline.repository.exception.DataException
|
||||
import io.reactivex.Observable
|
||||
|
||||
object TaskDb : IDbRepository {
|
||||
|
||||
private const val TAG = "${M_BUS}TaskDb"
|
||||
|
||||
private var taskDataDao: TaskDataDao? = null
|
||||
get() {
|
||||
if(field==null){
|
||||
field = MyDataBase.instance?.taskDataDao
|
||||
register()
|
||||
}
|
||||
return field
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
taskDataDao = null
|
||||
}
|
||||
|
||||
fun addOrUpdate(vararg lineDataBean: TaskDataBean){
|
||||
// 从接口恢复数据
|
||||
taskDataDao?.insert(*lineDataBean)
|
||||
}
|
||||
|
||||
fun addOrUpdate(serverDateList: List<TaskDataBean>, lineId: Long?) {
|
||||
val runable = object :Runnable {
|
||||
override fun run() {
|
||||
taskDataDao?.let { taskDataDao ->
|
||||
val localTasks = taskDataDao.querySitesByLineId(lineId)
|
||||
if(localTasks==null){
|
||||
taskDataDao.insert(*serverDateList.toTypedArray())
|
||||
// TODO: Ui展示需要动态刷新UI去
|
||||
return
|
||||
}
|
||||
|
||||
// 后台新增数据
|
||||
val needAddDatas = serverDateList - localTasks
|
||||
// 后台没有本地数据库有的未分配线路
|
||||
val needMinusDatas = localTasks - serverDateList
|
||||
|
||||
// TODO: Ui展示需要动态刷新UI去
|
||||
|
||||
if (needAddDatas.isNotEmpty()) {
|
||||
// 新增任务
|
||||
taskDataDao.insert(*needAddDatas.toTypedArray())
|
||||
}
|
||||
if (needMinusDatas.isNotEmpty()) {
|
||||
val needSaveTask = mutableListOf<TaskDataBean>()
|
||||
// 删除任务
|
||||
needMinusDatas.forEach {
|
||||
if(it.status==TaskDataBean.useing||it.status==TaskDataBean.used){
|
||||
needSaveTask.add(it)
|
||||
}
|
||||
}
|
||||
val failneedMinusDatas = needMinusDatas-needSaveTask
|
||||
taskDataDao.delete(*failneedMinusDatas.toTypedArray())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BizLoopManager.runInIoThread(runable)
|
||||
|
||||
}
|
||||
|
||||
fun startTask(taskId: Long, lineId: Long,lineName:String): Observable<Boolean>? {
|
||||
return Observable.just(taskId)
|
||||
.flatMap {
|
||||
var updateCount:Int? = 0
|
||||
var startTime = System.currentTimeMillis()
|
||||
try {
|
||||
// 更新task状态
|
||||
taskDataDao?.queryTaskByTaskIdOne(taskId)?.let {
|
||||
it.startTime = System.currentTimeMillis()
|
||||
it.status = TaskDataBean.useing
|
||||
// 更新任务状态
|
||||
taskDataDao?.updateStatus(System.currentTimeMillis(),TaskDataBean.useing,it.id)
|
||||
OchChainLogManager.writeChainLogDb("开始任务", "变更线路:${lineId}_${lineName}_task:${taskId} 为正在使用的状态")
|
||||
}
|
||||
CallerLogger.d(TAG,"更新任务状态用时:${System.currentTimeMillis()-startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
updateCount = TaskSiteDb.startTask(taskId, lineId, lineName)
|
||||
OchChainLogManager.writeChainLogDb("开始任务", "把正在使用的数据更新到RunningTask表格一共${updateCount}行数据")
|
||||
CallerLogger.d(TAG,"插入正在运行的线路用时:${System.currentTimeMillis()-startTime}")
|
||||
} catch (e: Exception) {
|
||||
if (e is DbException) {
|
||||
println("数据不全")
|
||||
// 恢复数据
|
||||
taskDataDao?.queryTaskByTaskIdOne(taskId)?.let {
|
||||
it.startTime = System.currentTimeMillis()
|
||||
it.status = TaskDataBean.unUse
|
||||
// 更新任务状态
|
||||
taskDataDao?.updateStatus(System.currentTimeMillis(),TaskDataBean.unUse,it.id)
|
||||
OchChainLogManager.writeChainLogDb("开始任务", "异常情况${lineId}_${lineName}_task:${taskId} 为未使用的状态 原因:${e.message}")
|
||||
}
|
||||
}
|
||||
return@flatMap Observable.error(DataException(DataException.startTaskErrorCode,e.message?:""))
|
||||
}
|
||||
updateCount?.let {
|
||||
if(it<=0){
|
||||
// 插入失败
|
||||
return@flatMap Observable.error(DataException(DataException.startTaskErrorCode,"未插入数据"))
|
||||
}else{
|
||||
// 开始任务成功
|
||||
return@flatMap Observable.just(true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun queryRunningTaskByLineId(lineId: Long): List<TaskDataBean>? {
|
||||
return taskDataDao?.queryRunningTaskByLineId(lineId)
|
||||
}
|
||||
|
||||
fun deleteByLineId(lineId: Long) {
|
||||
taskDataDao?.deleteByLineId(lineId)
|
||||
}
|
||||
|
||||
fun queryRunningTask(): List<TaskDataBean>? {
|
||||
return taskDataDao?.queryRunningTaskByStatus()
|
||||
}
|
||||
|
||||
fun queryTaskById(taskId: Long): TaskDataBean? {
|
||||
return taskDataDao?.queryTaskByTaskIdOne(taskId)
|
||||
}
|
||||
|
||||
fun queryAllTask(): List<TaskDataBean>? {
|
||||
return taskDataDao?.queryAllTask()
|
||||
}
|
||||
|
||||
|
||||
fun endTask(taskId: Long) {
|
||||
BizLoopManager.runInIoThread{
|
||||
taskDataDao?.endTask(taskId)
|
||||
}
|
||||
}
|
||||
|
||||
fun deleteObsoleteData(){
|
||||
taskDataDao?.deleteObsoleteData()?.let {
|
||||
OchChainLogManager.writeChainLogDb("删除临时数据","Task删除数量:${it}")
|
||||
}
|
||||
}
|
||||
|
||||
fun saveRunningInfo(lineId: Int, taskId: Int, taskTime: Long) {
|
||||
val runningTask = taskDataDao?.queryTaskByTaskIdOne(taskId.toLong())
|
||||
if (runningTask==null) {
|
||||
val taskDataBean = TaskDataBean()
|
||||
taskDataBean.taskId = taskId.toLong()
|
||||
taskDataBean.lineId = lineId.toLong()
|
||||
taskDataBean.status = TaskDataBean.useing
|
||||
taskDataDao?.insert(taskDataBean)
|
||||
}else{
|
||||
runningTask.status = TaskDataBean.useing
|
||||
taskDataDao?.insert(runningTask)
|
||||
}
|
||||
}
|
||||
|
||||
fun endTaskByOther(taskId: Long) {
|
||||
BizLoopManager.runInIoThread{
|
||||
val taskInfo = taskDataDao?.queryTaskByTaskIdOne(taskId)
|
||||
if(taskInfo!=null){
|
||||
if (taskInfo.status == TaskDataBean.unUse) {
|
||||
taskDataDao?.endTask(taskId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun restoreTask(taskId: Long) {
|
||||
// 更新task状态
|
||||
taskDataDao?.queryTaskByTaskIdOne(taskId)?.let {
|
||||
it.startTime = System.currentTimeMillis()
|
||||
it.status = TaskDataBean.useing
|
||||
// 更新任务状态
|
||||
taskDataDao?.updateStatus(System.currentTimeMillis(),TaskDataBean.useing,it.id)
|
||||
OchChainLogManager.writeChainLogDb("恢复任务", "线路任务改为正在执行的状态")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
package com.mogo.och.offline.repository.db.repository
|
||||
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.data.db.bean.LineDataBean
|
||||
import com.mogo.och.data.db.exception.DbException
|
||||
import com.mogo.och.offline.repository.db.IDbRepository
|
||||
import com.mogo.och.offline.repository.db.MyDataBase
|
||||
import com.mogo.och.offline.repository.db.bean.TaskSiteDataBean
|
||||
import com.mogo.och.offline.repository.db.dao.TaskSiteDataDao
|
||||
|
||||
object TaskSiteDb : IDbRepository {
|
||||
|
||||
private const val TAG = "${M_BUS}TaskSiteDb"
|
||||
|
||||
private var taskSiteDataDao: TaskSiteDataDao? = null
|
||||
get() {
|
||||
if (field == null) {
|
||||
field = MyDataBase.instance?.taskSiteDataDao
|
||||
register()
|
||||
}
|
||||
return field
|
||||
}
|
||||
|
||||
override fun release() {
|
||||
taskSiteDataDao = null
|
||||
}
|
||||
|
||||
|
||||
fun addOrUpdate(vararg lineDataBean: TaskSiteDataBean) {
|
||||
taskSiteDataDao?.insert(*lineDataBean)
|
||||
}
|
||||
|
||||
// 开始线路
|
||||
fun startTask(taskId: Long, linId: Long, lineName: String): Int? {
|
||||
// 获取线路的站点
|
||||
var startTime = System.currentTimeMillis()
|
||||
val querySites = SiteDb.querySiteByLineId(linId)?.distinctBy { it.siteId }
|
||||
if (querySites.isNullOrEmpty()) {
|
||||
throw DbException("没有站点数据")
|
||||
}
|
||||
CallerLogger.d(TAG, "查询站点用时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
val toTaskSiteDatas = TaskSiteDataBean.toTaskSiteDatas(
|
||||
querySites,
|
||||
lineName
|
||||
)
|
||||
CallerLogger.d(TAG, "数据转换用时:${System.currentTimeMillis() - startTime}")
|
||||
if (toTaskSiteDatas.size < 2) {
|
||||
throw DbException("站点数据不全请稍后再试")
|
||||
}
|
||||
// 把线路所有的站点搬迁到运行中表格中
|
||||
startTime = System.currentTimeMillis()
|
||||
val result = taskSiteDataDao?.insert(*toTaskSiteDatas.toTypedArray())
|
||||
CallerLogger.d(TAG, "数据插入用时:${System.currentTimeMillis() - startTime}")
|
||||
return if (result.isNullOrEmpty()) {
|
||||
null
|
||||
} else {
|
||||
result.size
|
||||
}
|
||||
}
|
||||
|
||||
// 滑动出发
|
||||
fun updateLeave(taskId: Long, siteId: Long, leave: Boolean) {
|
||||
BizLoopManager.runInIoThread {
|
||||
taskSiteDataDao?.updateLeave(taskId, siteId, if (leave) 1 else 0)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateDrivingStatus(taskId: Long, siteId: Long, drivingStatus: Int) {
|
||||
BizLoopManager.runInIoThread {
|
||||
taskSiteDataDao?.updateDrivingStatus(taskId, siteId, drivingStatus)
|
||||
}
|
||||
}
|
||||
|
||||
fun updateDrivingStatusAndLeave(
|
||||
taskId: Long,
|
||||
siteId: Long,
|
||||
drivingStatus: Int,
|
||||
leave: Boolean
|
||||
) {
|
||||
BizLoopManager.runInIoThread {
|
||||
taskSiteDataDao?.updateDrivingStatusANdLeave(
|
||||
taskId,
|
||||
siteId,
|
||||
drivingStatus,
|
||||
if (leave) 1 else 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun queryRunningTask(taskId: Long): List<TaskSiteDataBean>? {
|
||||
return taskSiteDataDao?.queryRunningTask(taskId)
|
||||
}
|
||||
|
||||
fun deleteErrorData(taskId: Long) {
|
||||
taskSiteDataDao?.deleteErrorDataByTaskId(taskId)
|
||||
}
|
||||
|
||||
fun deleteObsoleteData() {
|
||||
taskSiteDataDao?.deleteObsoleteData()?.let {
|
||||
OchChainLogManager.writeChainLogDb("删除临时数据", "rurnning Task删除数量:${it}")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从后台恢复正在执行的任务
|
||||
*/
|
||||
fun restoreRunningTask(
|
||||
taskId: Long,
|
||||
currentSiteId: Long,
|
||||
leaving: Boolean,
|
||||
lineInfo: LineDataBean
|
||||
) {
|
||||
val taskHistory = queryRunningTask(taskId)
|
||||
if (!taskHistory.isNullOrEmpty()) {
|
||||
//有错误数据
|
||||
deleteErrorData(taskId)
|
||||
}
|
||||
// 获取线路的站点
|
||||
val querySites = SiteDb.querySiteByLineId(lineInfo.lineId!!)?.distinctBy { it.siteId }
|
||||
if (querySites.isNullOrEmpty()) {
|
||||
throw DbException("没有站点数据")
|
||||
}
|
||||
// val toTaskSiteDatas = TaskSiteDataBean.toTaskSiteDatas(
|
||||
// querySites,
|
||||
// taskId,
|
||||
// lineInfo.lineName!!
|
||||
// )
|
||||
// val resetData = resetInfo(currentSiteId, leaving, toTaskSiteDatas)
|
||||
// 把线路所有的站点搬迁到运行中表格中
|
||||
// taskSiteDataDao?.insert(*resetData.toTypedArray())
|
||||
}
|
||||
|
||||
fun resetInfo(
|
||||
currentSiteId: Long,
|
||||
leaving: Boolean,
|
||||
runningSite: MutableList<TaskSiteDataBean>
|
||||
): MutableList<TaskSiteDataBean> {
|
||||
var currentSeq = 0
|
||||
runningSite.forEach {
|
||||
if (it.siteId == currentSiteId) {
|
||||
currentSeq = it.seq ?: 0
|
||||
it.drivingStatus = TaskSiteDataBean.drivingStatusCurrent
|
||||
it.leaving = leaving
|
||||
return@forEach
|
||||
}
|
||||
}
|
||||
runningSite.forEach {
|
||||
val seq = it.seq ?: 0
|
||||
if (seq < currentSeq) {
|
||||
it.drivingStatus = TaskSiteDataBean.drivingStatusPassed
|
||||
it.leaving = true
|
||||
} else if (seq > currentSeq) {
|
||||
it.drivingStatus = TaskSiteDataBean.drivingStatusNotArrived
|
||||
it.leaving = false
|
||||
}
|
||||
}
|
||||
return runningSite
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
package com.mogo.och.offline.repository.exception
|
||||
|
||||
class DataException: RuntimeException {
|
||||
var code:Int = 0
|
||||
var msg:String = ""
|
||||
constructor() : super()
|
||||
constructor(code:Int, message: String) : super("${code}_${message}"){
|
||||
this.code = code
|
||||
this.msg = message
|
||||
}
|
||||
|
||||
companion object{
|
||||
val startTaskErrorCode = 10010
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
package com.mogo.och.offline.net;
|
||||
import com.mogo.och.offline.bean.BindLineListResponse;
|
||||
package com.mogo.och.offline.repository.net;
|
||||
import com.mogo.och.offline.repository.net.bean.BindLineListResponse;
|
||||
|
||||
import io.reactivex.Observable;
|
||||
import retrofit2.http.GET;
|
||||
@@ -1,4 +1,4 @@
|
||||
package com.mogo.och.offline.net
|
||||
package com.mogo.och.offline.repository.net
|
||||
|
||||
import com.mogo.cloud.passport.MoGoAiCloudClientConfig
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
@@ -9,7 +9,7 @@ import com.mogo.och.common.module.constant.OchCommonConst
|
||||
import com.mogo.och.common.module.network.OchCommonServiceCallback
|
||||
import com.mogo.och.common.module.network.OchCommonSubscribeImpl
|
||||
import com.mogo.och.common.module.network.interceptor.transformIoTry
|
||||
import com.mogo.och.offline.bean.BindLineListResponse
|
||||
import com.mogo.och.offline.repository.net.bean.BindLineListResponse
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.mogo.och.offline.repository.net.bean
|
||||
|
||||
import com.mogo.eagle.core.data.BaseData
|
||||
import com.mogo.och.data.bean.BusRoutesResult
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
data class BindLineListResponse(val data: List<Result>?) : BaseData(){
|
||||
|
||||
data class Result(
|
||||
var line: LineInfo?,
|
||||
var siteList: List<BusStationBean>?,//站点名称
|
||||
val contrail: Contrail?,//站点名称
|
||||
)
|
||||
|
||||
data class LineInfo(
|
||||
val lineId:Long?,
|
||||
var lineName:String?,
|
||||
)
|
||||
|
||||
data class Contrail(
|
||||
val csvFileUrl:String?,
|
||||
val csvFileMd5:String?,
|
||||
val txtFileUrl:String?,
|
||||
val txtFileMd5:String?,
|
||||
val contrailSaveTime:Long?,
|
||||
)
|
||||
companion object{
|
||||
fun save2Db(data: BindLineListResponse) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
package com.mogo.och.offline.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.ImageView
|
||||
import android.widget.LinearLayout
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.mogo.och.common.module.utils.BlinkAnimationUtil
|
||||
import com.mogo.och.offline.R
|
||||
import kotlinx.android.synthetic.main.offline_stations_common_item.view.*
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/9/15
|
||||
*/
|
||||
class BusStationCommonItem @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : LinearLayout(context, attrs, defStyleAttr){
|
||||
|
||||
init {
|
||||
LayoutInflater.from(context).inflate(R.layout.offline_stations_common_item,this,true)
|
||||
}
|
||||
|
||||
fun setStationName(name: String){
|
||||
busStationNameTv.text = name
|
||||
}
|
||||
|
||||
fun setStationNameColor(color: Int){
|
||||
busStationNameTv.setTextColor(color)
|
||||
}
|
||||
|
||||
fun setStationPointBg(type: Int) { // 0:灰色 过站 1:绿色 到站或者即将到站 2:蓝色:未到站
|
||||
BlinkAnimationUtil.clearAnimation(busCircleIv)
|
||||
when (type) {
|
||||
0 -> {
|
||||
busCircleIvBg.visibility = GONE
|
||||
busCircleIv.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_point_grey_bus
|
||||
)
|
||||
)
|
||||
}
|
||||
1 -> {
|
||||
busCircleIvBg.visibility = VISIBLE
|
||||
busCircleIv.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_point_green_bus
|
||||
)
|
||||
)
|
||||
BlinkAnimationUtil.setAnimation(busCircleIv)
|
||||
}
|
||||
2 -> {
|
||||
busCircleIvBg.visibility = GONE
|
||||
busCircleIv.setImageDrawable(
|
||||
ContextCompat.getDrawable(
|
||||
context,
|
||||
R.drawable.icon_point_blue_bus
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun getCircleImageView() : ImageView{
|
||||
return busCircleIv
|
||||
}
|
||||
|
||||
fun setStationArrowBg(type: Int){// 0:灰色 过站 1:绿色 前往下一站 2:蓝色 未到站
|
||||
when(type){
|
||||
0 -> busArrowBg.setImageResource(R.drawable.icon_arrow_grey_bus)
|
||||
1 -> busArrowBg.setImageResource(R.drawable.icon_arrow_green_bus)
|
||||
2 -> busArrowBg.setImageResource(R.drawable.icon_arrow_blue_bus)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun setStationTag(tag: String){ // 0:起 1:终
|
||||
if (tag.isNullOrEmpty()){
|
||||
busTagTxt.visibility = GONE
|
||||
}else{
|
||||
busTagTxt.text = tag
|
||||
busTagTxt.visibility = VISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
fun showOrHideStationArrowBg(isShow:Boolean){
|
||||
if (isShow){
|
||||
busArrowBg.visibility = VISIBLE
|
||||
}else{
|
||||
busArrowBg.visibility = GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,181 +0,0 @@
|
||||
package com.mogo.och.offline.ui
|
||||
|
||||
import android.graphics.Point
|
||||
import android.os.Bundle
|
||||
import android.view.Gravity
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.WindowManager
|
||||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.commons.mvp.MvpActivity
|
||||
import com.mogo.commons.storage.SharedPrefsMgr
|
||||
import com.mogo.och.offline.presenter.BusLinePresenter
|
||||
import com.mogo.och.offline.ui.adapter.SwitchLineAdapter
|
||||
import com.mogo.och.offline.ui.adapter.OpenItemAnimator
|
||||
import com.mogo.eagle.core.utilcode.mogo.view.SpacesItemDecoration
|
||||
import com.mogo.eagle.core.utilcode.util.ToastUtils
|
||||
import com.mogo.och.offline.R
|
||||
import com.mogo.och.offline.bean.BindLineListResponse
|
||||
import java.util.ArrayList
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/8
|
||||
*/
|
||||
class BusSwitchLineActivity : MvpActivity<BusSwitchLineView?, BusLinePresenter?>(),
|
||||
View.OnClickListener, BusSwitchLineView {
|
||||
|
||||
companion object{
|
||||
const val LASTCOMMITLINEID = "lastcommitlineid"
|
||||
}
|
||||
|
||||
private lateinit var mClose: ImageView
|
||||
private lateinit var mNoDatasView: ConstraintLayout
|
||||
private lateinit var mLinesListView: RecyclerView
|
||||
private lateinit var mLineCommitBtn: TextView
|
||||
private lateinit var mAdapter: SwitchLineAdapter
|
||||
private lateinit var linearLayoutManager:LinearLayoutManager
|
||||
private val mData: MutableList<BindLineListResponse.Result> = ArrayList()
|
||||
private var checkLineInfo:BindLineListResponse.Result? = null
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.offline_switch_line
|
||||
}
|
||||
|
||||
override fun createPresenter(): BusLinePresenter {
|
||||
return BusLinePresenter(this)
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
initWH()
|
||||
initView()
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
initDatas()
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化view
|
||||
*/
|
||||
private fun initView() {
|
||||
mClose = findViewById(R.id.switch_line_close)
|
||||
mClose.setOnClickListener(this)
|
||||
mNoDatasView = findViewById(R.id.no_order_data_view)
|
||||
mLineCommitBtn = findViewById(R.id.switch_line_btn_commit)
|
||||
mLineCommitBtn.setOnClickListener(this)
|
||||
mLinesListView = findViewById(R.id.switch_line_rv)
|
||||
linearLayoutManager = LinearLayoutManager(this)
|
||||
mLinesListView.setLayoutManager(linearLayoutManager)
|
||||
mLinesListView.setItemAnimator(OpenItemAnimator())
|
||||
mAdapter = SwitchLineAdapter(applicationContext, mData)
|
||||
mLinesListView.addItemDecoration(
|
||||
SpacesItemDecoration(
|
||||
4
|
||||
)
|
||||
)
|
||||
mLinesListView.setAdapter(mAdapter)
|
||||
//设置item 点击事件
|
||||
mAdapter.setOnLineItemClickListener(object : SwitchLineAdapter.LineItemClickListener{
|
||||
override fun onItemClick(lineInfo: BindLineListResponse.Result) {
|
||||
// 选中的线路
|
||||
checkLineInfo = lineInfo
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置布局宽高
|
||||
*/
|
||||
private fun initWH() {
|
||||
val window = window
|
||||
val params = window.attributes
|
||||
val windowManager = getSystemService(WINDOW_SERVICE) as WindowManager
|
||||
val point = Point()
|
||||
windowManager.defaultDisplay.getSize(point) //用于获取屏幕高度
|
||||
params.width = (point.x * 0.375).toInt()
|
||||
params.height = ViewGroup.LayoutParams.MATCH_PARENT
|
||||
window.attributes = params
|
||||
window.setGravity(Gravity.START or Gravity.BOTTOM)
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
private fun initDatas() {
|
||||
mPresenter?.queryBusLines()
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询返回绑定路线集合
|
||||
* @param data
|
||||
*/
|
||||
override fun onBusLinesChange(data: BindLineListResponse?) {
|
||||
if (null == data) {
|
||||
showNoData(true)
|
||||
return
|
||||
}
|
||||
if (data.data != null && data.data.size > 0) {
|
||||
showNoData(false)
|
||||
mData.clear()
|
||||
mData.addAll(data.data)
|
||||
mAdapter.notifyDataSetChanged()
|
||||
} else {
|
||||
showNoData(true)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onChangeLineIdSuccess() {
|
||||
ToastUtils.showLong(resources.getString(R.string.bus_change_line_commit_tip_s))
|
||||
mPresenter?.queryBusRoutes()
|
||||
mAdapter.setOnLineItemClickListener(null)
|
||||
mPresenter?.removeListener()
|
||||
finish()
|
||||
}
|
||||
|
||||
/**
|
||||
* 有无数据UI显示
|
||||
* @param b
|
||||
*/
|
||||
private fun showNoData(b: Boolean) {
|
||||
if (b) {
|
||||
mLinesListView.visibility = View.GONE
|
||||
mLineCommitBtn.visibility = View.GONE
|
||||
mNoDatasView.visibility = View.VISIBLE
|
||||
} else {
|
||||
mLinesListView.visibility = View.VISIBLE
|
||||
mLineCommitBtn.visibility = View.VISIBLE
|
||||
mNoDatasView.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onClick(v: View) {
|
||||
//关闭dialog
|
||||
if (v.id == R.id.switch_line_close) {
|
||||
finish()
|
||||
return
|
||||
}
|
||||
//切换路线提交
|
||||
if (v.id == R.id.switch_line_btn_commit) {
|
||||
if (checkLineInfo==null) {
|
||||
ToastUtils.showLong("请选择任务")
|
||||
}else{
|
||||
mPresenter?.commitSwitchLineId(checkLineInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
mPresenter!!.removeListener()
|
||||
super.onDestroy()
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
package com.mogo.och.offline.ui;
|
||||
|
||||
import com.mogo.commons.mvp.IView;
|
||||
import com.mogo.och.offline.bean.BindLineListResponse;
|
||||
|
||||
/**
|
||||
* @author: wangmingjun
|
||||
* @date: 2022/2/10
|
||||
*/
|
||||
public interface BusSwitchLineView extends IView {
|
||||
|
||||
void onBusLinesChange(BindLineListResponse data);
|
||||
void onChangeLineIdSuccess();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,643 +0,0 @@
|
||||
package com.mogo.och.offline.ui.adapter;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.animation.TimeInterpolator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.view.View;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.core.view.ViewCompat;
|
||||
import androidx.recyclerview.widget.DefaultItemAnimator;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
import androidx.recyclerview.widget.SimpleItemAnimator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This implementation of {@link RecyclerView.ItemAnimator} provides basic
|
||||
* animations on remove, add, and move events that happen to the items in
|
||||
* a RecyclerView. RecyclerView uses a DefaultItemAnimator by default.
|
||||
*
|
||||
* @see RecyclerView#setItemAnimator(RecyclerView.ItemAnimator)
|
||||
*/
|
||||
public class OpenItemAnimator extends DefaultItemAnimator {
|
||||
private static final boolean DEBUG = false;
|
||||
|
||||
private static TimeInterpolator sDefaultInterpolator;
|
||||
|
||||
private final ArrayList<RecyclerView.ViewHolder> mPendingRemovals = new ArrayList<>();
|
||||
private final ArrayList<RecyclerView.ViewHolder> mPendingAdditions = new ArrayList<>();
|
||||
private final ArrayList<MoveInfo> mPendingMoves = new ArrayList<>();
|
||||
private final ArrayList<ChangeInfo> mPendingChanges = new ArrayList<>();
|
||||
|
||||
ArrayList<ArrayList<RecyclerView.ViewHolder>> mAdditionsList = new ArrayList<>();
|
||||
ArrayList<ArrayList<MoveInfo>> mMovesList = new ArrayList<>();
|
||||
ArrayList<ArrayList<ChangeInfo>> mChangesList = new ArrayList<>();
|
||||
|
||||
ArrayList<RecyclerView.ViewHolder> mAddAnimations = new ArrayList<>();
|
||||
ArrayList<RecyclerView.ViewHolder> mMoveAnimations = new ArrayList<>();
|
||||
ArrayList<RecyclerView.ViewHolder> mRemoveAnimations = new ArrayList<>();
|
||||
ArrayList<RecyclerView.ViewHolder> mChangeAnimations = new ArrayList<>();
|
||||
|
||||
private static class MoveInfo {
|
||||
public RecyclerView.ViewHolder holder;
|
||||
public int fromX, fromY, toX, toY;
|
||||
|
||||
MoveInfo(RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
|
||||
this.holder = holder;
|
||||
this.fromX = fromX;
|
||||
this.fromY = fromY;
|
||||
this.toX = toX;
|
||||
this.toY = toY;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ChangeInfo {
|
||||
public RecyclerView.ViewHolder oldHolder, newHolder;
|
||||
public int fromX, fromY, toX, toY;
|
||||
private ChangeInfo(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder) {
|
||||
this.oldHolder = oldHolder;
|
||||
this.newHolder = newHolder;
|
||||
}
|
||||
|
||||
ChangeInfo(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder,
|
||||
int fromX, int fromY, int toX, int toY) {
|
||||
this(oldHolder, newHolder);
|
||||
this.fromX = fromX;
|
||||
this.fromY = fromY;
|
||||
this.toX = toX;
|
||||
this.toY = toY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "ChangeInfo{"
|
||||
+ "oldHolder=" + oldHolder
|
||||
+ ", newHolder=" + newHolder
|
||||
+ ", fromX=" + fromX
|
||||
+ ", fromY=" + fromY
|
||||
+ ", toX=" + toX
|
||||
+ ", toY=" + toY
|
||||
+ '}';
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runPendingAnimations() {
|
||||
boolean removalsPending = !mPendingRemovals.isEmpty();
|
||||
boolean movesPending = !mPendingMoves.isEmpty();
|
||||
boolean changesPending = !mPendingChanges.isEmpty();
|
||||
boolean additionsPending = !mPendingAdditions.isEmpty();
|
||||
if (!removalsPending && !movesPending && !additionsPending && !changesPending) {
|
||||
// nothing to animate
|
||||
return;
|
||||
}
|
||||
// First, remove stuff
|
||||
for (RecyclerView.ViewHolder holder : mPendingRemovals) {
|
||||
animateRemoveImpl(holder);
|
||||
}
|
||||
mPendingRemovals.clear();
|
||||
// Next, move stuff
|
||||
if (movesPending) {
|
||||
final ArrayList<MoveInfo> moves = new ArrayList<>(mPendingMoves);
|
||||
mMovesList.add(moves);
|
||||
mPendingMoves.clear();
|
||||
Runnable mover = () -> {
|
||||
for (MoveInfo moveInfo : moves) {
|
||||
animateMoveImpl(moveInfo.holder, moveInfo.fromX, moveInfo.fromY,
|
||||
moveInfo.toX, moveInfo.toY);
|
||||
}
|
||||
moves.clear();
|
||||
mMovesList.remove(moves);
|
||||
};
|
||||
if (removalsPending) {
|
||||
View view = moves.get(0).holder.itemView;
|
||||
ViewCompat.postOnAnimationDelayed(view, mover, getRemoveDuration());
|
||||
} else {
|
||||
mover.run();
|
||||
}
|
||||
}
|
||||
// Next, change stuff, to run in parallel with move animations
|
||||
if (changesPending) {
|
||||
final ArrayList<ChangeInfo> changes = new ArrayList<>(mPendingChanges);
|
||||
mChangesList.add(changes);
|
||||
mPendingChanges.clear();
|
||||
Runnable changer = () -> {
|
||||
for (ChangeInfo change : changes) {
|
||||
animateChangeImpl(change);
|
||||
}
|
||||
changes.clear();
|
||||
mChangesList.remove(changes);
|
||||
};
|
||||
if (removalsPending) {
|
||||
RecyclerView.ViewHolder holder = changes.get(0).oldHolder;
|
||||
ViewCompat.postOnAnimationDelayed(holder.itemView, changer, getRemoveDuration());
|
||||
} else {
|
||||
changer.run();
|
||||
}
|
||||
}
|
||||
// Next, add stuff
|
||||
if (additionsPending) {
|
||||
final ArrayList<RecyclerView.ViewHolder> additions = new ArrayList<>(mPendingAdditions);
|
||||
mAdditionsList.add(additions);
|
||||
mPendingAdditions.clear();
|
||||
Runnable adder = () -> {
|
||||
for (RecyclerView.ViewHolder holder : additions) {
|
||||
animateAddImpl(holder);
|
||||
}
|
||||
additions.clear();
|
||||
mAdditionsList.remove(additions);
|
||||
};
|
||||
if (removalsPending || movesPending || changesPending) {
|
||||
long removeDuration = removalsPending ? getRemoveDuration() : 0;
|
||||
long moveDuration = movesPending ? getMoveDuration() : 0;
|
||||
long changeDuration = changesPending ? getChangeDuration() : 0;
|
||||
long totalDelay = removeDuration + Math.max(moveDuration, changeDuration);
|
||||
View view = additions.get(0).itemView;
|
||||
ViewCompat.postOnAnimationDelayed(view, adder, totalDelay);
|
||||
} else {
|
||||
adder.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean animateRemove(final RecyclerView.ViewHolder holder) {
|
||||
resetAnimation(holder);
|
||||
mPendingRemovals.add(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void animateRemoveImpl(final RecyclerView.ViewHolder holder) {
|
||||
final View view = holder.itemView;
|
||||
final ViewPropertyAnimator animation = view.animate();
|
||||
mRemoveAnimations.add(holder);
|
||||
animation.setDuration(getRemoveDuration()).alpha(0).setListener(
|
||||
new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
dispatchRemoveStarting(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
animation.setListener(null);
|
||||
view.setAlpha(1);
|
||||
dispatchRemoveFinished(holder);
|
||||
mRemoveAnimations.remove(holder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean animateAdd(final RecyclerView.ViewHolder holder) {
|
||||
resetAnimation(holder);
|
||||
holder.itemView.setAlpha(0);
|
||||
mPendingAdditions.add(holder);
|
||||
return true;
|
||||
}
|
||||
|
||||
void animateAddImpl(final RecyclerView.ViewHolder holder) {
|
||||
final View view = holder.itemView;
|
||||
final ViewPropertyAnimator animation = view.animate();
|
||||
mAddAnimations.add(holder);
|
||||
animation.alpha(1).setDuration(getAddDuration())
|
||||
.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
dispatchAddStarting(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animator) {
|
||||
view.setAlpha(1);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
animation.setListener(null);
|
||||
dispatchAddFinished(holder);
|
||||
mAddAnimations.remove(holder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean animateMove(final RecyclerView.ViewHolder holder, int fromX, int fromY,
|
||||
int toX, int toY) {
|
||||
final View view = holder.itemView;
|
||||
fromX += (int) holder.itemView.getTranslationX();
|
||||
fromY += (int) holder.itemView.getTranslationY();
|
||||
resetAnimation(holder);
|
||||
int deltaX = toX - fromX;
|
||||
int deltaY = toY - fromY;
|
||||
if (deltaX == 0 && deltaY == 0) {
|
||||
dispatchMoveFinished(holder);
|
||||
return false;
|
||||
}
|
||||
if (deltaX != 0) {
|
||||
view.setTranslationX(-deltaX);
|
||||
}
|
||||
if (deltaY != 0) {
|
||||
view.setTranslationY(-deltaY);
|
||||
}
|
||||
mPendingMoves.add(new MoveInfo(holder, fromX, fromY, toX, toY));
|
||||
return true;
|
||||
}
|
||||
|
||||
void animateMoveImpl(final RecyclerView.ViewHolder holder, int fromX, int fromY, int toX, int toY) {
|
||||
final View view = holder.itemView;
|
||||
final int deltaX = toX - fromX;
|
||||
final int deltaY = toY - fromY;
|
||||
if (deltaX != 0) {
|
||||
view.animate().translationX(0);
|
||||
}
|
||||
if (deltaY != 0) {
|
||||
view.animate().translationY(0);
|
||||
}
|
||||
// TODO: make EndActions end listeners instead, since end actions aren't called when
|
||||
// vpas are canceled (and can't end them. why?)
|
||||
// need listener functionality in VPACompat for this. Ick.
|
||||
final ViewPropertyAnimator animation = view.animate();
|
||||
mMoveAnimations.add(holder);
|
||||
animation.setDuration(getMoveDuration()).setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
dispatchMoveStarting(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animator) {
|
||||
if (deltaX != 0) {
|
||||
view.setTranslationX(0);
|
||||
}
|
||||
if (deltaY != 0) {
|
||||
view.setTranslationY(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
animation.setListener(null);
|
||||
dispatchMoveFinished(holder);
|
||||
mMoveAnimations.remove(holder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean animateChange(RecyclerView.ViewHolder oldHolder, RecyclerView.ViewHolder newHolder,
|
||||
int fromX, int fromY, int toX, int toY) {
|
||||
if (oldHolder == newHolder) {
|
||||
// Don't know how to run change animations when the same view holder is re-used.
|
||||
// run a move animation to handle position changes.
|
||||
return animateMove(oldHolder, fromX, fromY, toX, toY);
|
||||
}
|
||||
final float prevTranslationX = oldHolder.itemView.getTranslationX();
|
||||
final float prevTranslationY = oldHolder.itemView.getTranslationY();
|
||||
final float prevAlpha = oldHolder.itemView.getAlpha();
|
||||
resetAnimation(oldHolder);
|
||||
int deltaX = (int) (toX - fromX - prevTranslationX);
|
||||
int deltaY = (int) (toY - fromY - prevTranslationY);
|
||||
// recover prev translation state after ending animation
|
||||
oldHolder.itemView.setTranslationX(prevTranslationX);
|
||||
oldHolder.itemView.setTranslationY(prevTranslationY);
|
||||
oldHolder.itemView.setAlpha(prevAlpha);
|
||||
if (newHolder != null) {
|
||||
// carry over translation values
|
||||
resetAnimation(newHolder);
|
||||
newHolder.itemView.setTranslationX(-deltaX);
|
||||
newHolder.itemView.setTranslationY(-deltaY);
|
||||
newHolder.itemView.setAlpha(0);
|
||||
}
|
||||
mPendingChanges.add(new ChangeInfo(oldHolder, newHolder, fromX, fromY, toX, toY));
|
||||
return true;
|
||||
}
|
||||
|
||||
void animateChangeImpl(final ChangeInfo changeInfo) {
|
||||
final RecyclerView.ViewHolder holder = changeInfo.oldHolder;
|
||||
final View view = holder == null ? null : holder.itemView;
|
||||
final RecyclerView.ViewHolder newHolder = changeInfo.newHolder;
|
||||
final View newView = newHolder != null ? newHolder.itemView : null;
|
||||
if (view != null) {
|
||||
final ViewPropertyAnimator oldViewAnim = view.animate().setDuration(
|
||||
getChangeDuration());
|
||||
mChangeAnimations.add(changeInfo.oldHolder);
|
||||
oldViewAnim.translationX((float)(changeInfo.toX - changeInfo.fromX));
|
||||
oldViewAnim.translationY((float)(changeInfo.toY - changeInfo.fromY));
|
||||
oldViewAnim.alpha(0).setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
dispatchChangeStarting(changeInfo.oldHolder, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
oldViewAnim.setListener(null);
|
||||
view.setAlpha(1);
|
||||
view.setTranslationX(0);
|
||||
view.setTranslationY(0);
|
||||
dispatchChangeFinished(changeInfo.oldHolder, true);
|
||||
mChangeAnimations.remove(changeInfo.oldHolder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
if (newView != null) {
|
||||
final ViewPropertyAnimator newViewAnimation = newView.animate();
|
||||
mChangeAnimations.add(changeInfo.newHolder);
|
||||
newViewAnimation.translationX(0).translationY(0).setDuration(getChangeDuration())
|
||||
.alpha(1).setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animator) {
|
||||
dispatchChangeStarting(changeInfo.newHolder, false);
|
||||
}
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
newViewAnimation.setListener(null);
|
||||
newView.setAlpha(1);
|
||||
newView.setTranslationX(0);
|
||||
newView.setTranslationY(0);
|
||||
dispatchChangeFinished(changeInfo.newHolder, false);
|
||||
mChangeAnimations.remove(changeInfo.newHolder);
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
}).start();
|
||||
}
|
||||
}
|
||||
|
||||
private void endChangeAnimation(List<ChangeInfo> infoList, RecyclerView.ViewHolder item) {
|
||||
for (int i = infoList.size() - 1; i >= 0; i--) {
|
||||
ChangeInfo changeInfo = infoList.get(i);
|
||||
if (endChangeAnimationIfNecessary(changeInfo, item)) {
|
||||
if (changeInfo.oldHolder == null && changeInfo.newHolder == null) {
|
||||
infoList.remove(changeInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void endChangeAnimationIfNecessary(ChangeInfo changeInfo) {
|
||||
if (changeInfo.oldHolder != null) {
|
||||
endChangeAnimationIfNecessary(changeInfo, changeInfo.oldHolder);
|
||||
}
|
||||
if (changeInfo.newHolder != null) {
|
||||
endChangeAnimationIfNecessary(changeInfo, changeInfo.newHolder);
|
||||
}
|
||||
}
|
||||
private boolean endChangeAnimationIfNecessary(ChangeInfo changeInfo, RecyclerView.ViewHolder item) {
|
||||
boolean oldItem = false;
|
||||
if (changeInfo.newHolder == item) {
|
||||
changeInfo.newHolder = null;
|
||||
} else if (changeInfo.oldHolder == item) {
|
||||
changeInfo.oldHolder = null;
|
||||
oldItem = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
item.itemView.setAlpha(1);
|
||||
item.itemView.setTranslationX(0);
|
||||
item.itemView.setTranslationY(0);
|
||||
dispatchChangeFinished(item, oldItem);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endAnimation(RecyclerView.ViewHolder item) {
|
||||
final View view = item.itemView;
|
||||
// this will trigger end callback which should set properties to their target values.
|
||||
view.animate().cancel();
|
||||
// TODO if some other animations are chained to end, how do we cancel them as well?
|
||||
for (int i = mPendingMoves.size() - 1; i >= 0; i--) {
|
||||
MoveInfo moveInfo = mPendingMoves.get(i);
|
||||
if (moveInfo.holder == item) {
|
||||
view.setTranslationY(0);
|
||||
view.setTranslationX(0);
|
||||
dispatchMoveFinished(item);
|
||||
mPendingMoves.remove(i);
|
||||
}
|
||||
}
|
||||
endChangeAnimation(mPendingChanges, item);
|
||||
if (mPendingRemovals.remove(item)) {
|
||||
view.setAlpha(1);
|
||||
dispatchRemoveFinished(item);
|
||||
}
|
||||
if (mPendingAdditions.remove(item)) {
|
||||
view.setAlpha(1);
|
||||
dispatchAddFinished(item);
|
||||
}
|
||||
|
||||
for (int i = mChangesList.size() - 1; i >= 0; i--) {
|
||||
ArrayList<ChangeInfo> changes = mChangesList.get(i);
|
||||
endChangeAnimation(changes, item);
|
||||
if (changes.isEmpty()) {
|
||||
mChangesList.remove(i);
|
||||
}
|
||||
}
|
||||
for (int i = mMovesList.size() - 1; i >= 0; i--) {
|
||||
ArrayList<MoveInfo> moves = mMovesList.get(i);
|
||||
for (int j = moves.size() - 1; j >= 0; j--) {
|
||||
MoveInfo moveInfo = moves.get(j);
|
||||
if (moveInfo.holder == item) {
|
||||
view.setTranslationY(0);
|
||||
view.setTranslationX(0);
|
||||
dispatchMoveFinished(item);
|
||||
moves.remove(j);
|
||||
if (moves.isEmpty()) {
|
||||
mMovesList.remove(i);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = mAdditionsList.size() - 1; i >= 0; i--) {
|
||||
ArrayList<RecyclerView.ViewHolder> additions = mAdditionsList.get(i);
|
||||
if (additions.remove(item)) {
|
||||
view.setAlpha(1);
|
||||
dispatchAddFinished(item);
|
||||
if (additions.isEmpty()) {
|
||||
mAdditionsList.remove(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// animations should be ended by the cancel above.
|
||||
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||
if (mRemoveAnimations.remove(item) && DEBUG) {
|
||||
throw new IllegalStateException("after animation is cancelled, item should not be in "
|
||||
+ "mRemoveAnimations list");
|
||||
}
|
||||
|
||||
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||
if (mAddAnimations.remove(item) && DEBUG) {
|
||||
throw new IllegalStateException("after animation is cancelled, item should not be in "
|
||||
+ "mAddAnimations list");
|
||||
}
|
||||
|
||||
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||
if (mChangeAnimations.remove(item) && DEBUG) {
|
||||
throw new IllegalStateException("after animation is cancelled, item should not be in "
|
||||
+ "mChangeAnimations list");
|
||||
}
|
||||
|
||||
//noinspection PointlessBooleanExpression,ConstantConditions
|
||||
if (mMoveAnimations.remove(item) && DEBUG) {
|
||||
throw new IllegalStateException("after animation is cancelled, item should not be in "
|
||||
+ "mMoveAnimations list");
|
||||
}
|
||||
dispatchFinishedWhenDone();
|
||||
}
|
||||
|
||||
private void resetAnimation(RecyclerView.ViewHolder holder) {
|
||||
if (sDefaultInterpolator == null) {
|
||||
sDefaultInterpolator = new ValueAnimator().getInterpolator();
|
||||
}
|
||||
holder.itemView.animate().setInterpolator(sDefaultInterpolator);
|
||||
endAnimation(holder);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return (!mPendingAdditions.isEmpty()
|
||||
|| !mPendingChanges.isEmpty()
|
||||
|| !mPendingMoves.isEmpty()
|
||||
|| !mPendingRemovals.isEmpty()
|
||||
|| !mMoveAnimations.isEmpty()
|
||||
|| !mRemoveAnimations.isEmpty()
|
||||
|| !mAddAnimations.isEmpty()
|
||||
|| !mChangeAnimations.isEmpty()
|
||||
|| !mMovesList.isEmpty()
|
||||
|| !mAdditionsList.isEmpty()
|
||||
|| !mChangesList.isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the state of currently pending and running animations. If there are none
|
||||
* pending/running, call {@link #dispatchAnimationsFinished()} to notify any
|
||||
* listeners.
|
||||
*/
|
||||
void dispatchFinishedWhenDone() {
|
||||
if (!isRunning()) {
|
||||
dispatchAnimationsFinished();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void endAnimations() {
|
||||
int count = mPendingMoves.size();
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
MoveInfo item = mPendingMoves.get(i);
|
||||
View view = item.holder.itemView;
|
||||
view.setTranslationY(0);
|
||||
view.setTranslationX(0);
|
||||
dispatchMoveFinished(item.holder);
|
||||
mPendingMoves.remove(i);
|
||||
}
|
||||
count = mPendingRemovals.size();
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
RecyclerView.ViewHolder item = mPendingRemovals.get(i);
|
||||
dispatchRemoveFinished(item);
|
||||
mPendingRemovals.remove(i);
|
||||
}
|
||||
count = mPendingAdditions.size();
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
RecyclerView.ViewHolder item = mPendingAdditions.get(i);
|
||||
item.itemView.setAlpha(1);
|
||||
dispatchAddFinished(item);
|
||||
mPendingAdditions.remove(i);
|
||||
}
|
||||
count = mPendingChanges.size();
|
||||
for (int i = count - 1; i >= 0; i--) {
|
||||
endChangeAnimationIfNecessary(mPendingChanges.get(i));
|
||||
}
|
||||
mPendingChanges.clear();
|
||||
if (!isRunning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
int listCount = mMovesList.size();
|
||||
for (int i = listCount - 1; i >= 0; i--) {
|
||||
ArrayList<MoveInfo> moves = mMovesList.get(i);
|
||||
count = moves.size();
|
||||
for (int j = count - 1; j >= 0; j--) {
|
||||
MoveInfo moveInfo = moves.get(j);
|
||||
RecyclerView.ViewHolder item = moveInfo.holder;
|
||||
View view = item.itemView;
|
||||
view.setTranslationY(0);
|
||||
view.setTranslationX(0);
|
||||
dispatchMoveFinished(moveInfo.holder);
|
||||
moves.remove(j);
|
||||
if (moves.isEmpty()) {
|
||||
mMovesList.remove(moves);
|
||||
}
|
||||
}
|
||||
}
|
||||
listCount = mAdditionsList.size();
|
||||
for (int i = listCount - 1; i >= 0; i--) {
|
||||
ArrayList<RecyclerView.ViewHolder> additions = mAdditionsList.get(i);
|
||||
count = additions.size();
|
||||
for (int j = count - 1; j >= 0; j--) {
|
||||
RecyclerView.ViewHolder item = additions.get(j);
|
||||
View view = item.itemView;
|
||||
view.setAlpha(1);
|
||||
dispatchAddFinished(item);
|
||||
additions.remove(j);
|
||||
if (additions.isEmpty()) {
|
||||
mAdditionsList.remove(additions);
|
||||
}
|
||||
}
|
||||
}
|
||||
listCount = mChangesList.size();
|
||||
for (int i = listCount - 1; i >= 0; i--) {
|
||||
ArrayList<ChangeInfo> changes = mChangesList.get(i);
|
||||
count = changes.size();
|
||||
for (int j = count - 1; j >= 0; j--) {
|
||||
endChangeAnimationIfNecessary(changes.get(j));
|
||||
if (changes.isEmpty()) {
|
||||
mChangesList.remove(changes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cancelAll(mRemoveAnimations);
|
||||
cancelAll(mMoveAnimations);
|
||||
cancelAll(mAddAnimations);
|
||||
cancelAll(mChangeAnimations);
|
||||
|
||||
dispatchAnimationsFinished();
|
||||
}
|
||||
|
||||
void cancelAll(List<RecyclerView.ViewHolder> viewHolders) {
|
||||
for (int i = viewHolders.size() - 1; i >= 0; i--) {
|
||||
viewHolders.get(i).itemView.animate().cancel();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>
|
||||
* If the payload list is not empty, DefaultItemAnimator returns <code>true</code>.
|
||||
* When this is the case:
|
||||
* <ul>
|
||||
* <li>If you override {@link #animateChange(RecyclerView.ViewHolder, RecyclerView.ViewHolder, int, int, int, int)}, both
|
||||
* ViewHolder arguments will be the same instance.
|
||||
* </li>
|
||||
* <li>
|
||||
* If you are not overriding {@link #animateChange(RecyclerView.ViewHolder, RecyclerView.ViewHolder, int, int, int, int)},
|
||||
* then DefaultItemAnimator will call {@link #animateMove(RecyclerView.ViewHolder, int, int, int, int)} and
|
||||
* run a move animation instead.
|
||||
* </li>
|
||||
* </ul>
|
||||
*/
|
||||
@Override
|
||||
public boolean canReuseUpdatedViewHolder(@NonNull RecyclerView.ViewHolder viewHolder,
|
||||
@NonNull List<Object> payloads) {
|
||||
return !payloads.isEmpty() || super.canReuseUpdatedViewHolder(viewHolder, payloads);
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
package com.mogo.och.offline.ui.adapter
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.ImageView
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.och.offline.R
|
||||
import com.mogo.och.offline.bean.BindLineListResponse
|
||||
import com.mogo.och.offline.ui.adapter.SwitchLineAdapter.SwitchLineViewHolder
|
||||
import kotlin.text.StringBuilder
|
||||
|
||||
/**
|
||||
* 路线列表adapter
|
||||
*/
|
||||
class SwitchLineAdapter(
|
||||
private val mContext: Context,
|
||||
private val mData: List<BindLineListResponse.Result>
|
||||
) : RecyclerView.Adapter<SwitchLineViewHolder>() {
|
||||
companion object{
|
||||
const val TAG = "SwitchLineAdapter"
|
||||
}
|
||||
// RecyclerView设置点击事件
|
||||
private var mItemClickListener: LineItemClickListener? = null
|
||||
private var checkInfo:BindLineListResponse.Result? = null
|
||||
override fun onCreateViewHolder(
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
): SwitchLineViewHolder {
|
||||
val view = LayoutInflater.from(mContext).inflate(
|
||||
R.layout.offline_switch_line_list_item, parent, false
|
||||
)
|
||||
return SwitchLineViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: SwitchLineViewHolder, position: Int) {
|
||||
val currentPosition = holder.bindingAdapterPosition
|
||||
val lineInfo = mData[currentPosition]
|
||||
|
||||
if (lineInfo==checkInfo) {
|
||||
holder.itemView.setBackgroundResource(R.drawable.bus_shape_select_line_item_bg_normal)
|
||||
} else {
|
||||
holder.itemView.setBackgroundColor(Color.parseColor("#162761"))
|
||||
}
|
||||
|
||||
lineInfo.line?.let {line->
|
||||
line.lineName?.let {
|
||||
if(it.length>10){
|
||||
holder.linelineName.text = it.substring(0,10)+"…"
|
||||
}else{
|
||||
holder.linelineName.text = lineInfo.line?.lineName
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
lineInfo.siteList?.let {
|
||||
val last = it.last()
|
||||
last.name?.let {siteName->
|
||||
val sb = StringBuilder()
|
||||
if (siteName.length>10) {
|
||||
sb.append(siteName.substring(0,5))
|
||||
sb.append("…")
|
||||
sb.append(siteName.substring(siteName.length-5,siteName.length))
|
||||
}else{
|
||||
sb.append(siteName)
|
||||
}
|
||||
val string = mContext.getString(R.string.bus_line_goto_end, sb.toString())
|
||||
holder.lineEndlineName.text = string
|
||||
}
|
||||
}
|
||||
|
||||
//设置item点击事件
|
||||
holder.itemView.setOnClickListener {
|
||||
val oldPosition = mData.indexOf(checkInfo)
|
||||
checkInfo = lineInfo
|
||||
notifyItemChanged(oldPosition)
|
||||
notifyItemChanged(currentPosition)
|
||||
mItemClickListener?.onItemClick(lineInfo)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return mData.size
|
||||
}
|
||||
|
||||
fun setOnLineItemClickListener(itemClickListener: LineItemClickListener?) {
|
||||
mItemClickListener = itemClickListener
|
||||
}
|
||||
|
||||
class SwitchLineViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val linelineName: AppCompatTextView//线路名称
|
||||
val lineEndlineName: AppCompatTextView //终点
|
||||
|
||||
init {
|
||||
linelineName = itemView.findViewById(R.id.switch_line_name)
|
||||
lineEndlineName = itemView.findViewById(R.id.switch_line_end_station)
|
||||
}
|
||||
}
|
||||
|
||||
interface LineItemClickListener {
|
||||
fun onItemClick(lineInfo: BindLineListResponse.Result)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
package com.mogo.och.offline.ui.bizswitch
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.findViewTreeViewModelStoreOwner
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.common.module.utils.RxUtils
|
||||
import com.mogo.och.common.module.wigets.WindowRelativeLayout
|
||||
import com.mogo.och.offline.R
|
||||
import io.reactivex.disposables.Disposable
|
||||
import kotlinx.android.synthetic.main.offline_switch_biz.view.loading_biz
|
||||
import kotlinx.android.synthetic.main.offline_switch_biz.view.swtichLine
|
||||
import kotlinx.android.synthetic.main.offline_switch_biz.view.taskRunning
|
||||
|
||||
class SwitchBizView: WindowRelativeLayout, SwtichBizModel.SwtichLineViewCallback {
|
||||
|
||||
|
||||
constructor(context: Context?) : super(context)
|
||||
|
||||
constructor(context: Context?, attributeSet: AttributeSet) : super(context, attributeSet)
|
||||
|
||||
constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
|
||||
|
||||
constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
|
||||
|
||||
|
||||
companion object {
|
||||
const val TAG = M_BUS+"SwitchBizView"
|
||||
}
|
||||
|
||||
private var viewModel: SwtichBizModel?=null
|
||||
|
||||
private var queryTimeout: Disposable? = null
|
||||
|
||||
|
||||
init {
|
||||
LayoutInflater.from(context).inflate(R.layout.offline_switch_biz, this, true)
|
||||
initView()
|
||||
}
|
||||
|
||||
private fun initView(){
|
||||
loading_biz.setEmptyText(ResourcesUtils.getString(R.string.offline_switch_biz_loading))
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
CallerLogger.d(TAG,"SwitchBizView:onAttachedToWindow")
|
||||
super.onAttachedToWindow()
|
||||
viewModel = findViewTreeViewModelStoreOwner()?.let {
|
||||
ViewModelProvider(it)[SwtichBizModel::class.java]
|
||||
}
|
||||
viewModel?.setSwitchBizCallback(this)
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
CallerLogger.d(TAG,"SwitchBizView:onDetachedFromWindow")
|
||||
}
|
||||
|
||||
var startLoading = System.currentTimeMillis()
|
||||
|
||||
/**
|
||||
* 展示loading页面
|
||||
* 1、
|
||||
* 2、第一次加载页面时展示
|
||||
* 3、
|
||||
*/
|
||||
override fun showLoadingView(){
|
||||
startLoading = System.currentTimeMillis()
|
||||
CallerLogger.d(TAG,"开始展示 lading 时间:${startLoading}")
|
||||
loading_biz.visibility = VISIBLE
|
||||
swtichLine.visibility = GONE
|
||||
queryTimeout = RxUtils.createSubscribe(10_1000) {
|
||||
OchChainLogManager.writeChainLog("Loading超时","loading 展示了10s")
|
||||
CallerLogger.d(TAG,"Loading超时:loading 展示了10s")
|
||||
viewModel?.queryRuningTask()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
override fun loadLineData() {
|
||||
swtichLine.loadingDatas()
|
||||
}
|
||||
|
||||
// 展示选择线路页面
|
||||
override fun showSwtichLineView() {
|
||||
RxUtils.disposeSubscribe(queryTimeout)
|
||||
val endLoading = System.currentTimeMillis()
|
||||
val dex = (100-(endLoading - startLoading)).takeIf { it>=0 }?:0
|
||||
CallerLogger.d(TAG,"展示线路 lading 展示了 ${dex}毫秒")
|
||||
ThreadUtils.runOnUiThreadDelayed({
|
||||
loading_biz.visibility = GONE
|
||||
swtichLine.visibility = VISIBLE
|
||||
taskRunning.visibility = GONE
|
||||
},dex,ThreadUtils.MODE.QUEUE)
|
||||
|
||||
}
|
||||
// 展示正在进行的任务
|
||||
override fun loadRunningTask() {
|
||||
RxUtils.disposeSubscribe(queryTimeout)
|
||||
val endLoading = System.currentTimeMillis()
|
||||
val dex = (100-(endLoading - startLoading)).takeIf { it>=0 }?:0
|
||||
CallerLogger.d(TAG,"展示运行中任务 lading 展示了 ${dex}毫秒")
|
||||
ThreadUtils.runOnUiThreadDelayed({
|
||||
loading_biz.visibility = GONE
|
||||
swtichLine.visibility = GONE
|
||||
taskRunning.visibility = VISIBLE
|
||||
taskRunning.showRunningTaskInfo()
|
||||
},dex,ThreadUtils.MODE.QUEUE)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
package com.mogo.och.offline.ui.bizswitch
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils
|
||||
import com.mogo.och.offline.callback.IBusLinesCallback
|
||||
import com.mogo.och.offline.model.LineModel
|
||||
import com.mogo.och.offline.model.OrderModel
|
||||
|
||||
/**
|
||||
* @author XuXinChao
|
||||
* @description BadCase录包管理页面
|
||||
* @since: 2022/12/15
|
||||
*/
|
||||
class SwtichBizModel : ViewModel(), IBusLinesCallback {
|
||||
|
||||
private val TAG = M_BUS + SwtichBizModel::class.java.simpleName
|
||||
|
||||
private var viewCallback: SwtichLineViewCallback? = null
|
||||
|
||||
|
||||
override fun onCleared() {
|
||||
d(TAG, "onCleared")
|
||||
LineModel.setBusLinesCallback(TAG, null)
|
||||
}
|
||||
|
||||
fun setSwitchBizCallback(viewCallback: SwtichLineViewCallback) {
|
||||
d(TAG, "setSwitchBizCallback")
|
||||
LineModel.setBusLinesCallback(TAG, this)
|
||||
this.viewCallback = viewCallback
|
||||
this.viewCallback?.showLoadingView()
|
||||
ThreadUtils.getIoPool().execute {
|
||||
OrderModel.queryBusRoutes()
|
||||
}
|
||||
}
|
||||
|
||||
fun queryRuningTask() {
|
||||
ThreadUtils.getIoPool().execute {
|
||||
OrderModel.queryBusRoutes()
|
||||
}
|
||||
}
|
||||
|
||||
fun showSwitchLineInfo() {
|
||||
viewCallback?.showLoadingView()
|
||||
viewCallback?.loadLineData()
|
||||
}
|
||||
|
||||
fun showSwitchLineInfoResult() {
|
||||
viewCallback?.showSwtichLineView()
|
||||
}
|
||||
|
||||
|
||||
interface SwtichLineViewCallback {
|
||||
fun showSwtichLineView()
|
||||
fun showLoadingView()
|
||||
fun loadLineData()
|
||||
fun loadRunningTask()
|
||||
}
|
||||
|
||||
|
||||
override fun onNoRunningTask() {
|
||||
this.viewCallback?.loadLineData()
|
||||
d(TAG, "没有任务去加载线路")
|
||||
}
|
||||
|
||||
override fun onRunningTask() {
|
||||
this.viewCallback?.loadRunningTask()
|
||||
d(TAG, "有任务去加载正在执行的任务")
|
||||
}
|
||||
|
||||
|
||||
override fun onCompleteTask() {
|
||||
OrderModel.queryBusRoutes()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
package com.mogo.och.offline.ui.fragment
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import com.mogo.commons.mvp.MvpFragment
|
||||
import com.mogo.eagle.core.function.call.och.CallerEagleBaseFunctionCall4OchManager
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.och.bridge.ui.drawline.LineView
|
||||
import com.mogo.och.offline.R
|
||||
import kotlinx.android.synthetic.main.offline_base_fragment.mapContainerLayout
|
||||
|
||||
/**
|
||||
* 网约车基础Fragment,主要负责布局通用界面,处理站点面板和通话面板互斥情况
|
||||
*
|
||||
*
|
||||
* 部分业务放在了此处处理
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
class OfflineFragment : MvpFragment<OfflineFragment?, OfflinePresenter?>() {
|
||||
|
||||
|
||||
private val runningTaskGateWay = "RUNNINGTASKGATEWAY"
|
||||
private val lineView = "LINEVIEW"
|
||||
|
||||
|
||||
override fun getLayoutId(): Int {
|
||||
return R.layout.offline_base_fragment
|
||||
}
|
||||
|
||||
override fun getTagName(): String {
|
||||
return "ShuttleFragment"
|
||||
}
|
||||
|
||||
override fun initViews() {
|
||||
|
||||
context?.let {
|
||||
CallerEagleBaseFunctionCall4OchManager.addSingleToolKitCustomItem(lineView, LineView(it),10)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun initViews(savedInstanceState: Bundle?) {
|
||||
super.initViews(savedInstanceState)
|
||||
mapContainerLayout?.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun createPresenter(): OfflinePresenter {
|
||||
return OfflinePresenter(this)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
mapContainerLayout?.onResume()
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater, container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
return super.onCreateView(inflater, container, savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onSaveInstanceState(outState: Bundle) {
|
||||
super.onSaveInstanceState(outState)
|
||||
mapContainerLayout?.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
override fun onLowMemory() {
|
||||
super.onLowMemory()
|
||||
mapContainerLayout?.onLowMemory()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
mapContainerLayout?.onPause()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
mapContainerLayout?.onDestroy()
|
||||
if (mPresenter != null) {
|
||||
mPresenter!!.onDestroy(this)
|
||||
}
|
||||
CallerEagleBaseFunctionCall4OchManager.removeToolKitDefaultItemClickListener(lineView)
|
||||
super.onDestroyView()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
}
|
||||
|
||||
/**
|
||||
* END
|
||||
*/
|
||||
companion object {
|
||||
private const val TAG = "${M_BUS}BaseBusTabFragment"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package com.mogo.och.offline.ui.fragment
|
||||
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import com.mogo.commons.AbsMogoApplication
|
||||
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.Companion.M_BUS
|
||||
import com.mogo.och.common.module.biz.login.ILoginCallback
|
||||
import com.mogo.och.common.module.biz.login.LoginStatusEnum
|
||||
import com.mogo.och.common.module.biz.login.LoginStatusManager
|
||||
import com.mogo.och.common.module.biz.login.LoginStatusManager.isLogin
|
||||
import com.mogo.och.bridge.autopilot.OCHAdasAbilityManager
|
||||
import com.mogo.och.offline.model.OrderModel
|
||||
import com.mogo.och.offline.util.OffLineTrajectoryManager
|
||||
|
||||
/**
|
||||
* 网约车小巴
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
class OfflinePresenter(view: OfflineFragment?) : Presenter<OfflineFragment?>(view), ILoginCallback {
|
||||
|
||||
override fun onCreate(owner: LifecycleOwner) {
|
||||
super.onCreate(owner)
|
||||
initModelListener()
|
||||
}
|
||||
|
||||
override fun onDestroy(owner: LifecycleOwner) {
|
||||
super.onDestroy(owner)
|
||||
|
||||
releaseListener()
|
||||
}
|
||||
|
||||
private fun initModelListener() {
|
||||
OCHAdasAbilityManager.getInstance().init(AbsMogoApplication.getApp())
|
||||
LoginStatusManager.addListener(TAG, this)
|
||||
OrderModel.init()
|
||||
}
|
||||
|
||||
private fun releaseListener() {
|
||||
OCHAdasAbilityManager.getInstance().release()
|
||||
LoginStatusManager.removeListener(TAG)
|
||||
OrderModel.release()
|
||||
}
|
||||
|
||||
override fun onStatusChange(currentStatus: LoginStatusEnum) {
|
||||
d(TAG, " loginStatus =" + isLogin())
|
||||
if (!isLogin()) {
|
||||
OffLineTrajectoryManager.stopTrajReqLoop()
|
||||
OrderModel.closeBeautificationMode()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = M_BUS+"BusPresenter"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
package com.mogo.och.offline.ui.switchline
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.AppCompatTextView
|
||||
import androidx.recyclerview.widget.DiffUtil
|
||||
import androidx.recyclerview.widget.DiffUtil.Callback
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.och.offline.ui.switchline.SwitchLineAdapter.SwitchLineViewHolder
|
||||
import com.mogo.och.data.db.bean.LineDataBean
|
||||
import com.mogo.och.offline.R
|
||||
import me.jessyan.autosize.AutoSizeCompat
|
||||
|
||||
/**
|
||||
* 路线列表adapter
|
||||
*/
|
||||
class SwitchLineAdapter(
|
||||
private val mContext: Context,
|
||||
val mData: MutableList<LineDataBean>
|
||||
) : RecyclerView.Adapter<SwitchLineViewHolder>() {
|
||||
companion object{
|
||||
const val TAG = M_BUS+"SwitchLineAdapter"
|
||||
}
|
||||
// RecyclerView设置点击事件
|
||||
private var mItemClickListener: LineItemClickListener? = null
|
||||
|
||||
fun setDataList(dataList: List<LineDataBean>) {
|
||||
|
||||
val diffResult = DiffUtil.calculateDiff(MyDiffCallback(this.mData, dataList))
|
||||
this.mData.clear()
|
||||
this.mData.addAll(dataList)
|
||||
diffResult.dispatchUpdatesTo(this)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
): SwitchLineViewHolder {
|
||||
val view = LayoutInflater.from(mContext).inflate(
|
||||
R.layout.offline_switch_line_list_item, parent, false
|
||||
)
|
||||
return SwitchLineViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: SwitchLineViewHolder, position: Int) {
|
||||
val currentPosition = holder.bindingAdapterPosition
|
||||
AutoSizeCompat.autoConvertDensityOfGlobal(holder.itemView.resources)
|
||||
val line = mData[currentPosition]
|
||||
|
||||
holder.lineName.text = line.lineName
|
||||
val string = mContext.getString(R.string.offline_switch_line_endstationname, line.endStationName)
|
||||
holder.lineEndName.text = string
|
||||
|
||||
|
||||
//设置item点击事件
|
||||
holder.itemView.setOnClickListener {
|
||||
mItemClickListener?.onItemClick(line)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return mData.size
|
||||
}
|
||||
|
||||
fun setOnLineItemClickListener(itemClickListener: LineItemClickListener?) {
|
||||
mItemClickListener = itemClickListener
|
||||
}
|
||||
|
||||
class SwitchLineViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val lineName: AppCompatTextView = itemView.findViewById(R.id.switch_line_name)//线路名称
|
||||
val lineEndName: AppCompatTextView = itemView.findViewById(R.id.switch_line_end_station) //终点
|
||||
}
|
||||
|
||||
interface LineItemClickListener {
|
||||
fun onItemClick(data: LineDataBean)
|
||||
}
|
||||
|
||||
inner class MyDiffCallback(private val oldData:List<LineDataBean>, private val newData:List<LineDataBean>):
|
||||
Callback(){
|
||||
override fun getOldListSize(): Int {
|
||||
return oldData.size
|
||||
}
|
||||
|
||||
override fun getNewListSize(): Int {
|
||||
return newData.size
|
||||
}
|
||||
|
||||
override fun areItemsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
val oldItem = oldData[oldItemPosition]
|
||||
val newItem = newData[newItemPosition]
|
||||
return oldItem == newItem && oldItem.endStationName == newItem.endStationName
|
||||
}
|
||||
|
||||
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
|
||||
val oldItem = oldData[oldItemPosition]
|
||||
val newItem = newData[newItemPosition]
|
||||
return oldItem == newItem && oldItem.endStationName == newItem.endStationName
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,182 @@
|
||||
package com.mogo.och.offline.ui.switchline
|
||||
|
||||
import android.animation.ObjectAnimator
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.findViewTreeViewModelStoreOwner
|
||||
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.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.eagle.core.utilcode.mogo.view.SpacesItemDecoration
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
|
||||
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.common.module.wigets.WrapContentLinearLayoutManager
|
||||
import com.mogo.och.common.module.wigets.commonview.ErrorView
|
||||
import com.mogo.och.data.db.bean.LineDataBean
|
||||
import com.mogo.och.offline.R
|
||||
import com.mogo.och.offline.ui.bizswitch.SwtichBizModel
|
||||
import kotlinx.android.synthetic.main.offline_switch_line.view.aciv_refresh_task
|
||||
import kotlinx.android.synthetic.main.offline_switch_line.view.actv_last_refresh_date
|
||||
import kotlinx.android.synthetic.main.offline_switch_line.view.include_empty
|
||||
import kotlinx.android.synthetic.main.offline_switch_line.view.include_errorview
|
||||
import kotlinx.android.synthetic.main.offline_switch_line.view.switch_line_rv
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
|
||||
|
||||
class SwitchLineView: WindowRelativeLayout, SwtichLineModel.SwtichLineViewCallback {
|
||||
|
||||
|
||||
constructor(context: Context?) : super(context)
|
||||
|
||||
constructor(context: Context?, attributeSet: AttributeSet) : super(context, attributeSet)
|
||||
|
||||
constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
|
||||
|
||||
constructor(context: Context?, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
|
||||
|
||||
|
||||
companion object {
|
||||
const val TAG = "${M_BUS}SwitchLineView"
|
||||
}
|
||||
|
||||
private var viewModel: SwtichLineModel?=null
|
||||
private var viewbizModel: SwtichBizModel?=null
|
||||
|
||||
private lateinit var mAdapter: SwitchLineAdapter
|
||||
|
||||
private var animator:ObjectAnimator?=null
|
||||
|
||||
|
||||
private lateinit var linearLayoutManager: WrapContentLinearLayoutManager
|
||||
|
||||
private var animatorStart = System.currentTimeMillis()
|
||||
|
||||
init {
|
||||
LayoutInflater.from(context).inflate(R.layout.offline_switch_line, this, true)
|
||||
initView()
|
||||
}
|
||||
|
||||
private fun initView(){
|
||||
linearLayoutManager = WrapContentLinearLayoutManager(context)
|
||||
switch_line_rv.setLayoutManager(linearLayoutManager)
|
||||
mAdapter = SwitchLineAdapter(context, mutableListOf())
|
||||
switch_line_rv.addItemDecoration(
|
||||
SpacesItemDecoration(
|
||||
AutoSizeUtils.dp2px(context,20f)
|
||||
)
|
||||
)
|
||||
switch_line_rv.setAdapter(mAdapter)
|
||||
//设置item 点击事件
|
||||
mAdapter.setOnLineItemClickListener(object : SwitchLineAdapter.LineItemClickListener{
|
||||
override fun onItemClick(data: LineDataBean) {
|
||||
CallerLogger.d(TAG,"选择线路 线路信息:${data}")
|
||||
|
||||
}
|
||||
})
|
||||
|
||||
aciv_refresh_task.onClick(5_000) {
|
||||
viewModel?.refreshTask()
|
||||
animatorStart = System.currentTimeMillis()
|
||||
if(animator==null) {
|
||||
animator = ObjectAnimator.ofFloat(aciv_refresh_task, "rotation", 0f, 360f)
|
||||
animator?.setDuration(1000) // 设置动画持续时间
|
||||
animator?.repeatCount = ValueAnimator.INFINITE // 设置动画无限重复
|
||||
animator?.repeatMode = ValueAnimator.RESTART // 设置重复模式
|
||||
}
|
||||
animator?.start()
|
||||
}
|
||||
include_errorview.reloadLIstener = object :ErrorView.ReloadLIstener{
|
||||
override fun reload() {
|
||||
viewbizModel?.showSwitchLineInfo()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化数据
|
||||
*/
|
||||
fun loadingDatas() {
|
||||
CallerLogger.d(TAG,"加载线路去")
|
||||
viewModel?.queryBusLines(true)
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
viewModel = findViewTreeViewModelStoreOwner()?.let {
|
||||
ViewModelProvider(it).get(SwtichLineModel::class.java)
|
||||
}
|
||||
viewbizModel = findViewTreeViewModelStoreOwner()?.let {
|
||||
ViewModelProvider(it).get(SwtichBizModel::class.java)
|
||||
}
|
||||
|
||||
viewModel?.setDistanceCallback(this)
|
||||
CallerLogger.d(TAG,"onAttachedToWindow")
|
||||
}
|
||||
|
||||
override fun onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow()
|
||||
CallerLogger.d(TAG,"onDetachedFromWindow")
|
||||
}
|
||||
|
||||
override fun startTaskState(success: Boolean) {
|
||||
|
||||
}
|
||||
|
||||
override fun onBusLinesChange(data: MutableList<LineDataBean>?, show:Boolean) {
|
||||
if (data.isNullOrEmpty()) {
|
||||
showNoData(true)
|
||||
}else{
|
||||
showNoData(false)
|
||||
mAdapter.setDataList(data)
|
||||
}
|
||||
CallerLogger.d(TAG,"加载线路成功")
|
||||
if(show) {
|
||||
viewbizModel?.showSwitchLineInfoResult()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 有无数据UI显示
|
||||
* @param b
|
||||
*/
|
||||
private fun showNoData(b: Boolean) {
|
||||
BizLoopManager.runInMainThread{
|
||||
include_errorview.visibility = View.GONE
|
||||
if (b) {
|
||||
switch_line_rv.visibility = View.GONE
|
||||
include_empty.visibility = View.VISIBLE
|
||||
} else {
|
||||
switch_line_rv.visibility = View.VISIBLE
|
||||
include_empty.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun refreshDate(formatLongToString: String?) {
|
||||
val endTime = System.currentTimeMillis()
|
||||
val dex = (1000-(endTime - animatorStart)).takeIf { it>=0 }?:0
|
||||
UiThreadHandler.postDelayed({
|
||||
formatLongToString?.let {
|
||||
actv_last_refresh_date.text = ResourcesUtils.getString(R.string.offline_switch_line_refresh_time,it)
|
||||
animator?.cancel()
|
||||
}
|
||||
},dex,UiThreadHandler.MODE.QUEUE,)
|
||||
|
||||
}
|
||||
|
||||
override fun onBusLinesChangeFaile() {
|
||||
include_errorview.visibility = View.VISIBLE
|
||||
switch_line_rv.visibility = View.GONE
|
||||
include_empty.visibility = View.GONE
|
||||
viewbizModel?.showSwitchLineInfoResult()
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
package com.mogo.och.offline.ui.switchline
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.och.common.module.utils.DateTimeUtil
|
||||
import com.mogo.och.common.module.utils.RxUtils
|
||||
import com.mogo.och.data.db.bean.LineDataBean
|
||||
import com.mogo.och.offline.callback.IBusLinesCallback
|
||||
import com.mogo.och.offline.model.LineModel
|
||||
import com.mogo.och.offline.repository.RepositoryManager
|
||||
import io.reactivex.Observer
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.disposables.Disposable
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
|
||||
/**
|
||||
* @author XuXinChao
|
||||
* @description BadCase录包管理页面
|
||||
* @since: 2022/12/15
|
||||
*/
|
||||
class SwtichLineModel : ViewModel(), IBusLinesCallback {
|
||||
|
||||
private val TAG = M_BUS+ SwtichLineModel::class.java.simpleName
|
||||
|
||||
private var viewCallback: SwtichLineViewCallback?=null
|
||||
|
||||
private var endTaskDisposable:Disposable?=null
|
||||
|
||||
|
||||
override fun onCleared() {
|
||||
d(TAG,"onCleared")
|
||||
LineModel.setBusLinesCallback(TAG,null)
|
||||
}
|
||||
|
||||
fun setDistanceCallback(viewCallback: SwtichLineViewCallback){
|
||||
this.viewCallback = viewCallback
|
||||
LineModel.setBusLinesCallback(TAG,this)
|
||||
}
|
||||
|
||||
fun queryBusLines(loading:Boolean) {
|
||||
RxUtils.disposeSubscribe(endTaskDisposable)
|
||||
RepositoryManager.queryCanUseLine()
|
||||
?.subscribeOn(Schedulers.io())
|
||||
?.observeOn(AndroidSchedulers.mainThread())
|
||||
?.subscribe(object : Observer<List<LineDataBean>?> {
|
||||
override fun onSubscribe(d: Disposable) {
|
||||
endTaskDisposable = d
|
||||
d(TAG, "queryBusLines onSubscribe")
|
||||
}
|
||||
|
||||
override fun onError(e: Throwable) {
|
||||
d(TAG, "queryBusLines onError${e.printStackTrace()}")
|
||||
viewCallback?.onBusLinesChangeFaile()
|
||||
}
|
||||
|
||||
override fun onComplete() {
|
||||
d(TAG, "queryBusLines onComplete")
|
||||
}
|
||||
|
||||
override fun onNext(data: List<LineDataBean>) {
|
||||
d(TAG, "queryBusLines onNext ${data}")
|
||||
val tempData = data.distinctBy { it.lineId }
|
||||
viewCallback?.onBusLinesChange(tempData.toMutableList(),loading)
|
||||
RxUtils.disposeSubscribe(endTaskDisposable)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
fun refreshTask() {
|
||||
LineModel.refreshTask()
|
||||
}
|
||||
|
||||
interface SwtichLineViewCallback{
|
||||
fun startTaskState(success: Boolean)
|
||||
fun onBusLinesChange(data: MutableList<LineDataBean>?, show:Boolean)
|
||||
fun refreshDate(formatLongToString: String?)
|
||||
fun onBusLinesChangeFaile()
|
||||
}
|
||||
|
||||
override fun onRefreshSuccess(currentTimeStamp: Long) {
|
||||
viewCallback?.refreshDate(
|
||||
DateTimeUtil.formatLongToString(currentTimeStamp, DateTimeUtil.HH_mm_ss)
|
||||
)
|
||||
}
|
||||
|
||||
override fun onRefreshSuccessWIthData() {
|
||||
super.onRefreshSuccessWIthData()
|
||||
queryBusLines(false)
|
||||
}
|
||||
|
||||
override fun onChangeLineIdFail() {
|
||||
viewCallback?.startTaskState(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,258 @@
|
||||
package com.mogo.och.offline.ui.taskrunning
|
||||
|
||||
import android.animation.ArgbEvaluator
|
||||
import android.content.Context
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import android.util.TypedValue
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
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.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.data.bean.BusStationBean
|
||||
import com.mogo.och.offline.R
|
||||
import com.mogo.och.offline.model.LineModel
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils
|
||||
|
||||
/**
|
||||
* 路线列表adapter
|
||||
*/
|
||||
class TaskRunningAdapter(
|
||||
private val mContext: Context,
|
||||
val mData: MutableList<BusStationBean>
|
||||
) : RecyclerView.Adapter<TaskRunningAdapter.TaskRunningViewHolder>() {
|
||||
|
||||
companion object {
|
||||
const val TAG = "${M_BUS}TaskRunningAdapter"
|
||||
}
|
||||
|
||||
private val argbEvaluator: ArgbEvaluator = ArgbEvaluator()
|
||||
private val startColor = ResourcesUtils.getColor(R.color.common_1970FF)
|
||||
private val endColor = ResourcesUtils.getColor(R.color.common_19FF7F)
|
||||
private val heightItem = 100f
|
||||
private val halfHeight = 16.5f
|
||||
private var totalHeight = 0f
|
||||
|
||||
fun setDataList(dataList: List<BusStationBean>) {
|
||||
this.mData.clear()
|
||||
this.mData.addAll(dataList)
|
||||
if (LineModel.startStationIndex == 0) {
|
||||
totalHeight = 33 + (dataList.size - 2) * heightItem
|
||||
} else {
|
||||
totalHeight =
|
||||
(halfHeight + (dataList.size - 1 - LineModel.startStationIndex) * heightItem).toFloat()
|
||||
}
|
||||
notifyItemRangeChanged(0, dataList.size, true)
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(
|
||||
parent: ViewGroup,
|
||||
viewType: Int
|
||||
): TaskRunningViewHolder {
|
||||
val view = LayoutInflater.from(mContext).inflate(
|
||||
R.layout.offline_task_running_item, parent, false
|
||||
)
|
||||
return TaskRunningViewHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: TaskRunningViewHolder, position: Int) {
|
||||
val currentPosition = holder.bindingAdapterPosition
|
||||
val line = mData[currentPosition]
|
||||
holder.actvStationName.text = line.name
|
||||
val startStationIndex = LineModel.startStationIndex
|
||||
if (startStationIndex > 0) {
|
||||
CallerLogger.d(TAG, "位置:$currentPosition 当前站${mData[startStationIndex]} ")
|
||||
}
|
||||
|
||||
if (currentPosition < startStationIndex) {
|
||||
holder.actvStationName.setTextSize(
|
||||
TypedValue.COMPLEX_UNIT_PX,
|
||||
AutoSizeUtils.dp2px(mContext, 40f).toFloat()
|
||||
)
|
||||
holder.actvStationName.setTextColor(ResourcesUtils.getColor(R.color.common_4DFFFFFF))
|
||||
holder.acivStationHead.setImageResource(R.drawable.offline_task_running_pass_station_head)
|
||||
} else if (currentPosition == startStationIndex) {
|
||||
holder.actvStationName.setTextSize(
|
||||
TypedValue.COMPLEX_UNIT_PX,
|
||||
AutoSizeUtils.dp2px(mContext, 45f).toFloat()
|
||||
)
|
||||
holder.actvStationName.setTextColor(ResourcesUtils.getColor(R.color.common_2EACFF))
|
||||
|
||||
holder.acivStationHead.setImageResource(R.drawable.offline_task_running_item_normal)
|
||||
} else {
|
||||
holder.actvStationName.setTextColor(ResourcesUtils.getColor(R.color.white))
|
||||
holder.actvStationName.setTextSize(
|
||||
TypedValue.COMPLEX_UNIT_PX,
|
||||
AutoSizeUtils.dp2px(mContext, 40f).toFloat()
|
||||
)
|
||||
holder.itemView.background = null
|
||||
holder.acivStationHead.setImageResource(R.drawable.offline_task_running_item_normal)
|
||||
}
|
||||
|
||||
when (currentPosition) {
|
||||
0 -> {
|
||||
holder.acivStationHeadBig.visibility = View.VISIBLE
|
||||
holder.acivStationHead.visibility = View.INVISIBLE
|
||||
holder.acivStationHeadBig.setImageResource(R.drawable.offline_task_running_item_start)
|
||||
holder.middleStationBg.visibility = View.GONE
|
||||
holder.startStationBg.visibility = View.VISIBLE
|
||||
holder.endStationBg.visibility = View.GONE
|
||||
if (startStationIndex == 0) {
|
||||
if (line.isLeaving) {
|
||||
// 下端 灰色
|
||||
holder.startStationBg.setBackgroundResource(R.color.common_4DFFFFFF)
|
||||
holder.itemView.background = null
|
||||
} else {
|
||||
// 下端 彩色
|
||||
holder.itemView.setBackgroundResource(R.drawable.offline_task_running_current_station_bg)
|
||||
|
||||
val orientation = GradientDrawable.Orientation.TOP_BOTTOM
|
||||
val temp01 = GradientDrawable(
|
||||
orientation, intArrayOf(
|
||||
startColor,
|
||||
endColor
|
||||
)
|
||||
)
|
||||
holder.startStationBg.background = temp01
|
||||
}
|
||||
} else {
|
||||
// 下端 灰色
|
||||
holder.startStationBg.setBackgroundResource(R.color.common_4DFFFFFF)
|
||||
holder.itemView.background = null
|
||||
}
|
||||
}
|
||||
|
||||
mData.size - 1 -> {
|
||||
holder.acivStationHeadBig.visibility = View.VISIBLE
|
||||
holder.acivStationHead.visibility = View.INVISIBLE
|
||||
holder.acivStationHeadBig.setImageResource(R.drawable.offline_task_running_item_end)
|
||||
holder.middleStationBg.visibility = View.GONE
|
||||
holder.startStationBg.visibility = View.GONE
|
||||
holder.endStationBg.visibility = View.VISIBLE
|
||||
if (startStationIndex == itemCount - 1) {
|
||||
if (line.isLeaving) {
|
||||
holder.endStationBg.setBackgroundResource(R.color.common_4DFFFFFF)
|
||||
holder.itemView.setBackgroundResource(R.drawable.offline_task_running_current_station_bg)
|
||||
} else {
|
||||
holder.itemView.setBackgroundResource(R.drawable.offline_task_running_current_station_bg)
|
||||
holder.endStationBg.setBackgroundResource(R.color.common_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.endStationBg.background = temp01
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
holder.acivStationHeadBig.visibility = View.GONE
|
||||
holder.acivStationHead.visibility = View.VISIBLE
|
||||
holder.middleStationBg.visibility = View.VISIBLE
|
||||
holder.startStationBg.visibility = View.GONE
|
||||
holder.endStationBg.visibility = View.GONE
|
||||
if (currentPosition == startStationIndex) {
|
||||
if (line.isLeaving) {
|
||||
// 灰色
|
||||
holder.middleStationBg.setBackgroundResource(R.color.common_4DFFFFFF)
|
||||
holder.itemView.background = null
|
||||
} else {
|
||||
// 彩色
|
||||
holder.itemView.setBackgroundResource(R.drawable.offline_task_running_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.middleStationBg.background = temp01
|
||||
}
|
||||
} else if (currentPosition < startStationIndex) {
|
||||
// 灰色
|
||||
holder.middleStationBg.setBackgroundResource(R.color.common_4DFFFFFF)
|
||||
holder.itemView.background = null
|
||||
} else {
|
||||
var dex = 0f
|
||||
if (startStationIndex == 0) {
|
||||
val firstItemData = mData[0]
|
||||
if (!firstItemData.isLeaving) {
|
||||
dex = halfHeight
|
||||
}
|
||||
} else {
|
||||
val checkIndex = mData.get(startStationIndex)
|
||||
if (!checkIndex.isLeaving) {
|
||||
dex = heightItem
|
||||
}
|
||||
}
|
||||
// 彩色
|
||||
holder.itemView.background = null
|
||||
val index = (currentPosition - startStationIndex - 1) * 100
|
||||
val startFraction = (dex + index) / totalHeight
|
||||
val endFraction = (dex + index + 100) / totalHeight
|
||||
CallerLogger.d(
|
||||
TAG,
|
||||
"位置:$currentPosition 当前站${startStationIndex} 开始百分比:${startFraction} 结束百分比:${endFraction}"
|
||||
)
|
||||
val startColorTemp =
|
||||
argbEvaluator.evaluate(startFraction, startColor, endColor) as Int
|
||||
val endColorTemp =
|
||||
argbEvaluator.evaluate(endFraction, startColor, endColor) as Int
|
||||
val orientation = GradientDrawable.Orientation.TOP_BOTTOM
|
||||
val temp01 = GradientDrawable(
|
||||
orientation, intArrayOf(
|
||||
startColorTemp,
|
||||
endColorTemp
|
||||
)
|
||||
)
|
||||
holder.middleStationBg.background = temp01
|
||||
}
|
||||
}
|
||||
}
|
||||
if (currentPosition == startStationIndex + 1) {
|
||||
val preLine = mData[currentPosition - 1]
|
||||
if (preLine.isLeaving) {
|
||||
holder.itemView.setBackgroundResource(R.drawable.offline_task_running_current_station_bg)
|
||||
} else {
|
||||
holder.itemView.background = null
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return mData.size
|
||||
}
|
||||
|
||||
class TaskRunningViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||
val actvStationName: AppCompatTextView = itemView.findViewById(R.id.actv_station_name)//站点名称
|
||||
val acivStationHead: AppCompatImageView =
|
||||
itemView.findViewById(R.id.aciv_station_head)//普通站点标识 不是起始和终点坐标
|
||||
val acivStationHeadBig: AppCompatImageView =
|
||||
itemView.findViewById(R.id.aciv_station_head_big)//起始和终点坐标标识
|
||||
val middleStationBg: View = itemView.findViewById(R.id.bg_pass_bg) //贯通背景调
|
||||
val endStationBg: View = itemView.findViewById(R.id.bg_pass_head_bg) //终点的背景
|
||||
val startStationBg: View = itemView.findViewById(R.id.bg_pass_bottom_bg) //起点坐标的背景
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.mogo.och.offline.ui.taskrunning
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.och.common.module.manager.loop.BizLoopManager
|
||||
import com.mogo.och.offline.callback.IBusLinesCallback
|
||||
import com.mogo.och.offline.model.LineModel
|
||||
import com.mogo.och.offline.model.OrderModel
|
||||
|
||||
/**
|
||||
* @author XuXinChao
|
||||
* @description BadCase录包管理页面
|
||||
* @since: 2022/12/15
|
||||
*/
|
||||
class TaskRunningModel : ViewModel(), IBusLinesCallback {
|
||||
|
||||
private val TAG = M_BUS + TaskRunningModel::class.java.simpleName
|
||||
|
||||
private var viewCallback: SwtichLineViewCallback? = null
|
||||
|
||||
|
||||
override fun onCleared() {
|
||||
}
|
||||
|
||||
fun setDistanceCallback(viewCallback: SwtichLineViewCallback) {
|
||||
this.viewCallback = viewCallback
|
||||
LineModel.setBusLinesCallback(TAG, this)
|
||||
}
|
||||
|
||||
fun leaveStation() {
|
||||
OrderModel.driveToNextStation()
|
||||
}
|
||||
|
||||
interface SwtichLineViewCallback {
|
||||
fun showRunningTaskInfo()
|
||||
fun hideLoadingAndshowRunningTaskInfo()
|
||||
fun smoothScrollToPosition(position: Int)
|
||||
fun completeTaskFail()
|
||||
}
|
||||
|
||||
override fun onLeaveStaionSuccess() {
|
||||
BizLoopManager.runInMainThread {
|
||||
viewCallback?.hideLoadingAndshowRunningTaskInfo()
|
||||
smoothScrollToPosition()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun smoothScrollToPosition() {
|
||||
BizLoopManager.runInMainThread(object : Runnable {
|
||||
override fun run() {
|
||||
viewCallback?.smoothScrollToPosition(LineModel.startStationIndex)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fun arriveStation() {
|
||||
OrderModel.onArriveAt(null, "页面触发到站")
|
||||
}
|
||||
|
||||
override fun onArriveStationSuccess() {
|
||||
BizLoopManager.runInMainThread {
|
||||
smoothScrollToPosition()
|
||||
viewCallback?.showRunningTaskInfo()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onCompleteTask() {
|
||||
|
||||
}
|
||||
|
||||
override fun onCompleteTaskFail() {
|
||||
super.onCompleteTaskFail()
|
||||
BizLoopManager.runInMainThread {
|
||||
viewCallback?.completeTaskFail()
|
||||
}
|
||||
}
|
||||
|
||||
fun completeTask() {
|
||||
OrderModel.completeTask()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,168 @@
|
||||
package com.mogo.och.offline.ui.taskrunning
|
||||
|
||||
import android.content.Context
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import androidx.constraintlayout.widget.ConstraintLayout
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.findViewTreeViewModelStoreOwner
|
||||
import com.mogo.eagle.core.utilcode.kotlin.onClick
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
|
||||
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.Companion.M_BUS
|
||||
import com.mogo.och.bridge.autopilot.line.LineManager
|
||||
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.common.module.wigets.dialog.CommonDialogStatus
|
||||
import com.mogo.och.common.module.wigets.CommonSlideView
|
||||
import com.mogo.och.common.module.wigets.WrapContentLinearLayoutManager
|
||||
import com.mogo.och.offline.R
|
||||
import com.mogo.och.offline.model.LineModel
|
||||
import com.mogo.och.offline.ui.bizswitch.SwtichBizModel
|
||||
import kotlinx.android.synthetic.main.offline_task_running.view.aciv_task_leave_station_slide_bg
|
||||
import kotlinx.android.synthetic.main.offline_task_running.view.actv_arriver_station
|
||||
import kotlinx.android.synthetic.main.offline_task_running.view.actv_complete_task
|
||||
import kotlinx.android.synthetic.main.offline_task_running.view.actv_running_task_last_station
|
||||
import kotlinx.android.synthetic.main.offline_task_running.view.actv_running_task_time
|
||||
import kotlinx.android.synthetic.main.offline_task_running.view.bus_task_running_line_name
|
||||
import kotlinx.android.synthetic.main.offline_task_running.view.loading_arrive_station
|
||||
import kotlinx.android.synthetic.main.offline_task_running.view.rl_running_task_station_list
|
||||
|
||||
|
||||
class TaskRunningView : ConstraintLayout, TaskRunningModel.SwtichLineViewCallback {
|
||||
|
||||
|
||||
constructor(context: Context) : super(context)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
|
||||
|
||||
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(
|
||||
context,
|
||||
attributeSet,
|
||||
defStyleAttr
|
||||
)
|
||||
|
||||
constructor(
|
||||
context: Context,
|
||||
attributeSet: AttributeSet,
|
||||
defStyleAttr: Int,
|
||||
defStyleRes: Int
|
||||
) : super(context, attributeSet, defStyleAttr, defStyleRes)
|
||||
|
||||
|
||||
companion object {
|
||||
const val TAG = M_BUS + "TaskRunningView"
|
||||
}
|
||||
|
||||
private var viewModel: TaskRunningModel? = null
|
||||
private var viewbizModel: SwtichBizModel? = null
|
||||
|
||||
private lateinit var mAdapter: TaskRunningAdapter
|
||||
|
||||
private lateinit var linearLayoutManager: WrapContentLinearLayoutManager
|
||||
|
||||
init {
|
||||
LayoutInflater.from(context).inflate(R.layout.offline_task_running, this, true)
|
||||
initView()
|
||||
}
|
||||
|
||||
private fun initView() {
|
||||
linearLayoutManager = WrapContentLinearLayoutManager(context)
|
||||
rl_running_task_station_list.setLayoutManager(linearLayoutManager)
|
||||
mAdapter = TaskRunningAdapter(context, mutableListOf())
|
||||
rl_running_task_station_list.setAdapter(mAdapter)
|
||||
aciv_task_leave_station_slide_bg.setSlideListener(object : CommonSlideView.SlideListener {
|
||||
override fun slideEnd() {
|
||||
viewModel?.leaveStation()
|
||||
}
|
||||
})
|
||||
actv_arriver_station.onClick {
|
||||
loading_arrive_station.visibility = VISIBLE
|
||||
viewModel?.arriveStation()
|
||||
}
|
||||
actv_complete_task.onClick {
|
||||
val builder = CommonDialogStatus.Builder()
|
||||
val closeLineConfirmDialog = builder
|
||||
.tips(ResourcesUtils.getString(R.string.offline_dialog_tips))
|
||||
.status(CommonDialogStatus.Status.ask)
|
||||
.build(context)
|
||||
closeLineConfirmDialog.setClickListener(object : CommonDialogStatus.ClickListener {
|
||||
override fun confirm() {
|
||||
viewModel?.completeTask()
|
||||
}
|
||||
|
||||
override fun cancel() {
|
||||
closeLineConfirmDialog.dismiss()
|
||||
}
|
||||
})
|
||||
closeLineConfirmDialog.show()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onAttachedToWindow() {
|
||||
super.onAttachedToWindow()
|
||||
viewModel = findViewTreeViewModelStoreOwner()?.let {
|
||||
ViewModelProvider(it).get(TaskRunningModel::class.java)
|
||||
}
|
||||
viewbizModel = findViewTreeViewModelStoreOwner()?.let {
|
||||
ViewModelProvider(it).get(SwtichBizModel::class.java)
|
||||
}
|
||||
|
||||
viewModel?.setDistanceCallback(this)
|
||||
}
|
||||
|
||||
override fun showRunningTaskInfo() {
|
||||
LineManager.getLineInfo { lineInfo ->
|
||||
bus_task_running_line_name.text = lineInfo.lineName
|
||||
}
|
||||
actv_running_task_time.text = "班次:${LineModel.getTaskTime()}"
|
||||
LineModel.stationList?.takeIf { it.size >= 2 }?.let {
|
||||
actv_running_task_last_station.text = "往${it.last().name ?: ""}"
|
||||
mAdapter.setDataList(it)
|
||||
CallerLogger.d(
|
||||
TAG,
|
||||
"BusLineModel.startStationIndex:${LineModel.startStationIndex}___$it"
|
||||
)
|
||||
val currentStation = it.get(LineModel.startStationIndex)
|
||||
if (currentStation.isLeaving) {
|
||||
showArriverStationAndCompleteTask()
|
||||
} else {
|
||||
showLeaveStationView()
|
||||
}
|
||||
if (LineModel.startStationIndex == it.size - 1) {
|
||||
aciv_task_leave_station_slide_bg.setTextValue("单程结束")
|
||||
} else {
|
||||
aciv_task_leave_station_slide_bg.setTextValue("滑动出发")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun hideLoadingAndshowRunningTaskInfo() {
|
||||
loading_arrive_station.visibility = GONE
|
||||
showRunningTaskInfo()
|
||||
}
|
||||
|
||||
override fun completeTaskFail() {
|
||||
aciv_task_leave_station_slide_bg.reset()
|
||||
}
|
||||
|
||||
override fun smoothScrollToPosition(position: Int) {
|
||||
try {
|
||||
rl_running_task_station_list.smoothScrollToPosition(position)
|
||||
} catch (e: Exception) {
|
||||
OchChainLogManager.writeChainLog("错误", "e:${e.message}")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun showLeaveStationView() {
|
||||
aciv_task_leave_station_slide_bg.visibility = VISIBLE
|
||||
actv_arriver_station.visibility = GONE
|
||||
actv_complete_task.visibility = GONE
|
||||
}
|
||||
|
||||
fun showArriverStationAndCompleteTask() {
|
||||
aciv_task_leave_station_slide_bg.visibility = INVISIBLE
|
||||
actv_arriver_station.visibility = VISIBLE
|
||||
actv_complete_task.visibility = VISIBLE
|
||||
}
|
||||
}
|
||||
@@ -4,15 +4,23 @@ import com.mogo.commons.AbsMogoApplication
|
||||
import com.mogo.commons.voice.AIAssist
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager
|
||||
import com.mogo.och.common.module.manager.socket.lan.bean.AppConnectMsg
|
||||
import com.mogo.och.common.module.utils.ResourcesUtils
|
||||
import com.mogo.och.common.module.voice.VoiceNotice
|
||||
import com.mogo.och.offline.R
|
||||
import com.mogo.och.shuttle.weaknet.R
|
||||
import com.mogo.skin.utils.SkinResources
|
||||
import com.mogo.tts.base.LangTtsEntity
|
||||
import com.mogo.tts.base.LanguageType
|
||||
import java.util.ArrayList
|
||||
|
||||
object ShuttleVoiceManager {
|
||||
|
||||
fun arrivedStationOut(notice:String?){
|
||||
if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
|
||||
VoiceNotice.showNoticeOut(notice)
|
||||
}
|
||||
}
|
||||
|
||||
fun arrivedStationBus(siteNameCN: String?, siteNameKR: String?) {
|
||||
val context = AbsMogoApplication.getApp()
|
||||
val list: MutableList<LangTtsEntity> = ArrayList()
|
||||
@@ -23,7 +31,7 @@ object ShuttleVoiceManager {
|
||||
)
|
||||
val engTTS = LangTtsEntity(
|
||||
context.getString(R.string.bus_arrived_station_english_tip, it),
|
||||
LanguageType.CHINESE
|
||||
LanguageType.ENGLISH
|
||||
)
|
||||
val koreanTTS = LangTtsEntity(
|
||||
context.getString(R.string.bus_arrived_station_korean_tip, siteNameKR?:it),
|
||||
@@ -32,9 +40,25 @@ object ShuttleVoiceManager {
|
||||
list.add(chineseTTS)
|
||||
list.add(engTTS)
|
||||
list.add(koreanTTS)
|
||||
|
||||
}
|
||||
|
||||
VoiceNotice.showNotice(list, AIAssist.LEVEL1,null)
|
||||
if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
|
||||
VoiceNotice.showNotice(list, AIAssist.LEVEL1,null)
|
||||
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
|
||||
siteNameCN?.let {
|
||||
sendArrivedStationToClient(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendArrivedStationToClient(arriveStation: String) {
|
||||
val arrivedMsg = AppConnectMsg(
|
||||
isViewShow = false,
|
||||
isPlay = true,
|
||||
msg = ResourcesUtils.getString(R.string.bus_arrived_station_tip,arriveStation),
|
||||
)
|
||||
LanSocketManager.sendMsgToClient(arrivedMsg)
|
||||
}
|
||||
|
||||
fun leaveStationBus(siteNameCN: String?, siteNameKR: String?) {
|
||||
@@ -47,7 +71,7 @@ object ShuttleVoiceManager {
|
||||
)
|
||||
val engTTS = LangTtsEntity(
|
||||
context.getString(R.string.bus_leave_station_english_tip, it),
|
||||
LanguageType.CHINESE
|
||||
LanguageType.ENGLISH
|
||||
)
|
||||
list.add(chineseTTS)
|
||||
list.add(engTTS)
|
||||
@@ -56,9 +80,26 @@ object ShuttleVoiceManager {
|
||||
context.getString(R.string.bus_leave_station_korean_tip, siteNameKR ?: it),
|
||||
LanguageType.KOREAN
|
||||
)
|
||||
|
||||
list.add(koreanTTS)
|
||||
}
|
||||
VoiceNotice.showNotice(list, AIAssist.LEVEL1,null)
|
||||
|
||||
if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
|
||||
VoiceNotice.showNotice(list, AIAssist.LEVEL1,null)
|
||||
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
|
||||
siteNameCN?.let {
|
||||
sendStartStationToClient(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendStartStationToClient(nextStation: String) {
|
||||
val startMsg = AppConnectMsg(
|
||||
isViewShow = false,
|
||||
isPlay = true,
|
||||
msg = ResourcesUtils.getString(R.string.bus_leave_station_tip,nextStation),
|
||||
)
|
||||
LanSocketManager.sendMsgToClient(startMsg)
|
||||
}
|
||||
|
||||
fun endOrderBus() {
|
||||
@@ -70,17 +111,45 @@ object ShuttleVoiceManager {
|
||||
list.add(chineseTTS)
|
||||
list.add(engTTS)
|
||||
list.add(koreanTTS)
|
||||
VoiceNotice.showNotice(list, AIAssist.LEVEL0,null)
|
||||
|
||||
if (AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)) {
|
||||
VoiceNotice.showNotice(list, AIAssist.LEVEL0,null)
|
||||
} else if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
|
||||
sendEndTaskToClient()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private fun sendEndTaskToClient() {
|
||||
val endMsg = AppConnectMsg(
|
||||
isViewShow = false,
|
||||
isPlay = true,
|
||||
msg = SkinResources.getInstance().getString(R.string.bus_end_task_tip),
|
||||
)
|
||||
LanSocketManager.sendMsgToClient(endMsg)
|
||||
}
|
||||
|
||||
|
||||
fun writeOffCount(successNum:Int){
|
||||
if(successNum<=1){
|
||||
VoiceNotice.showNotice("核验通过", AIAssist.LEVEL3);
|
||||
VoiceNotice.showNotice("核验通过", AIAssist.LEVEL3)
|
||||
//sendWriteOffNumToClient("核验通过")
|
||||
}else{
|
||||
VoiceNotice.showNotice("$successNum 人核验通过", AIAssist.LEVEL3)
|
||||
//sendWriteOffNumToClient("$successNum 人核验通过")
|
||||
}
|
||||
}
|
||||
|
||||
private fun sendWriteOffNumToClient(msg: String?) {
|
||||
val passengerMsg = AppConnectMsg(
|
||||
isViewShow = false,
|
||||
isPlay = true,
|
||||
msg = msg!!,
|
||||
)
|
||||
LanSocketManager.sendMsgToClient(passengerMsg)
|
||||
}
|
||||
|
||||
|
||||
// 距离发车还有1分钟
|
||||
fun showLeafTime(tips: String) {
|
||||
//语音提示
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
package com.mogo.och.offline.view
|
||||
|
||||
import android.content.Context
|
||||
import android.os.Bundle
|
||||
import android.util.AttributeSet
|
||||
import android.view.LayoutInflater
|
||||
import android.widget.FrameLayout
|
||||
import com.mogo.eagle.core.data.config.FunctionBuildConfig
|
||||
import com.mogo.eagle.core.function.view.MapBizView
|
||||
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
|
||||
import com.mogo.map.uicontroller.IMogoMapUIController
|
||||
import com.mogo.och.offline.R
|
||||
|
||||
/**
|
||||
* 魔戒蓝牙控件
|
||||
* 放置于StatusBar右侧位置
|
||||
*/
|
||||
class BizMapView @JvmOverloads constructor(
|
||||
context: Context,
|
||||
attrs: AttributeSet? = null,
|
||||
defStyleAttr: Int = 0
|
||||
) : FrameLayout(context, attrs, defStyleAttr) {
|
||||
|
||||
private lateinit var mapBizView: MapBizView
|
||||
|
||||
init {
|
||||
if (AppIdentityModeUtils.isB2(FunctionBuildConfig.appIdentityMode)) {
|
||||
LayoutInflater.from(context).inflate(R.layout.offline_m2_bizmap_map, this, true)
|
||||
}else if(AppIdentityModeUtils.isB1(FunctionBuildConfig.appIdentityMode)){
|
||||
LayoutInflater.from(context).inflate(R.layout.offline_jl_bizmap_map, this, true)
|
||||
}else{
|
||||
LayoutInflater.from(context).inflate(R.layout.offline_jl_bizmap_map, this, true)
|
||||
}
|
||||
mapBizView = findViewById(R.id.bizMapView)
|
||||
}
|
||||
|
||||
fun getUI(): IMogoMapUIController? {
|
||||
return mapBizView.getUI()
|
||||
}
|
||||
|
||||
fun onCreate(bundle: Bundle?) {
|
||||
mapBizView.onCreate(bundle)
|
||||
}
|
||||
fun onResume() {
|
||||
mapBizView.onResume()
|
||||
}
|
||||
|
||||
fun onSaveInstanceState(outState: Bundle){
|
||||
mapBizView.onSaveInstanceState(outState)
|
||||
}
|
||||
|
||||
fun onLowMemory() {
|
||||
mapBizView.onLowMemory()
|
||||
}
|
||||
|
||||
fun onPause() {
|
||||
mapBizView.onPause()
|
||||
}
|
||||
|
||||
fun onDestroy() {
|
||||
mapBizView.onDestroy()
|
||||
}
|
||||
}
|
||||
@@ -1,300 +0,0 @@
|
||||
package com.mogo.och.offline.view;
|
||||
|
||||
import android.animation.ObjectAnimator;
|
||||
import android.animation.ValueAnimator;
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Matrix;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Rect;
|
||||
import android.graphics.RectF;
|
||||
import android.graphics.Shader;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.mogo.commons.AbsMogoApplication;
|
||||
import com.mogo.eagle.core.utilcode.util.ConvertUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.ThreadUtils;
|
||||
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
|
||||
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager;
|
||||
import com.mogo.och.offline.R;
|
||||
|
||||
import me.jessyan.autosize.AutoSizeConfig;
|
||||
import me.jessyan.autosize.utils.AutoSizeUtils;
|
||||
|
||||
/**
|
||||
* 滑块滑动面板
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class SlidePanelView extends View {
|
||||
private static final String TAG = "SlidePanelView";
|
||||
|
||||
public SlidePanelView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public SlidePanelView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SlidePanelView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
TypedArray mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.SlidePanelView);
|
||||
textSize = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_textSize, textSize);
|
||||
BLOCK_START_X = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_BLOCK_START_X, BLOCK_START_X);
|
||||
BLOCK_START_Y = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_BLOCK_START_Y, BLOCK_START_Y);
|
||||
NORMAL_TEXT_MARGIN_LEFT = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_NORMAL_TEXT_MARGIN_LEFT, NORMAL_TEXT_MARGIN_LEFT);
|
||||
NORMAL_TEXT_MARGIN_RIGHT = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_NORMAL_TEXT_MARGIN_RIGHT, NORMAL_TEXT_MARGIN_RIGHT);
|
||||
SHORT_TEXT_MARGIN_LEFT = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_SHORT_TEXT_MARGIN_LEFT, SHORT_TEXT_MARGIN_LEFT);
|
||||
SHORT_TEXT_MARGIN_RIGHT = (int) mTypedArray.getDimension(R.styleable.SlidePanelView_SHORT_TEXT_MARGIN_RIGHT, SHORT_TEXT_MARGIN_RIGHT);
|
||||
init();
|
||||
}
|
||||
|
||||
private final Paint bgPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint blockPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
private static int textSize = 40;
|
||||
private static int BLOCK_START_X = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),15);
|
||||
private static int BLOCK_START_Y = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),15);
|
||||
private static int NORMAL_TEXT_MARGIN_LEFT = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),40);
|
||||
private static int NORMAL_TEXT_MARGIN_RIGHT = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),60);
|
||||
private static int SHORT_TEXT_MARGIN_LEFT = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),60);;
|
||||
private static int SHORT_TEXT_MARGIN_RIGHT = AutoSizeUtils.dp2px(AbsMogoApplication.getApp(),70);;
|
||||
|
||||
private int textMarginLeft = NORMAL_TEXT_MARGIN_LEFT;
|
||||
private int textMarginRight = NORMAL_TEXT_MARGIN_RIGHT;
|
||||
|
||||
private OnSlidePanelMoveToEndListener moveToEndListener;
|
||||
|
||||
private int blockWidth = 0;
|
||||
private int blockOffset = 0;
|
||||
|
||||
private float lastX;
|
||||
private boolean isToEnd = false;
|
||||
|
||||
private static final String STRING_SLIDE_TO_RIGHT = "向右滑动";
|
||||
private RectF bgRectF;
|
||||
private Bitmap bmBlock;
|
||||
|
||||
private final Matrix gradientMatrix = new Matrix();
|
||||
private float matrixTranslate;
|
||||
private final Rect textRect = new Rect();
|
||||
private LinearGradient textGradient;
|
||||
|
||||
private ObjectAnimator matrixAnim;
|
||||
|
||||
private String blockText = STRING_SLIDE_TO_RIGHT;
|
||||
private final Paint.FontMetrics blockTextMetrics = new Paint.FontMetrics();
|
||||
|
||||
private static final int GRADIENT_OFFSET = 200;
|
||||
|
||||
public void setOnSlidePanelMoveToEndListener(OnSlidePanelMoveToEndListener moveToEndListener) {
|
||||
this.moveToEndListener = moveToEndListener;
|
||||
}
|
||||
|
||||
private void setBlockOffset(int blockOffset) {
|
||||
this.blockOffset = blockOffset;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void setMatrixTranslate(float matrixTranslate) {
|
||||
this.matrixTranslate = matrixTranslate;
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setText(String text) {
|
||||
this.blockText = text;
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
bgRectF = new RectF(0, 0, 0, 0);
|
||||
bgPaint.setColor(Color.parseColor("#CC0F1325"));
|
||||
bgPaint.setStyle(Paint.Style.FILL);
|
||||
|
||||
textPaint.setStyle(Paint.Style.FILL);
|
||||
textPaint.setTextSize(textSize);
|
||||
textPaint.setTextAlign(Paint.Align.LEFT);
|
||||
textGradient = new LinearGradient(-GRADIENT_OFFSET, 0, 0, 0, new int[]{0x33ffffff, 0xffffffff, 0x33ffffff}, null, Shader.TileMode.CLAMP);
|
||||
textGradient.setLocalMatrix(gradientMatrix);
|
||||
textPaint.setShader(textGradient);
|
||||
textPaint.getFontMetrics(blockTextMetrics);
|
||||
decodeImage();
|
||||
}
|
||||
|
||||
private void decodeImage(){
|
||||
ThreadUtils.getCpuPool().execute(() -> {
|
||||
int size = AutoSizeUtils.dp2px(getContext(), 120);
|
||||
BitmapFactory.Options opts = new BitmapFactory.Options();
|
||||
opts.inDensity = (int) AutoSizeConfig.getInstance().getInitDensity();
|
||||
bmBlock = BitmapFactory.decodeResource(getResources(), R.drawable.bus_base_slide_block,opts);
|
||||
bmBlock = Bitmap.createScaledBitmap(bmBlock, size, size, true);
|
||||
blockWidth = bmBlock.getWidth();
|
||||
UiThreadHandler.post(this::requestLayout,UiThreadHandler.MODE.QUEUE);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
int widthSize;
|
||||
int heightSize;
|
||||
|
||||
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(bmBlock!=null) {
|
||||
if (widthMode == MeasureSpec.AT_MOST) {
|
||||
// 宽度根据图片大小,字符串长度,各种间隔确定
|
||||
// 高度根据图片大小和上下间隔确定
|
||||
textPaint.getTextBounds(blockText, 0, blockText.length(), textRect);
|
||||
widthSize = BLOCK_START_X * 2 + bmBlock.getWidth() + textMarginLeft + textMarginRight + textRect.width();
|
||||
heightSize = BLOCK_START_Y * 2 + bmBlock.getHeight();
|
||||
widthMeasureSpec = MeasureSpec.makeMeasureSpec(widthSize, widthMode);
|
||||
heightMeasureSpec = MeasureSpec.makeMeasureSpec(heightSize, heightMode);
|
||||
}
|
||||
}
|
||||
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
|
||||
private float textOffset = 0;
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
if (bgRectF != null){
|
||||
bgRectF.left = 0;
|
||||
bgRectF.top = 0;
|
||||
bgRectF.right = w;
|
||||
bgRectF.bottom = h;
|
||||
}
|
||||
|
||||
if (matrixAnim != null) {
|
||||
matrixAnim.cancel();
|
||||
}
|
||||
textOffset = (getHeight() - blockTextMetrics.ascent - blockTextMetrics.descent) / 2;
|
||||
matrixAnim = ObjectAnimator.ofFloat(this, "matrixTranslate", 0, w + GRADIENT_OFFSET).setDuration(2000);
|
||||
matrixAnim.setRepeatCount(ValueAnimator.INFINITE);
|
||||
matrixAnim.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onAttachedToWindow() {
|
||||
super.onAttachedToWindow();
|
||||
if (matrixAnim != null) {
|
||||
matrixAnim.start();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDetachedFromWindow() {
|
||||
super.onDetachedFromWindow();
|
||||
if (matrixAnim != null) {
|
||||
matrixAnim.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(MotionEvent event) {
|
||||
float x = event.getX();
|
||||
float y = event.getY();
|
||||
|
||||
switch (event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
if (x > BLOCK_START_X + blockOffset && x < blockWidth + BLOCK_START_X + blockOffset && y > BLOCK_START_Y && y < getHeight() - BLOCK_START_Y) {
|
||||
isToEnd = false;
|
||||
lastX = x;
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
if (lastX != 0) {
|
||||
blockOffset = (int) (x - lastX);
|
||||
if (blockOffset < 0) {
|
||||
blockOffset = 0;
|
||||
}
|
||||
if (blockOffset + BLOCK_START_X + blockWidth > getWidth()) {
|
||||
// 超出右边界
|
||||
blockOffset = getWidth() - BLOCK_START_X - blockWidth;
|
||||
if (!isToEnd) {
|
||||
isToEnd = true;
|
||||
if (moveToEndListener != null) {
|
||||
moveToEndListener.moveToEnd();
|
||||
}
|
||||
startBlockBackAnim();
|
||||
}
|
||||
}
|
||||
invalidate();
|
||||
}
|
||||
break;
|
||||
case MotionEvent.ACTION_UP:
|
||||
// 执行滑块回归动画
|
||||
if (!isToEnd) {
|
||||
startBlockBackAnim();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void startBlockBackAnim() {
|
||||
ObjectAnimator blockBackanimator = ObjectAnimator.ofInt(this, "blockOffset", blockOffset, 0);
|
||||
blockBackanimator.setInterpolator(new DecelerateInterpolator());
|
||||
blockBackanimator.setDuration(1000 * blockOffset / getWidth());
|
||||
blockBackanimator.start();
|
||||
lastX = 0;
|
||||
}
|
||||
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
// 画背景
|
||||
canvas.drawRoundRect(bgRectF, (float) getHeight() / 2.0f, (float) getHeight() / 2.0f, bgPaint);
|
||||
// 画文字
|
||||
gradientMatrix.setTranslate(matrixTranslate, 0);
|
||||
textGradient.setLocalMatrix(gradientMatrix);
|
||||
canvas.save();
|
||||
canvas.drawText(blockText, (float) (blockWidth + BLOCK_START_X + textMarginLeft), (float) textOffset, textPaint);
|
||||
canvas.restore();
|
||||
if (bmBlock != null) {
|
||||
if(bmBlock.getByteCount()>=5*1024*1024){
|
||||
OchChainLogManager.writeChainLog("崩溃兜底策略",
|
||||
"图片大小监听"+ ConvertUtils.byte2FitMemorySize(bmBlock.getByteCount()),true,OchChainLogManager.EVENT_KEY_INFE_ERROR);
|
||||
bmBlock.recycle();
|
||||
bmBlock = null;
|
||||
blockWidth = 0;
|
||||
decodeImage();
|
||||
}else {
|
||||
// 画滑块
|
||||
canvas.drawBitmap(bmBlock, (float) (BLOCK_START_X + blockOffset), (float) BLOCK_START_Y, blockPaint);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public interface OnSlidePanelMoveToEndListener {
|
||||
/**
|
||||
* 滑块滑到了末尾
|
||||
*/
|
||||
void moveToEnd();
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
package com.mogo.och.offline.view;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.LinearGradient;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.Shader;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* 垂直虚线
|
||||
*
|
||||
* @author tongchenfei
|
||||
*/
|
||||
public class VerticalDashLineView extends View {
|
||||
public VerticalDashLineView(Context context) {
|
||||
this(context,null);
|
||||
}
|
||||
|
||||
public VerticalDashLineView(Context context, @Nullable AttributeSet attrs) {
|
||||
this(context, attrs,0);
|
||||
}
|
||||
|
||||
public VerticalDashLineView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private final Paint linePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
private final Path dashPath = new Path();
|
||||
|
||||
private void init(){
|
||||
linePaint.setColor(Color.GREEN);
|
||||
linePaint.setStyle(Paint.Style.STROKE);
|
||||
linePaint.setStrokeWidth(2);
|
||||
linePaint.setPathEffect(new DashPathEffect(new float[]{5, 5}, 0));
|
||||
}
|
||||
|
||||
public void setGradient(int startColor, int endColor) {
|
||||
LinearGradient linearGradient = new LinearGradient(0, 0, getWidth(), getHeight(), startColor, endColor, Shader.TileMode.CLAMP);
|
||||
linePaint.setShader(linearGradient);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
linePaint.setShader(null);
|
||||
linePaint.setColor(color);
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
dashPath.reset();
|
||||
dashPath.moveTo((float) getWidth()/2, 0);
|
||||
dashPath.lineTo((float) getWidth()/2,getHeight());
|
||||
canvas.drawPath(dashPath,linePaint);
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 8.6 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 323 B |
|
Before Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 1.3 KiB |
|
Before Width: | Height: | Size: 338 B |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 53 KiB |
|
Before Width: | Height: | Size: 47 KiB |
|
Before Width: | Height: | Size: 491 B |
|
Before Width: | Height: | Size: 2.5 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1004 B |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 5.1 KiB |
|
Before Width: | Height: | Size: 4.3 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 5.7 KiB |
|
Before Width: | Height: | Size: 5.4 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 3.9 KiB |
|
Before Width: | Height: | Size: 5.0 KiB |
|
Before Width: | Height: | Size: 7.4 KiB |
|
Before Width: | Height: | Size: 4.7 KiB |
|
Before Width: | Height: | Size: 5.2 KiB |
|
Before Width: | Height: | Size: 377 B |
|
Before Width: | Height: | Size: 400 B |
|
Before Width: | Height: | Size: 402 B |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 6.9 KiB |
|
Before Width: | Height: | Size: 6.7 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 137 B |