Merge branch 'dev_robotaxi-d_240912_6.7.0' into 'tmp_6.7.0_arrow'

# Conflicts:
#   core/function-impl/mogo-core-function-hmi/src/main/res/layout/view_bone_container.xml
This commit is contained in:
aibingbing
2024-09-14 09:54:00 +00:00
163 changed files with 4060 additions and 3878 deletions

View File

@@ -1,24 +0,0 @@
package com.mogo.och.bus.bean;
import java.io.Serializable;
/**
* @author: wangmingjun
* @date: 2022/9/23
*/
public class WriteOffPassenger implements Serializable {
public String phone;
public String orderNo;
public int passengerSize;
public long writeOffTime;
@Override
public String toString() {
return "WriteOffPassenger{" +
"phone='" + phone + '\'' +
", orderNo='" + orderNo + '\'' +
", passengerSize=" + passengerSize +
", writeOffTime=" + writeOffTime +
'}';
}
}

View File

@@ -0,0 +1,14 @@
package com.mogo.och.bus.bean
import java.io.Serializable
/**
* @author: wangmingjun
* @date: 2022/9/23
*/
data class WriteOffPassenger(
var phone: String? = null,
var orderNo: String? = null,
@JvmField var passengerSize: Int = 0,
var writeOffTime: Long = 0
) : Serializable

View File

@@ -1,20 +0,0 @@
package com.mogo.och.bus.bean.request;
import com.mogo.commons.storage.SharedPrefsMgr;
/**
* 中止/结束任务请求
*/
public class BusCloseTaskRequest {
private String sn;
private int taskId;
public BusCloseTaskRequest(int taskId) {
this.sn = SharedPrefsMgr.getInstance().getSn();
this.taskId = taskId;
}
public String getSn() {
return sn;
}
}

View File

@@ -0,0 +1,8 @@
package com.mogo.och.bus.bean.request
import com.mogo.commons.storage.SharedPrefsMgr
/**
* 中止/结束任务请求
*/
data class BusCloseTaskRequest(val taskId: Int, val sn: String = SharedPrefsMgr.getInstance().sn)

View File

@@ -1,17 +0,0 @@
package com.mogo.och.bus.bean.request;
import com.mogo.commons.storage.SharedPrefsMgr;
/**
* @author congtaowang
* @since 2021/3/22
*
* 根据车机行驶线路站点信息
*/
public class BusQueryLineStationsRequest {
private String sn;
public BusQueryLineStationsRequest() {
this.sn = SharedPrefsMgr.getInstance().getSn();
}
}

View File

@@ -0,0 +1,11 @@
package com.mogo.och.bus.bean.request
import com.mogo.commons.storage.SharedPrefsMgr
/**
* @author congtaowang
* @since 2021/3/22
*
* 根据车机行驶线路站点信息
*/
data class BusQueryLineStationsRequest(private val sn: String = SharedPrefsMgr.getInstance().sn)

View File

@@ -1,17 +0,0 @@
package com.mogo.och.bus.bean.request;
import com.mogo.commons.storage.SharedPrefsMgr;
/**
* @author: wangmingjun
* @date: 2021/10/18
*/
public class BusResetDrivingLineRequest {
public String sn;
public int taskId; //切换到的线路id
public BusResetDrivingLineRequest(int taskId) {
this.sn = SharedPrefsMgr.getInstance().getSn();
this.taskId = taskId;
}
}

View File

@@ -0,0 +1,12 @@
package com.mogo.och.bus.bean.request
import com.mogo.commons.storage.SharedPrefsMgr
/**
* @author: wangmingjun
* @date: 2021/10/18
*/
data class BusResetDrivingLineRequest(//切换到的线路id
val taskId: Int,
val sn: String = SharedPrefsMgr.getInstance().sn
)

View File

@@ -1,30 +0,0 @@
package com.mogo.och.bus.bean.request;
import java.util.List;
/**
* Created by pangfan on 2021/8/19
*
* 订单状态更新请求数据结构
*/
public class BusRoutePlanningUpdateReqBean {
public String sn;
public int lineId;
public int startSiteId;
public int endSiteId;
public List<Result> points;
public static class Result {
public Double latitude;
public Double longitude;
}
public BusRoutePlanningUpdateReqBean(String sn, int lineId, int startSiteId
, int endSiteId, List<Result> points) {
this.sn = sn;
this.lineId = lineId;
this.startSiteId = startSiteId;
this.endSiteId = endSiteId;
this.points = points;
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.bus.bean.request
/**
* Created by pangfan on 2021/8/19
*
* 订单状态更新请求数据结构
*/
class BusRoutePlanningUpdateReqBean(
var sn: String, var lineId: Int, var startSiteId: Int,
var endSiteId: Int, var points: List<Result>
) {
data class Result(
var latitude: Double? = null,
var longitude: Double? = null
)
}

View File

@@ -1,24 +0,0 @@
package com.mogo.och.bus.bean.request;
import com.mogo.commons.storage.SharedPrefsMgr;
/**
* @author congtaowang
* @since 2021/3/22
*
* 小巴车运营状态请求参数
*/
public class BusUpdateSiteStatusRequest {
public String sn;
public int taskId;
public int seq;//站点序号
public int siteId;//站点id
public BusUpdateSiteStatusRequest(int taskId,int siteId,int seq) {
this.sn = SharedPrefsMgr.getInstance().getSn();
this.seq = seq;
this.siteId = siteId;
this.taskId = taskId;
}
}

View File

@@ -0,0 +1,16 @@
package com.mogo.och.bus.bean.request
import com.mogo.commons.storage.SharedPrefsMgr
/**
* @author congtaowang
* @since 2021/3/22
*
* 小巴车运营状态请求参数
*/
class BusUpdateSiteStatusRequest(
var taskId: Int, //站点id
var siteId: Int, //站点序号
var seq: Int,
var sn: String = SharedPrefsMgr.getInstance().sn
)

View File

@@ -1,26 +0,0 @@
package com.mogo.och.bus.bean.request;
import com.mogo.och.bus.constant.BusConst;
import java.util.UUID;
/**
* Created on 2021/9/16
*
* 上传车机心跳信息请求数据
*/
public class CarHeartbeatReqBean {
public String sn;
public double lon; //经度
public double lat; //纬度
public String msgId; //心跳信息唯一标识
public int interval; //上报间隔单位秒非必传默认60秒
public CarHeartbeatReqBean(String sn, double lon, double lat) {
this.sn = sn;
this.lon = lon;
this.lat = lat;
this.msgId = UUID.randomUUID().toString();
this.interval = (int) (BusConst.LOOP_PERIOD_60S / 1000);
}
}

View File

@@ -0,0 +1,17 @@
package com.mogo.och.bus.bean.request
import com.mogo.och.bus.constant.BusConst
import java.util.UUID
/**
* Created on 2021/9/16
*
* 上传车机心跳信息请求数据
*/
class CarHeartbeatReqBean(
var sn: String, //经度
var lon: Double, //纬度
var lat: Double,
var msgId: String = UUID.randomUUID().toString(), //心跳信息唯一标识
var interval: Int = (BusConst.LOOP_PERIOD_60S / 1000).toInt() //上报间隔单位秒非必传默认60秒
)

View File

@@ -1,19 +0,0 @@
package com.mogo.och.bus.bean.response;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2022/2/9
*/
public class BusQueryLineTaskResponse extends BaseData {
public List<Result> data;
public static class Result {
public int id;
public long taskStartTime;
}
}

View File

@@ -0,0 +1,15 @@
package com.mogo.och.bus.bean.response
import com.mogo.eagle.core.data.BaseData
/**
* @author: wangmingjun
* @date: 2022/2/9
*/
data class BusQueryLineTaskResponse(var data: List<Result>?) : BaseData() {
data class Result(
var id: Int = 0,
var taskStartTime: Long = 0,
)
}

View File

@@ -1,27 +0,0 @@
package com.mogo.och.bus.bean.response;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2022/2/9
*/
public class BusQueryLinesResponse extends BaseData {
public List<Result> data;
public static class Result {
public int lineId;//线路id
public String name;//线路名字
public int choose; // 1:绑定 2:未被绑定
public String startSiteName;//始发站名称
public String endSiteName;//终点名称
public boolean open;//true 打开状态 false
public boolean haveTask;
public List<BusQueryLineTaskResponse.Result> taskList;
}
}

View File

@@ -0,0 +1,22 @@
package com.mogo.och.bus.bean.response
import com.mogo.eagle.core.data.BaseData
/**
* @author: wangmingjun
* @date: 2022/2/9
*/
data class BusQueryLinesResponse(var data: MutableList<Result>?) : BaseData() {
data class Result(
var lineId: Int = 0, //线路id
var name: String? = null, //线路名字
var choose: Int = 0, // 1:绑定 2:未被绑定
var startSiteName: String? = null, //始发站名称
var endSiteName: String? = null, //终点名称
var open: Boolean = false, //true 打开状态 false
var haveTask: Boolean = false,
var taskList: MutableList<BusQueryLineTaskResponse.Result>? = null
)
}

View File

@@ -1,28 +0,0 @@
package com.mogo.och.bus.bean.response;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.data.bean.BusRoutesResult;
/**
* 网约车小巴路线接口请求响应结果
*
* @author tongchenfei
*/
public class BusRoutesResponse extends BaseData {
private BusRoutesResult data;
public BusRoutesResult getResult() {
return data;
}
public void setResult(BusRoutesResult data) {
this.data = data;
}
@Override
public String toString() {
return "BusRoutesResponse{" +
"data=" + data +
'}';
}
}

View File

@@ -0,0 +1,11 @@
package com.mogo.och.bus.bean.response
import com.mogo.eagle.core.data.BaseData
import com.mogo.och.data.bean.BusRoutesResult
/**
* 网约车小巴路线接口请求响应结果
*
* @author tongchenfei
*/
data class BusRoutesResponse(var result: BusRoutesResult) : BaseData()

View File

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

View File

@@ -1,11 +0,0 @@
package com.mogo.och.bus.callback;
/**
* Created on 2021/9/10
*
* Model->Presenter回调状态控制器监听accOn、adas ui show、voice ui show、push ui show、v2x ui show等等
*/
public interface IBusControllerStatusCallback {
//开始开启自动驾驶
void startOpenAutopilot();
}

View File

@@ -1,6 +1,9 @@
package com.mogo.och.bus.callback;
import com.mogo.och.bus.bean.WriteOffPassenger;
import com.mogo.och.data.bean.BusStationBean;
import java.util.List;
/**
* @author: wangmingjun
@@ -8,4 +11,20 @@ import com.mogo.och.bus.bean.WriteOffPassenger;
*/
public interface IPassengerCallback {
void playPassenger(WriteOffPassenger passenger);
//自驾返回失败
void onStartAdasFailure();
void startOpenAutopilot();
void updateBusTaskStatus(String lineName,String lintTime,
List<BusStationBean> stationList,
int arrivingOrArrivedIndex,
boolean isArrived);
/**
* 结束清理一遍、选择任务后清理一遍
*/
void clearBusStationsMarkers();
void updateEmptyUi();
void hideSlidePanel();
}

View File

@@ -1,23 +0,0 @@
package com.mogo.och.bus.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();
}

View File

@@ -1,9 +0,0 @@
package com.mogo.och.bus.callback;
/**
* @author: wangmingjun
* @date: 2021/10/22
*/
public interface ISlidePannelHideCallback {
void hideSlidePanel();
}

View File

@@ -33,11 +33,7 @@ import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.bus.R;
import com.mogo.och.bus.bean.response.BusRoutesResponse;
import com.mogo.och.bus.bean.WriteOffPassenger;
import com.mogo.och.bus.callback.IBusADASStatusCallback;
import com.mogo.och.bus.callback.IBusControllerStatusCallback;
import com.mogo.och.bus.callback.IPassengerCallback;
import com.mogo.och.bus.callback.IRefreshBusStationsCallback;
import com.mogo.och.bus.callback.ISlidePannelHideCallback;
import com.mogo.och.bus.constant.BusConst;
import com.mogo.och.bus.net.OrderServiceManager;
import com.mogo.och.bus.presenter.BusModelLoopManager;
@@ -116,11 +112,7 @@ public class OrderModel {
// 运营类型
private static final int VEHICLE_TYPE = 10;
private IRefreshBusStationsCallback refreshBusStationsCallback;
private ISlidePannelHideCallback slidePanelHideCallback;
private IBusControllerStatusCallback mControllerStatusCallback; //Model->PresenterVR mode等
private IPassengerCallback mPassengerCallback; //乘客核销回调
private IBusADASStatusCallback mADASStatusCallback;
private volatile boolean isArrivedStation = false;
@@ -298,25 +290,10 @@ public class OrderModel {
}
};
public void setAdasStatusCallback(IBusADASStatusCallback callback){
this.mADASStatusCallback = callback;
}
public void setRefreshBusStationsCallback(IRefreshBusStationsCallback callback){
this.refreshBusStationsCallback = callback;
}
public void setPassengerCallback(IPassengerCallback callback) {
this.mPassengerCallback = callback;
}
public void setSlidePanelHideCallback(ISlidePannelHideCallback callback) {
this.slidePanelHideCallback = callback;
}
public void setControllerStatusCallback(IBusControllerStatusCallback callback) {
this.mControllerStatusCallback = callback;
}
private final ITrajectoryListener trajectoryListener = (routeArrivied, routeArriving, location) -> {
@@ -402,9 +379,9 @@ public class OrderModel {
@Override
public void onStartAutopilotFailure(@NotNull String startFailedCode, @NonNull String startFailedMessage) {
OchAutopilotAnalytics.INSTANCE.triggerStartAutopilotFailureEventByAdas(startFailedCode, startFailedMessage, System.currentTimeMillis());
if (mADASStatusCallback != null && !FunctionBuildConfig.isDemoMode){
if (mPassengerCallback != null && !FunctionBuildConfig.isDemoMode){
CallerLogger.e( M_BUS + TAG, "mAdasStartFailureListener = "+startFailedMessage );
mADASStatusCallback.onStartAdasFailure();
mPassengerCallback.onStartAdasFailure();
}
}
};
@@ -478,8 +455,8 @@ public class OrderModel {
|| data.getResult().getSites().isEmpty()) {
//当为空时,显示无绑定路线图
CallerLogger.d(M_BUS + TAG, "获取到小巴路线数据:空 ");
if (refreshBusStationsCallback != null) {
refreshBusStationsCallback.updateEmptyUi();
if (mPassengerCallback != null) {
mPassengerCallback.updateEmptyUi();
}
clearAutopilotControlParameters();
closeBeautificationMode();
@@ -558,14 +535,14 @@ public class OrderModel {
if (arrivingOrArrivedStationIndex == 0 ||
arrivingOrArrivedStation.getDrivingStatus() == STATION_STATUS_STOPPED
&& !arrivingOrArrivedStation.isLeaving()) {
if (refreshBusStationsCallback != null) {
refreshBusStationsCallback.updateBusTaskStatus(busRoutesResult.getName(), lineTime,
if (mPassengerCallback != null) {
mPassengerCallback.updateBusTaskStatus(busRoutesResult.getName(), lineTime,
stationList, arrivingOrArrivedStationIndex, true);
}
clearAutopilotControlParameters();
} else {
if (refreshBusStationsCallback != null) {
refreshBusStationsCallback.updateBusTaskStatus(busRoutesResult.getName(), lineTime,
if (mPassengerCallback != null) {
mPassengerCallback.updateBusTaskStatus(busRoutesResult.getName(), lineTime,
stationList, arrivingOrArrivedStationIndex, false);
}
updateAutopilotControlParameters();
@@ -759,8 +736,8 @@ public class OrderModel {
+ " startLatLon=" + parameters.startName + "endLatLon=" + parameters.endName +
"isRestart = " + isRestart);
if (mControllerStatusCallback != null) {
mControllerStatusCallback.startOpenAutopilot();
if (mPassengerCallback != null) {
mPassengerCallback.startOpenAutopilot();
}
}
@@ -1029,8 +1006,8 @@ public class OrderModel {
}
if (currentStation.isLeaving() && slidePanelHideCallback != null) {
slidePanelHideCallback.hideSlidePanel();
if (currentStation.isLeaving() && mPassengerCallback != null) {
mPassengerCallback.hideSlidePanel();
}
sendTaskDetailsToClients();
@@ -1107,8 +1084,8 @@ public class OrderModel {
}
public void clearBusStationDatas() {
if (refreshBusStationsCallback != null) {
refreshBusStationsCallback.clearBusStationsMarkers();
if (mPassengerCallback != null) {
mPassengerCallback.clearBusStationsMarkers();
}
}

View File

@@ -1,130 +0,0 @@
package com.mogo.och.bus.net;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.bus.bean.request.BusCloseTaskRequest;
import com.mogo.och.bus.bean.response.BusQueryLineTaskResponse;
import com.mogo.och.bus.bean.response.BusQueryLinesResponse;
import com.mogo.och.bus.bean.request.BusRoutePlanningUpdateReqBean;
import com.mogo.och.bus.bean.response.BusRoutesResponse;
import com.mogo.och.bus.bean.request.CarHeartbeatReqBean;
import com.mogo.och.bus.bean.request.BusQueryLineStationsRequest;
import com.mogo.och.bus.bean.request.BusResetDrivingLineRequest;
import com.mogo.och.bus.bean.request.BusUpdateSiteStatusRequest;
import io.reactivex.Observable;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Query;
/**
* 小巴车相关接口
*
* @author tongchenfei
* <p>
* wiki: http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=48970072
*/
public interface IBascApiService {
/**
* 根据车机坐标获取所在区域全部站点信息
*
* @param request 请求参数
* @return 接口返回数据
*/
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/line/v2/driver/bus/lineDataWithDriver/query" )
Observable<BusRoutesResponse> queryBusRoutes(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusQueryLineStationsRequest request);
/**
* @param request 请求参数{"destLine":1,"sn":"F803EB2046PZD00229"} 这个接口是重置bus线路的 不是重置线路中站点的
* @return 返回值是重置后的车站列表
* 开始路线
*/
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/cab/flow/v1/bus/driver/bus/startTask" )
Observable<BusRoutesResponse> switchLine(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusResetDrivingLineRequest request);
/**
* 离站,通知服务器
* @param request
* @return
*/
@Headers({"Content-Type:application/json;charset=UTF-8"})
@POST("/autopilot-car-hailing/cab/flow/v1/bus/driver/bus/leave")
Observable<BaseData> leaveStation(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusUpdateSiteStatusRequest request);
/**
* 到站 更新到站信息
* @param request
* @return
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("/autopilot-car-hailing/cab/flow/v1/bus/driver/bus/arrive")
Observable< BaseData > arriveSiteStation(@Header ("appId") String appId,@Header("ticket") String ticket,@Body BusUpdateSiteStatusRequest request);
/**
* 车机端上传心跳数据(只在出车状态时上传):包含高德坐标系经纬度
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/location/v2/driver/bus/heartbeat" )
Observable<BaseData> runCarHeartbeat(@Header ("appId") String appId,@Header("ticket") String ticket,@Body CarHeartbeatReqBean data);
/**
* 查询车辆配置的所有路线
* @param appId
* @param ticket
* @param sn
* @return
*/
@GET("/autopilot-car-hailing/line/v2/driver/bus/bindLine/query")
Observable<BusQueryLinesResponse> queryBusLines(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
/**
* 查询路线当天的任务
* @param appId
* @param ticket
* @param lineId 线路id
* @return
*/
@GET("/autopilot-car-hailing/line/v2/driver/bus/task/query")
Observable<BusQueryLineTaskResponse> queryBusTaskByLineId(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("lineId") String lineId);
/**
* 上传轨迹信息
* @param appId
* @param ticket
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/location/v2/driver/bus/saveLineCoordinate" )
Observable<BaseData> updateOrderRoute(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusRoutePlanningUpdateReqBean data);
/**
* 中止任务
* @param appId
* @param ticket
* @param data
* @return
*/
@POST("/autopilot-car-hailing/cab/flow/v1/bus/driver/bus/abortTask")
Observable<BaseData> abortTask(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusCloseTaskRequest data);
/**
* 任务正常跑完结束
* @param appId
* @param ticket
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST("/autopilot-car-hailing/cab/flow/v1/bus/driver/bus/endTask")
Observable<BaseData> endTask(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusCloseTaskRequest data);
}

View File

@@ -0,0 +1,166 @@
package com.mogo.och.bus.net
import com.mogo.eagle.core.data.BaseData
import com.mogo.och.bus.bean.request.BusCloseTaskRequest
import com.mogo.och.bus.bean.request.BusQueryLineStationsRequest
import com.mogo.och.bus.bean.request.BusResetDrivingLineRequest
import com.mogo.och.bus.bean.request.BusRoutePlanningUpdateReqBean
import com.mogo.och.bus.bean.request.BusUpdateSiteStatusRequest
import com.mogo.och.bus.bean.request.CarHeartbeatReqBean
import com.mogo.och.bus.bean.response.BusQueryLineTaskResponse
import com.mogo.och.bus.bean.response.BusQueryLinesResponse
import com.mogo.och.bus.bean.response.BusRoutesResponse
import io.reactivex.Observable
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Headers
import retrofit2.http.POST
import retrofit2.http.Query
/**
* 小巴车相关接口
*
* @author tongchenfei
*
*
* wiki: http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=48970072
*/
interface IBascApiService {
/**
* 根据车机坐标获取所在区域全部站点信息
*
* @param request 请求参数
* @return 接口返回数据
*/
@Headers("Content-Type:application/json;charset=UTF-8")
@POST("/autopilot-car-hailing/line/v2/driver/bus/lineDataWithDriver/query")
fun queryBusRoutes(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body request: BusQueryLineStationsRequest?
): Observable<BusRoutesResponse>
/**
* @param request 请求参数{"destLine":1,"sn":"F803EB2046PZD00229"} 这个接口是重置bus线路的 不是重置线路中站点的
* @return 返回值是重置后的车站列表
* 开始路线
*/
@Headers("Content-Type:application/json;charset=UTF-8")
@POST("/autopilot-car-hailing/cab/flow/v1/bus/driver/bus/startTask")
fun switchLine(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body request: BusResetDrivingLineRequest?
): Observable<BusRoutesResponse>
/**
* 离站,通知服务器
* @param request
* @return
*/
@Headers("Content-Type:application/json;charset=UTF-8")
@POST("/autopilot-car-hailing/cab/flow/v1/bus/driver/bus/leave")
fun leaveStation(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body request: BusUpdateSiteStatusRequest?
): Observable<BaseData>
/**
* 到站 更新到站信息
* @param request
* @return
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/autopilot-car-hailing/cab/flow/v1/bus/driver/bus/arrive")
fun arriveSiteStation(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body request: BusUpdateSiteStatusRequest?
): Observable<BaseData>
/**
* 车机端上传心跳数据(只在出车状态时上传):包含高德坐标系经纬度
* @param data
* @return
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/autopilot-car-hailing/location/v2/driver/bus/heartbeat")
fun runCarHeartbeat(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body data: CarHeartbeatReqBean?
): Observable<BaseData>
/**
* 查询车辆配置的所有路线
* @param appId
* @param ticket
* @param sn
* @return
*/
@GET("/autopilot-car-hailing/line/v2/driver/bus/bindLine/query")
fun queryBusLines(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Query("sn") sn: String?
): Observable<BusQueryLinesResponse>
/**
* 查询路线当天的任务
* @param appId
* @param ticket
* @param lineId 线路id
* @return
*/
@GET("/autopilot-car-hailing/line/v2/driver/bus/task/query")
fun queryBusTaskByLineId(@Header("appId") appId: String?, @Header("ticket") ticket: String?, @Query("lineId") lineId: String?): Observable<BusQueryLineTaskResponse>
/**
* 上传轨迹信息
* @param appId
* @param ticket
* @param data
* @return
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/autopilot-car-hailing/location/v2/driver/bus/saveLineCoordinate")
fun updateOrderRoute(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body data: BusRoutePlanningUpdateReqBean?
): Observable<BaseData>
/**
* 中止任务
* @param appId
* @param ticket
* @param data
* @return
*/
@POST("/autopilot-car-hailing/cab/flow/v1/bus/driver/bus/abortTask")
fun abortTask(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body data: BusCloseTaskRequest?
): Observable<BaseData>
/**
* 任务正常跑完结束
* @param appId
* @param ticket
* @param data
* @return
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/autopilot-car-hailing/cab/flow/v1/bus/driver/bus/endTask")
fun endTask(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body data: BusCloseTaskRequest?
): Observable<BaseData>
}

View File

@@ -1,108 +0,0 @@
package com.mogo.och.bus.net;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.bus.bean.request.BusCloseTaskRequest;
import com.mogo.och.bus.bean.response.BusQueryLineTaskResponse;
import com.mogo.och.bus.bean.response.BusQueryLinesResponse;
import com.mogo.och.bus.bean.request.BusResetDrivingLineRequest;
import com.mogo.och.bus.bean.request.BusRoutePlanningUpdateReqBean;
import com.mogo.och.bus.bean.response.BusRoutesResponse;
import com.mogo.och.bus.bean.request.BusUpdateSiteStatusRequest;
import io.reactivex.Observable;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Header;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Query;
/**
* 小巴车相关接口
*
* @author tongchenfei
* <p>
* wiki: http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=48970072
*/
public interface ISAASApiService {
/**
* 根据车机坐标获取所在区域全部站点信息
*/
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
@GET( "/och-bus-cabin/api/business/v1/driver/bus/lineDataWithDriver/query" )
Observable<BusRoutesResponse> queryBusRoutes(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
/**
* @param request 请求参数{"destLine":1,"sn":"F803EB2046PZD00229"} 这个接口是重置bus线路的 不是重置线路中站点的
* @return 返回值是重置后的车站列表
* 开始路线
*/
@Headers( {"Content-Type:application/json;charset=UTF-8"} )
@POST( "/och-bus-cabin/cab/flow/v1/bus/driver/startTask" )
Observable<BusRoutesResponse> switchLine(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusResetDrivingLineRequest request);
/**
* 离站,通知服务器
*/
@Headers({"Content-Type:application/json;charset=UTF-8"})
@POST("/och-bus-cabin/cab/flow/v1/bus/driver/leave")
Observable<BaseData> leaveStation(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusUpdateSiteStatusRequest request);
/**
* 到站 更新到站信息
*/
@Headers({"Content-type:application/json;charset=UTF-8"})
@POST("/och-bus-cabin/cab/flow/v1/bus/driver/arrive")
Observable< BaseData > arriveSiteStation(@Header ("appId") String appId,@Header("ticket") String ticket,@Body BusUpdateSiteStatusRequest request);
/**
* 查询车辆配置的所有路线
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@GET("/och-bus-cabin/api/business/v1/driver/BusBindLine")
Observable<BusQueryLinesResponse> queryBusLines(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("sn") String sn);
/**
* 查询路线当天的任务
* @param appId
* @param ticket
* @param lineId 线路id
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@GET("/och-bus-cabin/api/business/v1/driver/bus/task/query")
Observable<BusQueryLineTaskResponse> queryBusTaskByLineId(@Header ("appId") String appId, @Header("ticket") String ticket, @Query("lineId") String lineId);
/**
* 上传轨迹信息
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST( "/autopilot-car-hailing/location/v2/driver/bus/saveLineCoordinate" )
Observable<BaseData> updateOrderRoute(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusRoutePlanningUpdateReqBean data);
/**
* 中止任务
* @param appId
* @param ticket
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST("/och-bus-cabin/cab/flow/v1/bus/driver/abortTask")
Observable<BaseData> abortTask(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusCloseTaskRequest data);
/**
* 任务正常跑完结束
* @param appId
* @param ticket
* @param data
* @return
*/
@Headers( {"Content-type:application/json;charset=UTF-8"} )
@POST("/och-bus-cabin/cab/flow/v1/bus/driver/endTask")
Observable<BaseData> endTask(@Header ("appId") String appId, @Header("ticket") String ticket, @Body BusCloseTaskRequest data);
}

View File

@@ -0,0 +1,143 @@
package com.mogo.och.bus.net
import com.mogo.eagle.core.data.BaseData
import com.mogo.och.bus.bean.request.BusCloseTaskRequest
import com.mogo.och.bus.bean.request.BusResetDrivingLineRequest
import com.mogo.och.bus.bean.request.BusRoutePlanningUpdateReqBean
import com.mogo.och.bus.bean.request.BusUpdateSiteStatusRequest
import com.mogo.och.bus.bean.response.BusQueryLineTaskResponse
import com.mogo.och.bus.bean.response.BusQueryLinesResponse
import com.mogo.och.bus.bean.response.BusRoutesResponse
import io.reactivex.Observable
import retrofit2.http.Body
import retrofit2.http.GET
import retrofit2.http.Header
import retrofit2.http.Headers
import retrofit2.http.POST
import retrofit2.http.Query
/**
* 小巴车相关接口
*
* @author tongchenfei
*
*
* wiki: http://wiki.zhidaohulian.com/pages/viewpage.action?pageId=48970072
*/
interface ISAASApiService {
/**
* 根据车机坐标获取所在区域全部站点信息
*/
@Headers("Content-Type:application/json;charset=UTF-8")
@GET("/och-bus-cabin/api/business/v1/driver/bus/lineDataWithDriver/query")
fun queryBusRoutes(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Query("sn") sn: String?
): Observable<BusRoutesResponse>
/**
* @param request 请求参数{"destLine":1,"sn":"F803EB2046PZD00229"} 这个接口是重置bus线路的 不是重置线路中站点的
* @return 返回值是重置后的车站列表
* 开始路线
*/
@Headers("Content-Type:application/json;charset=UTF-8")
@POST("/och-bus-cabin/cab/flow/v1/bus/driver/startTask")
fun switchLine(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body request: BusResetDrivingLineRequest?
): Observable<BusRoutesResponse>
/**
* 离站,通知服务器
*/
@Headers("Content-Type:application/json;charset=UTF-8")
@POST("/och-bus-cabin/cab/flow/v1/bus/driver/leave")
fun leaveStation(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body request: BusUpdateSiteStatusRequest?
): Observable<BaseData>
/**
* 到站 更新到站信息
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/och-bus-cabin/cab/flow/v1/bus/driver/arrive")
fun arriveSiteStation(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body request: BusUpdateSiteStatusRequest?
): Observable<BaseData>
/**
* 查询车辆配置的所有路线
*/
@Headers("Content-type:application/json;charset=UTF-8")
@GET("/och-bus-cabin/api/business/v1/driver/BusBindLine")
fun queryBusLines(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Query("sn") sn: String?
): Observable<BusQueryLinesResponse>
/**
* 查询路线当天的任务
* @param appId
* @param ticket
* @param lineId 线路id
* @return
*/
@Headers("Content-type:application/json;charset=UTF-8")
@GET("/och-bus-cabin/api/business/v1/driver/bus/task/query")
fun queryBusTaskByLineId(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Query("lineId") lineId: String?
): Observable<BusQueryLineTaskResponse>
/**
* 上传轨迹信息
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/autopilot-car-hailing/location/v2/driver/bus/saveLineCoordinate")
fun updateOrderRoute(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body data: BusRoutePlanningUpdateReqBean?
): Observable<BaseData>
/**
* 中止任务
* @param appId
* @param ticket
* @param data
* @return
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/och-bus-cabin/cab/flow/v1/bus/driver/abortTask")
fun abortTask(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body data: BusCloseTaskRequest?
): Observable<BaseData>
/**
* 任务正常跑完结束
* @param appId
* @param ticket
* @param data
* @return
*/
@Headers("Content-type:application/json;charset=UTF-8")
@POST("/och-bus-cabin/cab/flow/v1/bus/driver/endTask")
fun endTask(
@Header("appId") appId: String?,
@Header("ticket") ticket: String?,
@Body data: BusCloseTaskRequest?
): Observable<BaseData>
}

View File

@@ -1,322 +0,0 @@
package com.mogo.och.bus.presenter;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
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.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.bus.bean.WriteOffPassenger;
import com.mogo.och.bus.callback.IBusADASStatusCallback;
import com.mogo.och.bus.callback.IBusControllerStatusCallback;
import com.mogo.och.bus.callback.IPassengerCallback;
import com.mogo.och.bus.callback.IRefreshBusStationsCallback;
import com.mogo.och.bus.callback.ISlidePannelHideCallback;
import com.mogo.och.bus.fragment.BusFragment;
import com.mogo.och.bus.model.OrderModel;
import com.mogo.och.bus.util.BusTrajectoryManager;
import com.mogo.och.bus.util.BusVoiceManager;
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.manager.autopilot.OCHAdasAbilityManager;
import com.mogo.och.common.module.manager.autopilot.autopilot.bean.ArrivedStation;
import com.mogo.och.common.module.manager.autopilot.autopilot.IOchAutopilotStatusListener;
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotStatusListenerManager;
import com.mogo.och.data.bean.BusStationBean;
import java.util.ArrayList;
import java.util.List;
import mogo.telematics.pad.MessagePad;
import mogo_msg.MogoReportMsg;
/**
* 网约车小巴
*/
public class BusPresenter extends Presenter<BusFragment>
implements IRefreshBusStationsCallback, ISlidePannelHideCallback
, IBusControllerStatusCallback, ILoginCallback, IPassengerCallback, IBusADASStatusCallback, IOchAutopilotStatusListener {
private static final String TAG = "BusPresenter";
private final List<BusStationBean> mStationList = new ArrayList<>();
private int mCurrentStation = 0;
public BusPresenter(BusFragment 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().setPassengerCallback(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().setPassengerCallback(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.setArrivedClickable(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 onAutopilotSNRequest(@NonNull MessagePad.BasicInfoReq basicInfoReq) {
}
@Override
public void onAutopilotStatusResponse(int state) {
switch (state) {
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE:
case IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE:
case IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING:
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 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));
}
}
/**
* 测试使用
*/
public void debugAutoPilotStatus(int status) {
onAutopilotStatusResponse(status);
}
@Override
public void onAutopilotGuardian(@Nullable MogoReportMsg.MogoReportMessage guardianInfo, long lineId) {
BusTrajectoryManager.getInstance().onAutopilotGuardian(guardianInfo, lineId);
}
@Override
public void onStatusChange(LoginStatusEnum currentStatus) {
CallerLogger.d(M_BUS + TAG, " loginStatus =" + LoginStatusManager.isLogin());
if (LoginStatusManager.isLogin()) {
OrderModel.getInstance().startOrStopOrderLoop(true);
OrderModel.getInstance().queryBusCacheRoutes();
} else {
BusTrajectoryManager.getInstance().stopTrajReqLoop();
OrderModel.getInstance().startOrStopOrderLoop(false);
BusTrajectoryManager.getInstance().stopTrajReqLoop();
clearBusStationsMarkers();
if(mView!=null) {
mView.hideSlidePanel();
}
OrderModel.getInstance().closeBeautificationMode();
}
}
@Override
public void playPassenger(WriteOffPassenger passenger) {
int passengerNum = passenger.passengerSize;
BusVoiceManager.INSTANCE.writeOffCount(passengerNum);
}
@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) {
if(mView!=null) {
mView.onAutopilotStatusChanged(CallerAutoPilotStatusListenerManager.INSTANCE.getState(), canStart);
}
}
}

View File

@@ -0,0 +1,259 @@
package com.mogo.och.bus.presenter
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.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.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.bus.bean.WriteOffPassenger
import com.mogo.och.bus.callback.IPassengerCallback
import com.mogo.och.bus.fragment.BusFragment
import com.mogo.och.bus.model.OrderModel
import com.mogo.och.bus.util.BusTrajectoryManager
import com.mogo.och.bus.util.BusVoiceManager
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.manager.autopilot.OCHAdasAbilityManager
import com.mogo.och.common.module.manager.autopilot.autopilot.IOchAutopilotStatusListener
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotStatusListenerManager
import com.mogo.och.common.module.manager.autopilot.autopilot.bean.ArrivedStation
import com.mogo.och.data.bean.BusStationBean
import mogo_msg.MogoReportMsg;
/**
* 网约车小巴
*/
class BusPresenter(view: BusFragment?) : Presenter<BusFragment?>(view), ILoginCallback,
IPassengerCallback, IOchAutopilotStatusListener {
private val mStationList: MutableList<BusStationBean> = ArrayList<BusStationBean>()
private var mCurrentStation = 0
init {
//2021.11.1 鹰眼架构整合由IMoGoAutopilotStatusListener逐步替代IMogoAdasOCHCallback接口
OrderModel.getInstance().init()
OCHAdasAbilityManager.getInstance().init(AbsMogoApplication.getApp())
}
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
initModelListener()
OrderModel.getInstance().queryBusCacheRoutes()
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
OrderModel.getInstance().release()
releaseListener()
}
fun initModelListener() {
OrderModel.getInstance().setPassengerCallback(this)
OchAutoPilotStatusListenerManager.addListener(TAG, this)
LoginStatusManager.addListener(TAG, this)
}
fun releaseListener() {
OrderModel.getInstance().setPassengerCallback(null)
OCHAdasAbilityManager.getInstance().release()
OchAutoPilotStatusListenerManager.removeListener(TAG)
LoginStatusManager.removeListener(TAG)
}
fun abortTask() {
OrderModel.getInstance().abortTask()
}
fun autoDriveToNextStation() {
OrderModel.getInstance().autoDriveToNextStation()
}
fun restartAutopilot() {
if (OrderModel.getInstance().isGoingToNextStation) {
OrderModel.getInstance().restartAutopilot()
}
}
// 登出
fun logout() {
OrderModel.getInstance().logout()
}
override fun updateBusTaskStatus(
lineName: String, lineTime: String,
stationList: List<BusStationBean>,
arrivingOrArrivedIndex: Int,
isArrived: Boolean
) {
mStationList.clear()
mStationList.addAll(stationList)
mCurrentStation = if (arrivingOrArrivedIndex == 0 || isArrived) {
arrivingOrArrivedIndex
} else {
arrivingOrArrivedIndex - 1
}
CallerLogger.d(
SceneConstant.Companion.M_BUS + "BusOrderModel =",
" mCurrentStation =$mCurrentStation"
)
UiThreadHandler.post({
mView?.updateBusTaskStatus(
lineName, lineTime,
stationList, arrivingOrArrivedIndex, isArrived
)
}, UiThreadHandler.MODE.QUEUE)
}
override fun updateEmptyUi() {
UiThreadHandler.post({
mView?.updateLineEmptyUI()
}, UiThreadHandler.MODE.QUEUE)
}
override fun clearBusStationsMarkers() {
UiThreadHandler.post({
mView?.clearBusStationsMarkers()
}, UiThreadHandler.MODE.QUEUE)
}
override fun hideSlidePanel() {
mView?.hideSlidePanel()
mView?.setArrivedClickable(true)
}
override fun onAutopilotArriveAtStation(arrivedStation: ArrivedStation) {
CallerLogger.e(
SceneConstant.Companion.M_BUS + TAG,
"行程日志-onAutopilotArriveAtStation arrive"
)
arriveStation(arrivedStation, "底盘触发进站")
}
fun arriveStation(arrivedStation: ArrivedStation?, type: String?) {
OrderModel.getInstance().onArriveAt(arrivedStation, type)
}
override fun onAutopilotStatusResponse(state: Int) {
when (state) {
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE, IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE, IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING -> {
if (FunctionBuildConfig.isDemoMode
&& ((mCurrentStation >= 0 && mCurrentStation <= mStationList.size - 1)
&& OrderModel.getInstance().isGoingToNextStation
)
) {
CallerLogger.d(SceneConstant.Companion.M_BUS + "BusOrderModel=", "有美化功能")
return
}
// 改变UI自动驾驶状态
UiThreadHandler.post({
mView?.onAutopilotStatusChanged(
state,
CallerAutoPilotControlManager.isCanStartAutopilot(false, 0)
)
}, UiThreadHandler.MODE.QUEUE)
}
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING -> {
OrderModel.getInstance().triggerStartServiceEvent(
OrderModel.getInstance().isRestartAutopilot, true, 0
)
// 改变UI自动驾驶状态
UiThreadHandler.post({
mView?.onAutopilotStatusChanged(
state,
CallerAutoPilotControlManager.isCanStartAutopilot(false, 0)
)
}, UiThreadHandler.MODE.QUEUE)
}
else -> UiThreadHandler.post({
mView?.onAutopilotEnableChange(false)
}, UiThreadHandler.MODE.QUEUE)
}
}
override fun onAutopilotStatusResponseFromCan(state: Int) {
if (state == IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING) {
OrderModel.getInstance().triggerStartServiceEvent(
OrderModel.getInstance().isRestartAutopilot, true, 1
)
}
}
override fun startOpenAutopilot() {
//非美化模式下启动动画
UiThreadHandler.post({
mView?.startAutopilotAnimation()
}, UiThreadHandler.MODE.QUEUE)
//中间站点再次开启自驾时, 自动驾驶状态是2未改变 此次鹰眼底层不再返给业务,需优化按钮动画显示
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
== CallerAutoPilotStatusListenerManager.getState() && mView != null
) {
mView?.onAutopilotStatusChanged(
CallerAutoPilotStatusListenerManager.getState(),
CallerAutoPilotControlManager.isCanStartAutopilot(false, 0)
)
}
}
/**
* 测试使用
*/
fun debugAutoPilotStatus(status: Int) {
onAutopilotStatusResponse(status)
}
override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?, lineId: Long) {
BusTrajectoryManager.getInstance().onAutopilotGuardian(guardianInfo, lineId)
}
override fun onStatusChange(currentStatus: LoginStatusEnum) {
CallerLogger.d(
SceneConstant.Companion.M_BUS + TAG,
" loginStatus =" + LoginStatusManager.isLogin()
)
if (LoginStatusManager.isLogin()) {
OrderModel.getInstance().startOrStopOrderLoop(true)
OrderModel.getInstance().queryBusCacheRoutes()
} else {
BusTrajectoryManager.getInstance().stopTrajReqLoop()
OrderModel.getInstance().startOrStopOrderLoop(false)
BusTrajectoryManager.getInstance().stopTrajReqLoop()
clearBusStationsMarkers()
mView?.hideSlidePanel()
OrderModel.getInstance().closeBeautificationMode()
}
}
override fun playPassenger(passenger: WriteOffPassenger) {
val passengerNum = passenger.passengerSize
BusVoiceManager.writeOffCount(passengerNum)
}
override fun onStartAdasFailure() {
UiThreadHandler.post({
mView?.stopAnimAndUpdateBtnStatus()
}, UiThreadHandler.MODE.QUEUE)
}
override fun canStartAutopilot(canStart: Boolean) {
mView?.onAutopilotStatusChanged(
CallerAutoPilotStatusListenerManager.getState(),
canStart
)
}
companion object {
private const val TAG = "BusPresenter"
}
}

View File

@@ -120,10 +120,10 @@ class BusSwitchLineActivity : MvpActivity<BusSwitchLineView?, BusLinePresenter?>
return
}
val lastCommitLineid = SharedPrefsMgr.getInstance().getInt(LASTCOMMITLINEID, -1)
if (data.data != null && data.data.size > 0) {
if (data.data != null && data.data.isNullOrEmpty()) {
showNoData(false)
mData.clear()
mData.addAll(data.data)
mData.addAll(data.data!!)
mAdapter.notifyDataSetChanged()
if(lastCommitLineid>0){
mData.forEachIndexed { index, line ->
@@ -157,17 +157,17 @@ class BusSwitchLineActivity : MvpActivity<BusSwitchLineView?, BusLinePresenter?>
// 打开操作
mAdapter.notifyItemChanged(position)
} else {
if (lineTaskInfo.data == null || lineTaskInfo.data.isEmpty()) {
if (lineTaskInfo.data.isNullOrEmpty()) {
result.haveTask = true
lineTaskInfo.data = ArrayList()
}
if (lineTaskInfo.data.size != result.taskList.size) { // 不相等有变动 重新赋值
result.taskList.clear()
result.taskList.addAll(lineTaskInfo.data)
if (lineTaskInfo.data!!.size != result.taskList!!.size) { // 不相等有变动 重新赋值
result.taskList!!.clear()
result.taskList!!.addAll(lineTaskInfo.data!!)
if(autoRefresh) {
mAdapter.checkTaskId = -1
mAdapter.checkLineId = -1
lineTaskInfo.data.forEach {
lineTaskInfo.data?.forEach {
if (it.id == mAdapter.checkTaskId) {
mAdapter.checkTaskId = it.id
mAdapter.checkLineId = result.lineId
@@ -178,7 +178,7 @@ class BusSwitchLineActivity : MvpActivity<BusSwitchLineView?, BusLinePresenter?>
mAdapter.notifyItemChanged(position)
linearLayoutManager.stackFromEnd = (position==mData.size-1||position==mData.size-2)&&mData.size>6
mLinesListView.smoothScrollToPosition(position)
}else if(lineTaskInfo.data.isEmpty()){
}else if(lineTaskInfo.data.isNullOrEmpty()){
mAdapter.notifyItemChanged(position)
}
}

View File

@@ -42,15 +42,15 @@ class SwitchLineAdapter(
override fun onBindViewHolder(holder: SwitchLineViewHolder, position: Int) {
val currentPosition = holder.bindingAdapterPosition
val line = mData[currentPosition]
if(line.name!=null&&line.name.length>10){
line.name = line.name.substring(0,10)+""
if(line.name!=null&&line.name!!.length>10){
line.name = line.name!!.substring(0,10)+""
}
holder.lineName.text = line.name
val sb = StringBuilder()
if (line.endSiteName!=null&&line.endSiteName.length>10) {
sb.append(line.endSiteName.substring(0,5))
if (line.endSiteName!=null&&line.endSiteName!!.length>10) {
sb.append(line.endSiteName!!.substring(0,5))
sb.append("")
sb.append(line.endSiteName.substring(line.endSiteName.length-5,line.endSiteName.length))
sb.append(line.endSiteName!!.substring(line.endSiteName!!.length-5,line.endSiteName!!.length))
}else{
sb.append(line.endSiteName)
}
@@ -66,7 +66,7 @@ class SwitchLineAdapter(
try {
if (isCheck) {
checkLineId = line.lineId
checkTaskId = line.taskList[position].id
checkTaskId = line.taskList!![position].id ?: 0
} else {
checkLineId = -1
checkTaskId = -1
@@ -83,7 +83,7 @@ class SwitchLineAdapter(
holder.actvShowMore.visibility = View.VISIBLE
if(line.open){
if(line.taskList==null||line.taskList.isEmpty()){
if(line.taskList.isNullOrEmpty()){
holder.actvShowMore.text = mContext.getString(R.string.bus_switch_line_no_task)
holder.actvShowMore.setTextColor(ContextCompat.getColor(mContext,R.color.bus_color_4dffffff))
holder.vLineTask.visibility = View.GONE
@@ -137,7 +137,7 @@ class SwitchLineAdapter(
result.open = false;
notifyItemChanged(index)
if(result.taskList!=null) {
result.taskList.clear()
result.taskList!!.clear()
}
if(index==currentPosition){// 点击当前已经打开的item 去关闭定时网络请求
mItemClickListener?.onItemClick(currentPosition,true)

View File

@@ -7,6 +7,7 @@ import android.os.Message
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.mogo.logger.scene.SceneConstant.Companion.M_BUS_P
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.common.module.utils.RxUtils
import io.reactivex.Observable
import io.reactivex.Observer
@@ -130,4 +131,14 @@ object BizLoopManager {
handler.removeCallbacks(function)
}
fun runInMainThread(function: Runnable){
if (ThreadUtils.isMainThread()) {
function.run()
}else{
ThreadUtils.runOnUiThread({
function.run()
},ThreadUtils.MODE.QUEUE)
}
}
}

View File

@@ -38,7 +38,7 @@ class ZhiView : ConstraintLayout, ZhiViewmanager.IViewCallback {
private fun initView() {
LayoutInflater.from(context).inflate(R.layout.common_xiaozhi, this, true)
setOnClickListener {
ZhiStateManager.weakUpXiaoZhi()
//ZhiStateManager.weakUpXiaoZhi()
}
}

View File

@@ -23,6 +23,7 @@ public class DateTimeUtil {
public static final String yy_MM_dd = "yy.MM.dd";
public static final String yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm";
public static final String yyyy_MM_dd_HH_mm_ss = "yyyy-MM-dd HH:mm:ss";
public static final String HH_mm_ss = "HH:mm:ss";
public static final String MM_dd_HH_mm_china = "yyyy年MM月dd日";
public static String formatCalendarToString(Calendar calendar, String format){

View File

@@ -1,5 +1,6 @@
package com.mogo.och.common.module.utils
import android.content.res.ColorStateList
import android.graphics.BitmapFactory
import androidx.annotation.ColorRes
import androidx.annotation.StringRes
@@ -11,6 +12,10 @@ object ResourcesUtils {
fun getColor(@ColorRes id: Int): Int {
return ContextCompat.getColor(AbsMogoApplication.getApp(),id)
}
@JvmStatic
fun getColors(@ColorRes id: Int): ColorStateList? {
return ContextCompat.getColorStateList(AbsMogoApplication.getApp(),id)
}
@JvmStatic
fun getString(@StringRes id: Int): String {

View File

@@ -15,6 +15,7 @@ import com.mogo.map.listener.IMogoMapListener
import com.mogo.map.listener.MogoMapListenerHandler
import com.mogo.map.uicontroller.EnumMapUI
import com.mogo.och.common.module.R
import com.mogo.och.common.module.biz.login.LoginStatusManager
import kotlinx.android.synthetic.main.common_loading_map.view.aciv_loading_map
class CommonLoadingView @JvmOverloads constructor(
@@ -56,6 +57,33 @@ class CommonLoadingView @JvmOverloads constructor(
HdMapBuildConfig.isMapLoaded = true
// 设置地图样式
MogoMapListenerHandler.mogoMapListenerHandler.onMapModeChanged(EnumMapUI.MAP_STYLE_DAY_VR)
when (LoginStatusManager.getLoginInfo()?.carModel) {
"E70" -> {
HdMapBuildConfig.currentCarVrIconRes = com.mogo.eagle.core.data.R.raw.chuzuche
}
"H9" -> {
HdMapBuildConfig.currentCarVrIconRes = com.mogo.eagle.core.data.R.raw.hq_h9
}
"B1" -> {
HdMapBuildConfig.currentCarVrIconRes = com.mogo.eagle.core.data.R.raw.xiaoba
}
"B2" -> {
HdMapBuildConfig.currentCarVrIconRes = com.mogo.eagle.core.data.R.raw.m2
}
"M1" -> {
HdMapBuildConfig.currentCarVrIconRes = R.raw.m1
}
"金旅牌XML6606JEVY0"-> {
HdMapBuildConfig.currentCarVrIconRes = com.mogo.eagle.core.data.R.raw.xiaoba
}
"NJL6450ICEV"-> {
HdMapBuildConfig.currentCarVrIconRes = com.mogo.eagle.core.data.R.raw.xiaoba
}
"BJ5122TXSEV-H1"-> {
HdMapBuildConfig.currentCarVrIconRes = R.raw.huanwei
}
else -> {}
}
CallerMapUIServiceManager.getMapUIController()?.changeCurrentIcon(HdMapBuildConfig.currentCarVrIconRes)
UiThreadHandler.postDelayed({ visibility = GONE },2_000,UiThreadHandler.MODE.QUEUE)
}

View File

@@ -2,10 +2,7 @@
package="com.mogo.och.shuttle.weaknet">
<application>
<activity android:name="com.mogo.och.weaknet.ui.BusSwitchLineActivity"
android:theme="@style/SwitchLineDialogStyle"
android:launchMode="singleTask"
android:screenOrientation="landscape" />
</application>
</manifest>

View File

@@ -6,7 +6,6 @@ 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.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.weaknet.fragment.ShuttleFragment
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.biz.provider.CommonServiceImpl
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutopilotAnalytics
@@ -14,6 +13,7 @@ import com.mogo.och.weaknet.database.repository.EventRepository
import com.mogo.och.weaknet.database.repository.LineRepository
import com.mogo.och.weaknet.database.repository.TaskRepository
import com.mogo.och.weaknet.database.repository.TaskSiteRepository
import com.mogo.och.weaknet.fragment.ShuttleFragment
import com.mogo.och.weaknet.model.BusLineModel
import com.mogo.och.weaknet.util.BusAnalyticsManager

View File

@@ -36,10 +36,23 @@ public class BusQueryLinesResponse extends BaseData {
public String startSiteName;//始发站名称
public String endSiteName;//终点名称
public boolean open;//true 打开状态 false
public boolean haveTask;
public List<BusQueryLineTaskResponse.Result> taskList;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Result result = (Result) o;
return lineId == result.lineId;
}
@Override
public int hashCode() {
return Long.hashCode(lineId);
}
}

View File

@@ -25,8 +25,4 @@ public interface IBusADASStatusCallback {
* 结束清理一遍、选择任务后清理一遍
*/
void clearBusStationsMarkers();
void updateEmptyUi();
void hideSlidePanel();
}

View File

@@ -1,7 +1,12 @@
package com.mogo.och.weaknet.callback;
import com.mogo.och.data.bean.BusStationBean;
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse;
import com.mogo.och.weaknet.bean.BusQueryLinesResponse;
import com.mogo.och.weaknet.database.bean.TaskDataBean;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.List;
@@ -10,11 +15,23 @@ import java.util.List;
* @date: 2022/2/9
*/
public interface IBusLinesCallback {
void onBusLinesChange(List<BusQueryLinesResponse.Result> data);
void onChangeLineIdSuccess();
void onBusLineTasks(List<BusQueryLineTaskResponse.Result> o, int position,boolean autoRefresh);
default void onBusLinesChange(List<BusQueryLinesResponse.Result> data){}
default void onChangeLineIdSuccess(){}
default void onBusLineTasks(List<BusQueryLineTaskResponse.Result> o){}
void onRefreshSuccess(long currentTimeStamp);
default void onRefreshSuccess(long currentTimeStamp){}
void onChangeLineIdFail();
default void onChangeLineIdFail(){}
default void onNoRunningTask(){}
default void onRunningTask(){}
default void onLeaveStaionSuccess(){}
default void onLeaveStaionFail(){}
default void onArriveStationSuccess(){}
default void onCompleteTask(){}
}

View File

@@ -1,511 +0,0 @@
package com.mogo.och.weaknet.fragment
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.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.isCanStartAutopilot
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getState
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager.attachAutopilotBeforeLaunchView
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMapUIController
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.isB1
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils.isB2
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.och.common.module.utils.ResourcesUtils
import com.mogo.och.common.module.utils.ResourcesUtils.getColor
import com.mogo.och.common.module.utils.SoundPoolHelper
import com.mogo.och.common.module.wigets.SlidePanelView
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.constant.BusConst
import com.mogo.och.weaknet.view.BizMapView
import org.greenrobot.eventbus.EventBus
/**
* 网约车基础Fragment主要负责布局通用界面处理站点面板和通话面板互斥情况
*
*
* 部分业务放在了此处处理
*
* @author tongchenfei
*/
abstract class BaseShuttleTabFragment<V : IView?, P : Presenter<V>?> : MvpFragment<V, P>() {
protected var slidePanelView: SlidePanelView? = null
private var ctvAutopilotStatus: RelativeLayout? = null
private var ctvAutopilotStatusIv: ImageView? = null
private var ctvAutopilotStatusTv: TextView? = null
protected var tvArrived: TextView? = null
private var flStationPanelContainer: FrameLayout? = null
private var mapBizView: BizMapView? = null
private var groupTestPanel: Group? = null
protected var smallMapView: SmallMapView? = null
//消息盒子
private var viewDriverMsgBoxButton: DriverMsgBoxButtonView? = null
private var viewDriverMsgBoxList: DriverMsgBoxListView? = null
private var viewDriverMsgBoxBubble: DriverMsgBoxBubbleView? = null
private var autopilotLoadingAnimator: ObjectAnimator? = null
var isAnimateRunning: Boolean = false
/**
* 滑动按钮触发的事件
*/
private val onSlideToEndListener = SlidePanelView.OnSlidePanelMoveToEndListener {
// 此处做一个代理,处理一下共有情况
if (slidePanelOnEndListener() != null) {
slidePanelOnEndListener()!!.moveToEnd()
}
}
override fun getLayoutId(): Int {
return R.layout.shuttle_weak_base_fragment
}
override fun 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)
val flSpeed = findViewById<FrameLayout>(R.id.fl_speed)
if (flSpeed != null) {
attachAutopilotBeforeLaunchView(flSpeed.context, flSpeed)
}
LayoutInflater.from(context).inflate(stationPanelViewId(), flStationPanelContainer)
slidePanelView!!.setOnSlidePanelMoveToEndListener(onSlideToEndListener)
updateSwitchMapIcon()
initListener()
setAutopilotBtnStatus(
getState(),
isCanStartAutopilot(false, 0)
)
ctvAutopilotStatus!!.setOnClickListener(object : OnPreventFastClickListener() {
override fun onClickImpl(v: View) {
restartAutopilot()
}
})
// 模拟 不可自动驾驶目前场景是刚开机adas还未和工控机连接
findViewById<View>(R.id.btnAutopilotDisable)!!.setOnClickListener { view: View? ->
debugAutoPilotStatus(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE
)
}
// 模拟 可自动驾驶,工控机连接正常,且处于人工干预状态
findViewById<View>(R.id.btnAutopilotEnable)!!.setOnClickListener { view: View? ->
debugAutoPilotStatus(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_ENABLE
)
}
// 模拟 自动驾驶能力,自动驾驶中,可能是停车,可能是行进,但是是机器在处理车的前进后退,不是人
findViewById<View>(R.id.btnAutopilotRunning)!!.setOnClickListener { view: View? ->
debugAutoPilotStatus(
IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
)
}
findViewById<View>(R.id.btnAutopilotPingxing)!!.setOnClickListener { view: View? ->
debugAutoPilotStatus(
IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING
)
}
// 模拟 自动驾驶网约车回调数据
findViewById<View>(R.id.btnAutopilotArrive)!!.setOnClickListener { view: View? -> debugArrivedStation() }
tvArrived!!.setOnClickListener { view: View? ->
onArriveStation()
}
//消息盒子
viewDriverMsgBoxButton = findViewById(R.id.viewDriverMsgBoxButton)
viewDriverMsgBoxList = findViewById(R.id.viewDriverMsgBoxList)
viewDriverMsgBoxBubble = findViewById(R.id.viewDriverMsgBoxBubble)
viewDriverMsgBoxButton!!.setClickListener(object :DriverMsgBoxButtonView.ClickListener {
override fun showMsgBoxList(show: Boolean) {
if (show) {
viewDriverMsgBoxList!!.visibility = View.VISIBLE
viewDriverMsgBoxList!!.notifyData()
viewDriverMsgBoxBubble!!.visibility = View.GONE
viewDriverMsgBoxBubble!!.isShowData(false)
} else {
viewDriverMsgBoxList!!.visibility = View.GONE
viewDriverMsgBoxBubble!!.visibility = View.VISIBLE
viewDriverMsgBoxBubble!!.isShowData(true)
}
}
})
smallMapView = findViewById(R.id.smallMapView)
}
override fun initViews(savedInstanceState: Bundle?) {
super.initViews(savedInstanceState)
mapBizView!!.onCreate(savedInstanceState)
smallMapView!!.onCreateView(savedInstanceState)
}
override fun onResume() {
super.onResume()
mapBizView!!.onResume()
smallMapView!!.onResume()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
EventBus.getDefault().register(this)
return super.onCreateView(inflater, container, savedInstanceState)
}
protected abstract fun onArriveStation()
private fun updateSwitchMapIcon() {
val mapUIController = getMapUIController(MogoMap.DEFAULT)
if (mapUIController != null) {
if (isB2(FunctionBuildConfig.appIdentityMode)) {
mapUIController.changeCurrentIcon(R.raw.m2)
HdMapBuildConfig.currentCarVrIconRes = R.raw.m2
} else if (isB1(FunctionBuildConfig.appIdentityMode)) {
mapUIController.changeCurrentIcon(R.raw.xiaoba)
HdMapBuildConfig.currentCarVrIconRes = R.raw.xiaoba
}
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapBizView!!.onSaveInstanceState(outState)
}
override fun onLowMemory() {
super.onLowMemory()
mapBizView!!.onLowMemory()
}
override fun onPause() {
super.onPause()
mapBizView!!.onPause()
smallMapView!!.onPause()
}
override fun onDestroyView() {
mapBizView!!.onDestroy()
if (smallMapView != null) {
smallMapView!!.onDestroy()
}
super.onDestroyView()
CallerAutopilotRecordListenerManager.removeListener(TAG)
EventBus.getDefault().unregister(this)
}
/**
* 测试到站
*/
protected abstract fun debugArrivedStation()
private fun initListener() {
}
/**
* 展示滑动按钮
*
* @param text 指定的文字
*/
fun showSlidePanel(text: String?) {
UiThreadHandler.post({
slidePanelView!!.setText(text)
slidePanelView!!.visibility = View.VISIBLE
}, UiThreadHandler.MODE.QUEUE)
setArrivedClikable(false)
}
/**
* 设置进站按钮状态
*
* @param isClickable
*/
fun setArrivedClikable(isClickable: Boolean) {
UiThreadHandler.post({
tvArrived!!.isEnabled = 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)
}
/**
* 隐藏滑动按钮
*/
fun hideSlidePanel() {
UiThreadHandler.post(
{ slidePanelView!!.visibility = View.GONE },
UiThreadHandler.MODE.QUEUE
)
}
fun playDI() {
SoundPoolHelper.getSoundPoolHelper().playSoundWithRedId(context, R.raw.bus_di)
}
/**
* 改变自动驾驶状态
*
* @param autopilotStatus 0:不可用 1:可用状态 2:自动驾驶中
*/
fun onAutopilotStatusChanged(autopilotStatus: Int, canStartAuto: Boolean) {
UiThreadHandler.post({
changeAutopilotBtnView(
autopilotStatus,
isAnimateRunning,
canStartAuto
)
}, UiThreadHandler.MODE.QUEUE)
}
fun setAutopilotBtnStatus(autopilotStatus: Int, canStartAuto: Boolean) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE == autopilotStatus) { //0不可用
ctvAutopilotStatusTv!!.setTextColor(getColor(R.color.bus_autopilot_text_color_disable))
ctvAutopilotStatusTv!!.text =
ResourcesUtils.getString(R.string.bus_loading_autopilot_runnig_tv)
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_disable_autopilot_icon)
ctvAutopilotStatus!!.isClickable = 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!!.text =
ResourcesUtils.getString(R.string.bus_loading_autopilot_runnig_tv)
if (canStartAuto) {
ctvAutopilotStatus!!.isClickable = true
ctvAutopilotStatus!!.setBackgroundResource(R.drawable.common_autopilot_press)
} else {
ctvAutopilotStatusTv!!.setTextColor(getColor(R.color.bus_autopilot_text_color_disable))
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_disable_autopilot_icon)
ctvAutopilotStatus!!.isClickable = 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!!.isClickable = true
ctvAutopilotStatus!!.setBackgroundResource(R.drawable.common_autopilot_in_autopilot)
} else if (IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING
== autopilotStatus
) {
ctvAutopilotStatusTv!!.setText(R.string.bus_pingxing_driver)
ctvAutopilotStatus!!.isClickable = false
ctvAutopilotStatus!!.setBackgroundResource(R.drawable.common_autopilot_pxjs)
}
}
}
fun updateAutopilotStatus(autopilotStatus: Int) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
== autopilotStatus
) { //2 running
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_right_autopilot_icon)
ctvAutopilotStatusTv!!.setTextColor(getColor(R.color.bus_autopilot_text_color_normal))
ctvAutopilotStatusTv!!.text =
ResourcesUtils.getString(R.string.bus_loading_autopilot_success_tv)
// ctvAutopilotStatus.setSelected(false);
ctvAutopilotStatus!!.isClickable = false
} else {
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_wrong_autopilot_icon)
ctvAutopilotStatusTv!!.setTextColor(getColor(R.color.bus_autopilot_text_color_normal))
ctvAutopilotStatusTv!!.text =
ResourcesUtils.getString(R.string.bus_loading_autopilot_failure_tv)
ctvAutopilotStatus!!.isClickable = false
// ctvAutopilotStatus.setSelected(false);
}
UiThreadHandler.postDelayed({
setAutopilotBtnStatus(
autopilotStatus,
isCanStartAutopilot(false, 0)
)
}, 1000)
}
private fun changeAutopilotBtnView(
autopilotStatus: Int,
isAnimateRunning: Boolean,
canStartAuto: Boolean
) {
if (isAnimateRunning && (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
!= autopilotStatus)
) {
// 主动开启自动驾驶中不为2为0、1则继续loading
return
}
if (isAnimateRunning) {
stopAnimAndUpdateBtnStatus()
} else {
setAutopilotBtnStatus(autopilotStatus, canStartAuto)
}
}
fun stopAnimAndUpdateBtnStatus() {
stopAutopilotAnimation()
updateAutopilotStatus(getState())
}
/**
* 隐藏【自动驾驶】按钮
*/
fun hideAutopilotBiz() {
}
/**
* 展示【自动驾驶】按钮
*/
fun showAutopilotBiz() {
}
abstract fun slidePanelOnEndListener(): SlidePanelView.OnSlidePanelMoveToEndListener?
/**
* 获取站点面板view在[.initViews]时候添加到container中
*
* @return 站点面板view
*/
abstract fun stationPanelViewId(): Int
/**
* 重新开启自动驾驶
*/
abstract fun restartAutopilot()
/**
* 模拟自动驾驶返回状态
*
* @param status
*/
abstract fun debugAutoPilotStatus(status: Int)
/**
* 开启自动驾驶中间动画
*/
fun startAutopilotAnimation() {
isAnimateRunning = true
ctvAutopilotStatusTv!!.text =
ResourcesUtils.getString(R.string.bus_loading_autopilot_tv)
ctvAutopilotStatusTv!!.setTextColor(getColor(R.color.bus_autopilot_text_color_normal))
ctvAutopilotStatus!!.isClickable = true
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_loading_autopilot_icon)
if (autopilotLoadingAnimator == null) {
autopilotLoadingAnimator = ObjectAnimator.ofFloat(ctvAutopilotStatusIv!!, "rotation", 0f, 360f)
autopilotLoadingAnimator?.interpolator = LinearInterpolator()
autopilotLoadingAnimator?.repeatCount = -1 //无限循环
autopilotLoadingAnimator?.setDuration(1000) //设置持续时间
}
autopilotLoadingAnimator!!.start() //动画开始
startingAutoApilotCountDown()
}
private fun startingAutoApilotCountDown() {
//10s 若自动驾驶没有开启,则结束动画
UiThreadHandler.postDelayed({
//未启动成功做处理
if (isAnimateRunning) { // 只判断动画是否在进行,根据自动驾驶当前状态去设置自动驾驶状态
stopAutopilotAnimation()
updateAutopilotStatus(getState())
}
}, BusConst.TIMER_START_AUTOPILOT_INTERVAL)
}
/**
* 停止自动驾驶中间动画
*/
protected fun 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 fun onDestroy() {
super.onDestroy()
}
/**
* bus调试面板打开关闭
*/
fun debugTestBar() {
if (groupTestPanel!!.visibility == View.VISIBLE) {
groupTestPanel!!.visibility = View.GONE
} else {
groupTestPanel!!.visibility = View.VISIBLE
}
}
/**
* END
*/
companion object {
private const val TAG = "BaseBusTabFragment"
}
}

View File

@@ -1,109 +1,323 @@
package com.mogo.och.weaknet.fragment
import android.content.Intent
import android.animation.ObjectAnimator
import android.graphics.BitmapFactory
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.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.Group
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.data.config.HdMapBuildConfig
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.CallerAutoPilotControlManager.isCanStartAutopilot
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager.getState
import com.mogo.eagle.core.function.call.autopilot.CallerAutopilotRecordListenerManager
import com.mogo.eagle.core.function.call.devatools.CallerDevaToolsManager.attachAutopilotBeforeLaunchView
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getMapUIController
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getOverlayManager
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils.isB1
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils.isB2
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.ActivityUtils
import com.mogo.eagle.core.utilcode.mogo.view.OnPreventFastClickListener
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.map.MogoMap
import com.mogo.map.overlay.core.Level
import com.mogo.map.overlay.point.Point
import com.mogo.och.common.module.utils.BlinkAnimationUtil
import com.mogo.och.common.module.utils.OCHThreadPoolManager
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.common.module.utils.ResourcesUtils.getColor
import com.mogo.och.common.module.utils.createQRCodeWithPicture
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.och.common.module.wigets.SlidePanelView
import com.mogo.och.data.bean.BusStationBean
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.constant.BusConst
import com.mogo.och.weaknet.presenter.BusPresenter
import com.mogo.och.weaknet.ui.BusStationCommonItem
import com.mogo.och.weaknet.ui.BusSwitchLineActivity
import com.mogo.och.weaknet.ui.taskrunning.RunningTaskManager
import com.mogo.och.weaknet.ui.taskrunned.RunningTaskManager
import com.mogo.och.weaknet.view.BizMapView
import me.jessyan.autosize.utils.AutoSizeUtils
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.Objects
/**
* 网约车小巴界面
* 网约车基础Fragment主要负责布局通用界面处理站点面板和通话面板互斥情况
*
*
* 部分业务放在了此处处理
*
* @author tongchenfei
*/
class ShuttleFragment : BaseShuttleTabFragment<ShuttleFragment?, BusPresenter?>(),
SlidePanelView.OnSlidePanelMoveToEndListener, View.OnClickListener {
class ShuttleFragment : MvpFragment<ShuttleFragment?, BusPresenter?>(), View.OnClickListener {
private var ctvAutopilotStatus: RelativeLayout? = null
private var ctvAutopilotStatusIv: ImageView? = null
private var ctvAutopilotStatusTv: TextView? = null
private var flStationPanelContainer: FrameLayout? = null
private var mapBizView: BizMapView? = null
private val TAG = "BusFragment"
private var autopilotLoadingAnimator: ObjectAnimator? = null
private var mSwitchLine: TextView? = null //切换路线
private var mLineName: MarqueeTextView? = null
private var mTaskTime: TextView? = null
private var groupStationsPanel: Group? = null
private var noDataView: ConstraintLayout? = null
private var startStation: BusStationBean? = null
private var endStation: BusStationBean? = null
private var firstStationItem: BusStationCommonItem? = null
private var secondStationItem: BusStationCommonItem? = null
private var thirdStationItem: BusStationCommonItem? = null
var isAnimateRunning: Boolean = false
override fun getLayoutId(): Int {
return R.layout.shuttle_weak_base_fragment
}
override fun getTagName(): String {
return "BusFragment"
}
override fun initViews() {
mapBizView = findViewById(R.id.mapBizView)
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)
val flSpeed = findViewById<FrameLayout>(R.id.fl_speed)
if (flSpeed != null) {
attachAutopilotBeforeLaunchView(flSpeed.context, flSpeed)
}
updateSwitchMapIcon()
initListener()
setAutopilotBtnStatus(
getState(),
isCanStartAutopilot(false, 0)
)
ctvAutopilotStatus!!.setOnClickListener(object : OnPreventFastClickListener() {
override fun onClickImpl(v: View) {
}
})
}
override fun initViews(savedInstanceState: Bundle?) {
super.initViews(savedInstanceState)
mapBizView!!.onCreate(savedInstanceState)
}
override fun createPresenter(): BusPresenter {
return BusPresenter(this)
}
override fun onResume() {
super.onResume()
mapBizView!!.onResume()
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
EventBus.getDefault().register(this)
return super.onCreateView(inflater, container, savedInstanceState)
}
private fun updateSwitchMapIcon() {
val mapUIController = getMapUIController(MogoMap.DEFAULT)
if (mapUIController != null) {
if (isB2(FunctionBuildConfig.appIdentityMode)) {
mapUIController.changeCurrentIcon(R.raw.m2)
HdMapBuildConfig.currentCarVrIconRes = R.raw.m2
} else if (isB1(FunctionBuildConfig.appIdentityMode)) {
mapUIController.changeCurrentIcon(R.raw.xiaoba)
HdMapBuildConfig.currentCarVrIconRes = R.raw.xiaoba
}
}
}
override fun onSaveInstanceState(outState: Bundle) {
super.onSaveInstanceState(outState)
mapBizView!!.onSaveInstanceState(outState)
}
override fun onLowMemory() {
super.onLowMemory()
mapBizView!!.onLowMemory()
}
override fun onPause() {
super.onPause()
mapBizView!!.onPause()
}
override fun onDestroyView() {
mapBizView!!.onDestroy()
if (mPresenter != null) {
mPresenter!!.onDestroy(this)
}
val overlayManager = getOverlayManager()
if (overlayManager != null) {
overlayManager.removeAllLines()
overlayManager.removeAllPoints()
}
super.onDestroyView()
CallerAutopilotRecordListenerManager.removeListener(TAG)
EventBus.getDefault().unregister(this)
}
override fun initViews() {
super.initViews()
mSwitchLine = findViewById(R.id.switch_line_btn)
mSwitchLine!!.tag = 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)
d(SceneConstant.M_BUS + TAG, "initView: " + getState())
// 初始化的时候设置 UI 按钮状态
showAutopilotBiz()
mSwitchLine!!.setOnClickListener(this)
private fun initListener() {
}
/**
* 改变自动驾驶状态
*
* @param autopilotStatus 0:不可用 1:可用状态 2:自动驾驶中
*/
fun onAutopilotStatusChanged(autopilotStatus: Int, canStartAuto: Boolean) {
UiThreadHandler.post({
changeAutopilotBtnView(
autopilotStatus,
isAnimateRunning,
canStartAuto
)
}, UiThreadHandler.MODE.QUEUE)
}
fun setAutopilotBtnStatus(autopilotStatus: Int, canStartAuto: Boolean) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_DISABLE == autopilotStatus) { //0不可用
ctvAutopilotStatusTv!!.setTextColor(getColor(R.color.bus_autopilot_text_color_disable))
ctvAutopilotStatusTv!!.text =
ResourcesUtils.getString(R.string.bus_loading_autopilot_runnig_tv)
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_disable_autopilot_icon)
ctvAutopilotStatus!!.isClickable = 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!!.text =
ResourcesUtils.getString(R.string.bus_loading_autopilot_runnig_tv)
if (canStartAuto) {
ctvAutopilotStatus!!.isClickable = true
ctvAutopilotStatus!!.setBackgroundResource(R.drawable.common_autopilot_press)
} else {
ctvAutopilotStatusTv!!.setTextColor(getColor(R.color.bus_autopilot_text_color_disable))
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_disable_autopilot_icon)
ctvAutopilotStatus!!.isClickable = 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!!.isClickable = true
ctvAutopilotStatus!!.setBackgroundResource(R.drawable.common_autopilot_in_autopilot)
} else if (IMoGoAutopilotStatusListener.STATUS_PARALLEL_DRIVING
== autopilotStatus
) {
ctvAutopilotStatusTv!!.setText(R.string.bus_pingxing_driver)
ctvAutopilotStatus!!.isClickable = false
ctvAutopilotStatus!!.setBackgroundResource(R.drawable.common_autopilot_pxjs)
}
}
}
fun updateAutopilotStatus(autopilotStatus: Int) {
if (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
== autopilotStatus
) { //2 running
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_right_autopilot_icon)
ctvAutopilotStatusTv!!.setTextColor(getColor(R.color.bus_autopilot_text_color_normal))
ctvAutopilotStatusTv!!.text =
ResourcesUtils.getString(R.string.bus_loading_autopilot_success_tv)
// ctvAutopilotStatus.setSelected(false);
ctvAutopilotStatus!!.isClickable = false
} else {
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_wrong_autopilot_icon)
ctvAutopilotStatusTv!!.setTextColor(getColor(R.color.bus_autopilot_text_color_normal))
ctvAutopilotStatusTv!!.text =
ResourcesUtils.getString(R.string.bus_loading_autopilot_failure_tv)
ctvAutopilotStatus!!.isClickable = false
// ctvAutopilotStatus.setSelected(false);
}
UiThreadHandler.postDelayed({
setAutopilotBtnStatus(
autopilotStatus,
isCanStartAutopilot(false, 0)
)
}, 1000)
}
private fun changeAutopilotBtnView(
autopilotStatus: Int,
isAnimateRunning: Boolean,
canStartAuto: Boolean
) {
if (isAnimateRunning && (IMoGoAutopilotStatusListener.STATUS_AUTOPILOT_RUNNING
!= autopilotStatus)
) {
// 主动开启自动驾驶中不为2为0、1则继续loading
return
}
if (isAnimateRunning) {
stopAnimAndUpdateBtnStatus()
} else {
setAutopilotBtnStatus(autopilotStatus, canStartAuto)
}
}
fun stopAnimAndUpdateBtnStatus() {
stopAutopilotAnimation()
updateAutopilotStatus(getState())
}
/**
* 开启自动驾驶中间动画
*/
fun startAutopilotAnimation() {
isAnimateRunning = true
ctvAutopilotStatusTv!!.text =
ResourcesUtils.getString(R.string.bus_loading_autopilot_tv)
ctvAutopilotStatusTv!!.setTextColor(getColor(R.color.bus_autopilot_text_color_normal))
ctvAutopilotStatus!!.isClickable = true
ctvAutopilotStatusIv!!.setImageResource(R.drawable.bus_loading_autopilot_icon)
if (autopilotLoadingAnimator == null) {
autopilotLoadingAnimator = ObjectAnimator.ofFloat(ctvAutopilotStatusIv!!, "rotation", 0f, 360f)
autopilotLoadingAnimator?.interpolator = LinearInterpolator()
autopilotLoadingAnimator?.repeatCount = -1 //无限循环
autopilotLoadingAnimator?.setDuration(1000) //设置持续时间
}
autopilotLoadingAnimator!!.start() //动画开始
startingAutoApilotCountDown()
}
private fun startingAutoApilotCountDown() {
//10s 若自动驾驶没有开启,则结束动画
UiThreadHandler.postDelayed({
//未启动成功做处理
if (isAnimateRunning) { // 只判断动画是否在进行,根据自动驾驶当前状态去设置自动驾驶状态
stopAutopilotAnimation()
updateAutopilotStatus(getState())
}
}, BusConst.TIMER_START_AUTOPILOT_INTERVAL)
}
/**
* 停止自动驾驶中间动画
*/
protected fun stopAutopilotAnimation() {
if (autopilotLoadingAnimator != null) {
autopilotLoadingAnimator!!.end()
ctvAutopilotStatusIv!!.clearAnimation()
autopilotLoadingAnimator = null
isAnimateRunning = false
}
}
override fun onDestroy() {
super.onDestroy()
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun changeOverview(eventLogout: EventLogout) {
when (eventLogout.messgae) {
@@ -143,317 +357,20 @@ class ShuttleFragment : BaseShuttleTabFragment<ShuttleFragment?, BusPresenter?>(
}
}
override fun onArriveStation() {
mPresenter!!.onAutopilotArriveAtStation(null)
mPresenter!!.arriveStation(null, "点击进站触发进站操作")
}
override fun debugArrivedStation() {
mPresenter!!.onAutopilotArriveAtStation(null)
mPresenter!!.arriveStation(null, "点击debug进站按钮触发进站操作")
}
override fun createPresenter(): BusPresenter {
return BusPresenter(this)
}
private fun hideStationsPanel() {
groupStationsPanel!!.visibility = View.GONE
noDataView!!.visibility = View.VISIBLE
}
private fun showStationsPanel() {
groupStationsPanel!!.visibility = View.VISIBLE
noDataView!!.visibility = View.GONE
}
fun updateLineEmptyUI() {
setArrivedClikable(false)
showOrHideSwitchLineBtn(true)
hideStationsPanel()
hideSlidePanel()
resetStationBlinkAnim()
}
private fun resetStationBlinkAnim() {
BlinkAnimationUtil.clearAnimation(firstStationItem!!.getCircleImageView())
BlinkAnimationUtil.clearAnimation(secondStationItem!!.getCircleImageView())
BlinkAnimationUtil.clearAnimation(thirdStationItem!!.getCircleImageView())
}
fun updateBusTaskStatus(
lineName: String?, lineTime: String,
stationList: List<BusStationBean>?,
arrivingOrArrivedIndex: Int,
isArrived: Boolean
) {
if (activity == null) {
return
}
UiThreadHandler.post(Runnable {
if (stationList == null) {
// 获取小巴数据失败
return@Runnable
}
showStationsPanel()
showOrHideSwitchLineBtn(false)
mLineName?.text = lineName
mTaskTime?.text = ResourcesUtils.getString(R.string.shuttle_line_time_tag,lineTime)
// 渲染小巴路线数据
updateBusStationStatus(stationList, arrivingOrArrivedIndex, isArrived)
}, UiThreadHandler.MODE.QUEUE)
}
private fun updateBusStationStatus(
stationList: List<BusStationBean>,
arrivingOrArrivedIndex: Int,
isArrived: Boolean
) {
startStation = stationList[0]
endStation = stationList[stationList.size - 1]
if (arrivingOrArrivedIndex == stationList.size - 1 && isArrived) {
//切换路线和结束路线按钮切换
showSlidePanel("单程结束")
setOrRemoveMapMaker(
false, BusConst.BUS_END_MAP_MAKER, endStation!!.lat,
endStation!!.lon, R.raw.end_marker
)
} else if (arrivingOrArrivedIndex == 0 && isArrived) {
showSlidePanel("滑动出发")
setOrRemoveMapMaker(
true, BusConst.BUS_START_MAP_MAKER,
startStation!!.lat, startStation!!.lon, R.raw.star_marker
)
setOrRemoveMapMaker(
true, BusConst.BUS_END_MAP_MAKER,
endStation!!.lat, endStation!!.lon, R.raw.end_marker
)
} else {
if (isArrived) {
// 重置滑动按钮文字
showSlidePanel("滑动出发")
}
setOrRemoveMapMaker(
false, BusConst.BUS_START_MAP_MAKER, startStation!!.lat,
startStation!!.lon, R.raw.star_marker
)
setOrRemoveMapMaker(
true, BusConst.BUS_END_MAP_MAKER, endStation!!.lat,
endStation!!.lon, R.raw.end_marker
)
}
if (stationList.size > 2) { //只有两个站点
updateMoreThanTwoStationsUI(stationList, arrivingOrArrivedIndex, isArrived)
} else {
updateTwoStationsUI(stationList, arrivingOrArrivedIndex, isArrived)
}
}
/**
* 有两个以上站点的路线
* @param stationList
* @param arrivingOrArrivedIndex
* @param isArrived
*/
private fun updateMoreThanTwoStationsUI(
stationList: List<BusStationBean>,
arrivingOrArrivedIndex: Int,
isArrived: Boolean
) {
secondStationItem!!.setStationTag("")
secondStationItem!!.showOrHideStationArrowBg(true)
thirdStationItem!!.setStationTag("")
secondStationItem!!.visibility = 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(getColor(R.color.bus_line_station_color_selected))
secondStationItem!!.setStationNameColor(getColor(R.color.bus_arrived_station_name_text_color))
thirdStationItem!!.setStationNameColor(getColor(R.color.bus_arrived_station_name_text_color))
firstStationItem!!.setStationName(stationList[0].name)
secondStationItem!!.setStationName(stationList[1].name)
thirdStationItem!!.setStationName(stationList[2].name)
firstStationItem!!.setStationPointBg(1)
secondStationItem!!.setStationPointBg(2)
thirdStationItem!!.setStationPointBg(2)
firstStationItem!!.setStationArrowBg(2)
secondStationItem!!.setStationArrowBg(2)
} else if (arrivingOrArrivedIndex == stationList.size - 1) {
firstStationItem!!.setStationNameColor(getColor(R.color.bus_station_tag_txt_un_color))
secondStationItem!!.setStationNameColor(getColor(R.color.bus_station_tag_txt_un_color))
thirdStationItem!!.setStationNameColor(getColor(R.color.bus_line_station_color_selected))
firstStationItem!!.setStationName(stationList[arrivingOrArrivedIndex - 2].name)
secondStationItem!!.setStationName(stationList[arrivingOrArrivedIndex - 1].name)
thirdStationItem!!.setStationName(stationList[arrivingOrArrivedIndex].name)
firstStationItem!!.setStationPointBg(0)
secondStationItem!!.setStationPointBg(0)
thirdStationItem!!.setStationPointBg(1)
firstStationItem!!.setStationArrowBg(0)
if (isArrived) {
secondStationItem!!.setStationArrowBg(0)
} else {
secondStationItem!!.setStationArrowBg(1)
}
} else {
firstStationItem!!.setStationNameColor(getColor(R.color.bus_station_tag_txt_un_color))
secondStationItem!!.setStationNameColor(getColor(R.color.bus_line_station_color_selected))
thirdStationItem!!.setStationNameColor(getColor(R.color.bus_arrived_station_name_text_color))
firstStationItem!!.setStationName(stationList[arrivingOrArrivedIndex - 1].name)
secondStationItem!!.setStationName(stationList[arrivingOrArrivedIndex].name)
thirdStationItem!!.setStationName(stationList[arrivingOrArrivedIndex + 1].name)
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 fun updateTwoStationsUI(
stationList: List<BusStationBean>,
arrivingOrArrivedIndex: Int,
isArrived: Boolean
) {
secondStationItem!!.visibility = 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[0].name)
thirdStationItem!!.setStationName(stationList[1].name)
//圆点: 0:灰色 过站 1绿色 到站或者即将到站 2蓝色未到站
if (arrivingOrArrivedIndex == 0 && isArrived) { //到站
firstStationItem!!.setStationNameColor(getColor(R.color.bus_line_station_color_selected))
thirdStationItem!!.setStationNameColor(getColor(R.color.bus_arrived_station_name_text_color))
firstStationItem!!.setStationPointBg(1)
firstStationItem!!.setStationArrowBg(2)
thirdStationItem!!.setStationPointBg(0)
} else {
firstStationItem!!.setStationNameColor(getColor(R.color.bus_station_tag_txt_un_color))
thirdStationItem!!.setStationNameColor(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 fun showOrHideSwitchLineBtn(isShow: Boolean) {
if (isShow) { //显示切换路线
mSwitchLine!!.tag = 0
mSwitchLine!!.text =
ResourcesUtils.getString(R.string.bus_switch_line_btn)
} else { //显示结束路线
mSwitchLine!!.tag = 1
mSwitchLine!!.text =
ResourcesUtils.getString(R.string.bus_close_line_btn)
}
}
fun hideOchBus() {
// tvNotice.setVisibility(View.GONE);
}
override fun stationPanelViewId(): Int {
return R.layout.shuttle_weak_fragment_och
}
override fun restartAutopilot() {
if (!isAnimateRunning) {
mPresenter!!.restartAutopilot()
}
}
override fun slidePanelOnEndListener(): SlidePanelView.OnSlidePanelMoveToEndListener {
return this
}
override fun moveToEnd() {
// 开启自动驾驶到下一站
if (isAnimateRunning) {
stopAutopilotAnimation()
}
mPresenter!!.autoDriveToNextStation()
}
/**
* 设置自动驾驶可用状态
*/
fun onAutopilotEnableChange(isEnable: Boolean) {
if (isEnable) {
showAutopilotBiz()
} else {
hideAutopilotBiz()
}
}
fun clearBusStationsMarkers() {
d(SceneConstant.M_BUS + TAG, "clearBusStationsMarkers()")
if (null != startStation) {
setOrRemoveMapMaker(
false, BusConst.BUS_START_MAP_MAKER, startStation!!.lat,
startStation!!.lon, R.raw.star_marker
)
}
if (null != endStation) {
setOrRemoveMapMaker(
false, BusConst.BUS_END_MAP_MAKER, endStation!!.lat,
endStation!!.lon, R.raw.end_marker
)
}
//清除鹰眼右下角小地图轨迹
d(SceneConstant.M_BUS, "clearBusStationsMarkers --------->")
smallMapView?.clearPolyline()
// d(SceneConstant.M_BUS + TAG, "clearBusStationsMarkers()")
// if (null != startStation) {
// setOrRemoveMapMaker(
// false, BusConst.BUS_START_MAP_MAKER, startStation!!.lat,
// startStation!!.lon, R.raw.star_marker
// )
// }
// if (null != endStation) {
// setOrRemoveMapMaker(
// false, BusConst.BUS_END_MAP_MAKER, endStation!!.lat,
// endStation!!.lon, R.raw.end_marker
// )
// }
}
/**
@@ -502,10 +419,6 @@ class ShuttleFragment : BaseShuttleTabFragment<ShuttleFragment?, BusPresenter?>(
}
}
override fun debugAutoPilotStatus(status: Int) {
mPresenter!!.debugAutoPilotStatus(status)
}
override fun onClick(v: View) {
if (v.id == R.id.switch_line_btn) { //切换路线条件: 自动驾驶过程中点击则toast提示自动驾驶中不可切换路线
//本次行程未结束不支持切换路线。点击则toast提示当前行程未完成不可切换路线
@@ -515,29 +428,13 @@ class ShuttleFragment : BaseShuttleTabFragment<ShuttleFragment?, BusPresenter?>(
ToastUtils.showLong(ResourcesUtils.getString(R.string.bus_switch_line_btn_warning1))
return
}
if (mSwitchLine!!.tag as Int == 0) { //切换路线
val intent = Intent(context, BusSwitchLineActivity::class.java)
ActivityUtils.startActivity(intent)
} else { //结束任务
val builder = OCHCommitDialog.Builder()
val 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(AbsMogoApplication.getApp())
closeLineConfirmDialog!!.setClickListener(object : OCHCommitDialog.ClickListener {
override fun confirm() {
mPresenter!!.abortTask()
}
override fun cancel() {
closeLineConfirmDialog.dismiss()
}
})
closeLineConfirmDialog.show()
}
}
}
/**
* END
*/
companion object {
private const val TAG = "BaseBusTabFragment"
}
}

View File

@@ -46,9 +46,9 @@ import com.mogo.och.weaknet.database.transform.FRetryWithTime11
import com.mogo.och.weaknet.database.transform.TransformTask
import com.mogo.och.weaknet.database.transform.transform4DataBase
import com.mogo.och.weaknet.net.OrderServiceManager
import com.mogo.och.weaknet.ui.BusSwitchLineActivity
import io.reactivex.Observer
import io.reactivex.disposables.Disposable
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.atomic.AtomicBoolean
/**
@@ -58,7 +58,9 @@ import java.util.concurrent.atomic.AtomicBoolean
@SuppressLint("StaticFieldLeak")
object BusLineModel {
private var mContext: Context? = null
private var mBusLinesCallback: IBusLinesCallback? = null
private val mBusLinesCallbackMap: MutableMap<String, IBusLinesCallback> = ConcurrentHashMap()
private const val TAG = "BusLineModel"
private const val LoopCarInfo = "LoopCarInfo"
@@ -68,14 +70,13 @@ object BusLineModel {
// 展示上一次刷新时间
const val executableChangeTime = "executablechangetime"
const val LASTCOMMITLINEID = "lastcommitlineid"
var currentTask: TaskDataBean?=null
// 当前任务的站点列表
var stationList:MutableList<BusStationBean>? = mutableListOf<BusStationBean>()
@JvmStatic
val busRoutesResult: BusRoutesResult = BusRoutesResult()
private val isRequesting = AtomicBoolean(false)
private val loopQueryInfo = object :Runnable{
@@ -100,13 +101,18 @@ object BusLineModel {
fun release() {
mContext = null
EventModel.release()
mBusLinesCallback = null
mBusLinesCallbackMap.clear()
BizLoopManager.removeCallback(loopQueryInfo)
}
@JvmStatic
fun setBusLinesCallback(callback: IBusLinesCallback?) {
mBusLinesCallback = callback
fun setBusLinesCallback(tag:String,callback: IBusLinesCallback?) {
if (tag == null || "" == tag) return
if (callback == null) {
mBusLinesCallbackMap.remove(tag)
return
}
mBusLinesCallbackMap[tag] = callback
}
fun refreshTask() {
@@ -138,7 +144,9 @@ object BusLineModel {
SharedPrefsMgr.getInstance().putLong(executableChangeTime, currentTimeStamp)
val sameDay = DateTimeUtil.isSameDay(currentTimeStamp, lastUpdateTime)
mBusLinesCallback?.onRefreshSuccess(currentTimeStamp)
mBusLinesCallbackMap.forEach {
it.value.onRefreshSuccess(currentTimeStamp)
}
if(isBackground){
if (currentRequest == lastChangeMd5 && sameDay) {
return
@@ -202,7 +210,9 @@ object BusLineModel {
}
override fun onNext(data: List<BusQueryLinesResponse.Result>) {
mBusLinesCallback?.onBusLinesChange(data)
mBusLinesCallbackMap.forEach {
it.value.onBusLinesChange(data)
}
}
})
@@ -214,7 +224,7 @@ object BusLineModel {
* @param position 位置
*/
@JvmStatic
fun queryBusLineTasksById(lineId: Long, position: Int, autoRefresh: Boolean) {
fun queryBusLineTasksById(lineId: Long) {
TaskRepository.queryCanUserTask(lineId)
?.transform4DataBase(TransformTask())
?.subscribe(object : Observer<List<BusQueryLineTaskResponse.Result>> {
@@ -231,8 +241,8 @@ object BusLineModel {
}
override fun onNext(data: List<BusQueryLineTaskResponse.Result>) {
if (mBusLinesCallback != null) {
mBusLinesCallback!!.onBusLineTasks(data, position, autoRefresh)
mBusLinesCallbackMap.forEach {
it.value.onBusLineTasks(data)
}
}
@@ -251,14 +261,18 @@ object BusLineModel {
object : TaskRepository.TaskStatusCallback {
override fun startSuccess() {
SharedPrefsMgr.getInstance()
.putLong(BusSwitchLineActivity.LASTCOMMITLINEID, line.lineId)
.putLong(LASTCOMMITLINEID, line.lineId)
EventRepository.saveEventTaskStart(task.id,line.lineId,task.taskStartTime,line.name)
mBusLinesCallback?.onChangeLineIdSuccess()
mBusLinesCallbackMap.forEach {
it.value.onChangeLineIdSuccess()
}
}
override fun startFail(msg: String) {
ToastUtils.showShort("选择任务失败:$msg")
mBusLinesCallback?.onChangeLineIdFail()
mBusLinesCallbackMap.forEach {
it.value.onChangeLineIdFail()
}
}
})
@@ -306,6 +320,9 @@ object BusLineModel {
val contraiInfoTemp = ContraiRepository.queryAutopilotInfoByLineid(it)
ContrailDataBean.save2Common(contraiInfoTemp)
}
mBusLinesCallbackMap.forEach { callback->
callback.value.onRunningTask()
}
}
}
@@ -324,7 +341,7 @@ object BusLineModel {
it.status = TaskDataBean.used
}
TaskRepository.addOrUpdate(*tempList.toTypedArray())
OrderModel.queryBusRoutes()
loadStartedTaskAndDefaultInfo()
OchChainLogManager.writeChainLogDb("加载任务", "异常情况:多个正在进行的任务 task:${runningTaskInfo} event:${queryLastData.taskId}有一个和event表对应使用相同的一个 另一个置为已使用")
return
}
@@ -342,6 +359,11 @@ object BusLineModel {
mContext?.let { contextit ->
OrderServiceManager.queryBusRoutes(contextit,object :OchCommonServiceCallback<BusRoutesResponse>{
override fun onSuccess(response: BusRoutesResponse?) {
if(response?.data == null){
mBusLinesCallbackMap.forEach { callback->
callback.value.onNoRunningTask()
}
}
response?.data?.let {
if (!it.sites.isNullOrEmpty()&&it.sites.size>1) {
val queryTaskById = TaskRepository.queryTaskById(it.taskId.toLong())
@@ -399,12 +421,15 @@ object BusLineModel {
fun leaveStation(){
//开始站点: leaving false->true
LineManager.getStartStation {
it.drivingStatus = TaskSiteDataBean.drivingStatusCurrent
it.isLeaving = true
if (currentTask != null && currentTask!!.taskId != null) {
currentTask?.let { task ->
if (task.taskId!=null&&task.lineId!=null) {
it.drivingStatus = TaskSiteDataBean.drivingStatusCurrent
it.isLeaving = true
TaskSiteRepository.updateLeave(task.taskId!!, it.siteId.toLong(), true)
mBusLinesCallbackMap.forEach {map->
map.value.onLeaveStaionSuccess()
}
OchChainLogManager.writeChainLogDb("滑动出发", "task:${currentTask}__taskId:${currentTask?.taskId}")
// 设置滑动出发任务
LineManager.lineInfos?.lineName?.let { lineName->
@@ -420,6 +445,9 @@ object BusLineModel {
}
}
} else {
mBusLinesCallbackMap.forEach {map->
map.value.onLeaveStaionFail()
}
OchChainLogManager.writeChainLog(
"滑动出发_数据更新_error",
"task:${currentTask}__taskId:${currentTask?.taskId}"
@@ -465,6 +493,9 @@ object BusLineModel {
stationList?.let {
startStationIndex+=1
mBusLinesCallbackMap.forEach {
it.value.onArriveStationSuccess()
}
val startStation = LineManager.endStation
if(startStationIndex+1< it.size){
val endStation = it[startStationIndex+1]
@@ -484,7 +515,7 @@ object BusLineModel {
fun getTaskTime():String {
return DateTimeUtil.formatLongToString(
currentTask!!.taskStartTime!!,
currentTask?.taskStartTime?:System.currentTimeMillis(),
DateTimeUtil.HH_mm
)
}
@@ -506,6 +537,9 @@ object BusLineModel {
LineManager.setStartAndEndStation(null,null)
stationList = mutableListOf()
startStationIndex = 0
mBusLinesCallbackMap.forEach {
it.value.onCompleteTask()
}
}
fun startTaskMessage():Boolean {
@@ -533,24 +567,4 @@ object BusLineModel {
}
}
fun sendTaskDetailsToClients() {
if (LineManager.lineInfos==null||currentTask==null||stationList.isNullOrEmpty()) {
val data = BusTransferData(if (LoginStatusManager.isLogin()) 1 else 0, null)
val msg = TaskDetailsMsg(GsonUtils.toJson(data), BusinessType.shuttle)
d(M_BUS + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg))
LanSocketManager.sendMsgToClient(msg)
}else{
busRoutesResult.setSite(stationList)
busRoutesResult.lineId = LineManager.lineInfos!!.lineId.toInt()
busRoutesResult.name = LineManager.lineInfos!!.lineName
busRoutesResult.taskId = currentTask!!.taskId!!.toInt()
busRoutesResult.taskTime = currentTask!!.taskStartTime!!
val data = BusTransferData(if (LoginStatusManager.isLogin()) 1 else 0, busRoutesResult)
val msg = TaskDetailsMsg(GsonUtils.toJson(data), BusinessType.shuttle)
d(M_BUS + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg))
LanSocketManager.sendMsgToClient(msg)
}
}
}

View File

@@ -140,7 +140,7 @@ object OrderModel {
// 乘客屏请求线路信息
private val taskDetailsMsgListener = object : ILanMessageListener<TaskDetailsMsg> {
override fun targetLan(): Class<TaskDetailsMsg> = TaskDetailsMsg::class.java
override fun onLanMsgReceived(taskDetailsMsg: TaskDetailsMsg?) = BusLineModel.sendTaskDetailsToClients()
override fun onLanMsgReceived(taskDetailsMsg: TaskDetailsMsg?) = ThirdDeviceData.sendTaskDetailsToClients()
}
@JvmStatic
@@ -211,7 +211,6 @@ object OrderModel {
BusLineModel.loadStartedTaskAndDefaultInfo()
if(BusLineModel.stationList.isNullOrEmpty()){
d(M_BUS + TAG, "获取到小巴路线数据:空 ")
mADASStatusCallback?.updateEmptyUi()
LineManager.setLineInfo(null);
updateBusStatus()
clearAutopilotControlParameters()
@@ -288,9 +287,12 @@ object OrderModel {
OCHThreadPoolManager.getsInstance().execute {
d(M_BUS + TAG, "结束当前路线abortTask")
endOrAbortTaskSuccess()
clearBusStationDatas()
queryBusRoutes()
isGoingToNextStation = false
ThirdDeviceData.endTask()
BusLineModel.endTask()
ThirdDeviceData.sendTaskDetailsToClients()
mADASStatusCallback?.clearBusStationsMarkers()
removeTipRunnables()
ShuttleVoiceManager.endOrderBus()
// 取消自驾
@@ -299,51 +301,6 @@ object OrderModel {
}
}
/**
* 中断或者正常结束任务后的处理
*/
private fun endOrAbortTaskSuccess() {
isGoingToNextStation = false
LineManager.lineInfos?.let {
LedScreenManager.sendTripInfo2Led(
LedScreenManager.END_TRIP,
it.lineName,
"",
"",
false
)
}
BusLineModel.endTask()
BusLineModel.sendTaskDetailsToClients()
}
/**
* 离站上报成功后渲染站点
* 服务端返回的OchBusRoutesResult逻辑 离开站为当前站, 到达下一站后才会将下一站置为当前站,
* 车机端展示是离开当前站,下一站设置为当前站, 所以服务端数据回来要做处理,不能直接渲染
*/
private fun leaveStationSuccess() {
onStartAutopilot()
LineManager.getStations { start, end ->
leaveTTSTips(end.name, end.nameKr)
//给bus外屏发送
LedScreenManager.sendTripInfo2Led(
LedScreenManager.LEAVE_STATION,
LineManager.lineInfos!!.lineName,
start.name,
end.name,
BusLineModel.isLastStation()==true
)
}
BusLineModel.leaveStation()
updateBusStatus()
}
private fun onStartAutopilot() {
//开启自动驾驶 2.10.0: 如果自动驾驶状态下开启, 非自动驾驶状态下不开启,需手动点击自动驾驶按钮开启
isGoingToNextStation = true
@@ -361,8 +318,6 @@ object OrderModel {
* @param isRestart
*/
private fun startAutopilot(isRestart: Boolean) {
val temp = initAutopilotControlParameters()
/**
* 存在Session
*/
@@ -436,57 +391,6 @@ object OrderModel {
mADASStatusCallback?.startOpenAutopilot()
}
/**
* 到站后重置站点状态
*/
private fun arriveSiteStation(changeInfo: String) {
OchChainLogManager.writeChainLog("触发进站", changeInfo)
if (LineManager.endStation==null) {
e(M_BUS + TAG, "未设置终点坐标")
OchChainLogManager.writeChainLog("shuttle弱网","围栏距离判断 未设置终点坐标")
return
}
isArrivedStation = true
isGoingToNextStation = false
arriveStationSuccess()
}
private fun arriveStationSuccess() {
LineManager.getStations { start, end ->
ShuttleVoiceManager.arrivedStationBus(end.name, end.nameKr)
//给bus外屏发送
LedScreenManager.sendTripInfo2Led(
LedScreenManager.ARRIVE_STATION,
LineManager.lineInfos!!.lineName,
start.name,
end.name,
BusLineModel.isLastStation()==true
)
}
BusLineModel.arrivedStation()
updateBusStatus()
}
/**
* 离站上报
*/
private fun leaveStation() {
if (LineManager.endStation==null) {
OchChainLogManager.writeChainLog("滑动出发", "未设置终点坐标")
return
}
isArrivedStation = false
leaveStationSuccess()
}
//车站10s后播报
private fun leaveTTSTips(nextStation: String?, nextStationKr: String?) {
UiThreadHandler.postDelayed({ //延迟10s播报
ShuttleVoiceManager.leaveStationBus(nextStation, nextStationKr)
}, BusConst.DELAY_10S)
}
@JvmStatic
fun startBeautificationMode() {
FunctionBuildConfig.isIgnoreConditionsDrawAutopilotTrajectoryData = true
@@ -518,7 +422,18 @@ object OrderModel {
abortTask()
return
}
leaveStation()
if (LineManager.endStation==null) {
OchChainLogManager.writeChainLog("滑动出发", "未设置终点坐标")
return
}
isArrivedStation = false
onStartAutopilot()
ThirdDeviceData.leaveStation()
BusLineModel.leaveStation()
updateBusStatus()
}
/**
@@ -548,14 +463,13 @@ object OrderModel {
LineManager.getStartStation {
if (it.isLeaving) {
mADASStatusCallback?.hideSlidePanel()
isGoingToNextStation = true
}else{
isGoingToNextStation = false
}
}
BusLineModel.sendTaskDetailsToClients()
ThirdDeviceData.sendTaskDetailsToClients()
//更新bus路线面板
updateBusTaskStatus()
@@ -621,13 +535,6 @@ object OrderModel {
firstStartAutopilot = 0
}
@JvmStatic
fun clearBusStationDatas() {
mADASStatusCallback?.clearBusStationsMarkers()
}
/**
* 在踩刹车、控制方向盘等操作后,会停止自动驾驶,重启自动驾驶的话相当于重新设置自动驾驶目的地
*/
@@ -673,7 +580,13 @@ object OrderModel {
if (isArrivedStation) return
arriveSiteStation(type)
OchChainLogManager.writeChainLog("触发进站", type)
isArrivedStation = true
isGoingToNextStation = false
ThirdDeviceData.arriveStation()
BusLineModel.arrivedStation()
updateBusStatus()
}
// 登出

View File

@@ -0,0 +1,87 @@
package com.mogo.och.weaknet.model
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.common.module.manager.autopilot.line.LineManager
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.TaskDetailsMsg
import com.mogo.och.data.bean.BusRoutesResult
import com.mogo.och.data.bean.BusTransferData
import com.mogo.och.weaknet.constant.BusConst
import com.mogo.och.weaknet.util.ShuttleVoiceManager
object ThirdDeviceData {
const val TAG = "ThirdDeviceData"
@JvmStatic
val busRoutesResult: BusRoutesResult = BusRoutesResult()
fun leaveStation(){
LineManager.getStations { start, end ->
UiThreadHandler.postDelayed({ //延迟10s播报
ShuttleVoiceManager.leaveStationBus(end.name, end.nameKr)
}, BusConst.DELAY_10S)
//给bus外屏发送
LedScreenManager.sendTripInfo2Led(
LedScreenManager.LEAVE_STATION,
LineManager.lineInfos!!.lineName,
start.name,
end.name,
BusLineModel.isLastStation()==true
)
}
}
fun arriveStation(){
LineManager.getStations { start, end ->
ShuttleVoiceManager.arrivedStationBus(end.name, end.nameKr)
//给bus外屏发送
LedScreenManager.sendTripInfo2Led(
LedScreenManager.ARRIVE_STATION,
LineManager.lineInfos!!.lineName,
start.name,
end.name,
BusLineModel.isLastStation()==true
)
}
}
fun endTask(){
LineManager.lineInfos?.let {
LedScreenManager.sendTripInfo2Led(
LedScreenManager.END_TRIP,
it.lineName,
"",
"",
false
)
}
}
fun sendTaskDetailsToClients() {
if (LineManager.lineInfos==null|| BusLineModel.currentTask ==null|| BusLineModel.stationList.isNullOrEmpty()) {
val data = BusTransferData(if (LoginStatusManager.isLogin()) 1 else 0, null)
val msg = TaskDetailsMsg(GsonUtils.toJson(data), BusinessType.shuttle)
d(M_BUS + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg))
LanSocketManager.sendMsgToClient(msg)
}else{
busRoutesResult.setSite(BusLineModel.stationList)
busRoutesResult.lineId = LineManager.lineInfos!!.lineId.toInt()
busRoutesResult.name = LineManager.lineInfos!!.lineName
busRoutesResult.taskId = BusLineModel.currentTask!!.taskId!!.toInt()
busRoutesResult.taskTime = BusLineModel.currentTask!!.taskStartTime!!
val data = BusTransferData(if (LoginStatusManager.isLogin()) 1 else 0, busRoutesResult)
val msg = TaskDetailsMsg(GsonUtils.toJson(data), BusinessType.shuttle)
d(M_BUS + TAG, "sendTaskDetailsToClients = " + GsonUtils.toJson(msg))
LanSocketManager.sendMsgToClient(msg)
}
}
}

View File

@@ -1,124 +0,0 @@
package com.mogo.och.weaknet.presenter
import androidx.lifecycle.LifecycleOwner
import com.mogo.commons.mvp.Presenter
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.weaknet.callback.IBusLinesCallback
import com.mogo.och.weaknet.model.BusLineModel
import com.mogo.och.weaknet.model.BusLineModel.executableChangeTime
import com.mogo.och.weaknet.model.BusLineModel.queryBusLineTasksById
import com.mogo.och.weaknet.model.BusLineModel.setBusLinesCallback
import com.mogo.och.weaknet.model.OrderModel
import com.mogo.och.weaknet.model.OrderModel.clearBusStationDatas
import com.mogo.och.weaknet.ui.BusSwitchLineView
import io.reactivex.Observable
import io.reactivex.disposables.Disposable
import java.util.concurrent.TimeUnit
/**
* @author: wangmingjun
* @date: 2022/2/9
*/
class BusLinePresenter(view: BusSwitchLineView?) : Presenter<BusSwitchLineView?>(view),
IBusLinesCallback {
private var subscribe: Disposable? = null
init {
BusLineModel.init()
OrderModel.init()
}
override fun onCreate(owner: LifecycleOwner) {
super.onCreate(owner)
initListener()
initData()
}
private fun initData() {
BusLineModel.refreshTask()
}
private fun initListener() {
setBusLinesCallback(this)
}
override fun onBusLinesChange(data: List<BusQueryLinesResponse.Result>) {
mView?.onBusLinesChange(data)
}
override fun onChangeLineIdSuccess() {
clearBusStationDatas()
UiThreadHandler.post({
mView?.startTaskState(true)
mView?.onChangeLineIdSuccess()
}, UiThreadHandler.MODE.QUEUE)
}
fun queryBusLines() {
BusLineModel.queryBusLines()
}
fun queryBusLineTasks(lineId: Long, position: Int, close: Boolean) {
if (subscribe != null && !subscribe!!.isDisposed) {
subscribe!!.dispose()
}
if (close) {
return
}
queryBusLineTasksById(lineId, position, false)
subscribe = Observable.interval(3, TimeUnit.MINUTES).subscribe { aLong: Long? ->
queryBusLineTasksById(lineId, position, true)
}
}
fun commitSwitchLineId(taskId: BusQueryLineTaskResponse.Result, lineId: BusQueryLinesResponse.Result) {
BusLineModel.commitSwitchLineId(taskId, lineId)
}
fun removeListener() {
setBusLinesCallback(null)
}
fun queryBusRoutes() {
OrderModel.queryBusRoutes()
}
override fun onDestroy(owner: LifecycleOwner) {
super.onDestroy(owner)
if (subscribe != null && !subscribe!!.isDisposed) {
subscribe!!.dispose()
}
}
override fun onBusLineTasks(
o: List<BusQueryLineTaskResponse.Result>,
position: Int,
autoRefresh: Boolean
) {
mView?.onBusLineTasks(o, position, autoRefresh)
}
override fun onRefreshSuccess(currentTimeStamp: Long) {
mView?.refreshDate(DateTimeUtil.formatLongToString(currentTimeStamp,DateTimeUtil.yyyy_MM_dd_HH_mm_ss))
}
override fun onChangeLineIdFail() {
mView?.startTaskState(false)
}
fun refreshTask() {
BusLineModel.refreshTask()
}
fun setRefreshTime() {
val lastUpdateTime = SharedPrefsMgr.getInstance().getLong(executableChangeTime, -1)
if(lastUpdateTime>0){
onRefreshSuccess(lastUpdateTime)
}
}
}

View File

@@ -99,21 +99,11 @@ class BusPresenter(view: ShuttleFragment?) : Presenter<ShuttleFragment?>(view),
arrivingOrArrivedIndex - 1
}
d(SceneConstant.M_BUS + "BusOrderModel =", " mCurrentStation =$mCurrentStation")
mView?.updateBusTaskStatus(
lineName, lineTime,
stationList, arrivingOrArrivedIndex, isArrived
)
}
override fun updateEmptyUi() {
UiThreadHandler.post({
if (mView != null) {
mView!!.updateLineEmptyUI()
}
}, UiThreadHandler.MODE.QUEUE)
}
override fun clearBusStationsMarkers() {
// TODO: 清理或展示地图
UiThreadHandler.post({
if (mView != null) {
mView!!.clearBusStationsMarkers()
@@ -121,13 +111,6 @@ class BusPresenter(view: ShuttleFragment?) : Presenter<ShuttleFragment?>(view),
}, UiThreadHandler.MODE.QUEUE)
}
override fun hideSlidePanel() {
if (mView != null) {
mView!!.hideSlidePanel()
mView!!.setArrivedClikable(true)
}
}
override fun onAutopilotArriveAtStation(arrivedStation: ArrivedStation?) {
e(SceneConstant.M_BUS + TAG, "行程日志-onAutopilotArriveAtStation arrive")
arriveStation(arrivedStation, "底盘触发进站")
@@ -165,9 +148,7 @@ class BusPresenter(view: ShuttleFragment?) : Presenter<ShuttleFragment?>(view),
}
else -> UiThreadHandler.post({
if (mView != null) {
mView!!.onAutopilotEnableChange(false)
}
}, UiThreadHandler.MODE.QUEUE)
}
}
@@ -214,14 +195,11 @@ class BusPresenter(view: ShuttleFragment?) : Presenter<ShuttleFragment?>(view),
override fun onStatusChange(currentStatus: LoginStatusEnum) {
d(SceneConstant.M_BUS + TAG, " loginStatus =" + isLogin())
if (isLogin()) {
OrderModel.queryBusRoutes()
//OrderModel.queryBusRoutes()
} else {
BusTrajectoryManager.getInstance().stopTrajReqLoop()
BusTrajectoryManager.getInstance().stopTrajReqLoop()
clearBusStationsMarkers()
if (mView != null) {
mView!!.hideSlidePanel()
}
OrderModel.closeBeautificationMode()
}
}

View File

@@ -1,282 +0,0 @@
package com.mogo.och.weaknet.ui
import android.animation.ObjectAnimator
import android.animation.ValueAnimator
import android.content.res.ColorStateList
import android.graphics.Color
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.LinearLayout
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.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.view.SpacesItemDecoration
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.weaknet.presenter.BusLinePresenter
import com.mogo.och.weaknet.ui.adapter.OpenItemAnimator
import com.mogo.och.weaknet.ui.adapter.SwitchLineAdapter
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.aciv_refresh_task
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.actv_last_refresh_date
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.pb_start_task
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.tv_start_task
/**
* @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: LinearLayout
private lateinit var mAdapter: SwitchLineAdapter
private lateinit var linearLayoutManager:LinearLayoutManager
private val mData: MutableList<BusQueryLinesResponse.Result> = ArrayList()
private var animator:ObjectAnimator?=null
override fun getLayoutId(): Int {
return R.layout.shuttle_weak_switch_line
}
override fun createPresenter(): BusLinePresenter {
return BusLinePresenter(this)
}
override fun initViews() {
initWH()
initView()
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
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(position: Int, close: Boolean) {
mPresenter?.queryBusLineTasks(mData[position].lineId, position, close)
}
})
aciv_refresh_task.onClick {
mPresenter?.refreshTask()
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()
}
pb_start_task.progressTintList = ColorStateList.valueOf(Color.WHITE)
}
/**
* 设置布局宽高
*/
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()
mPresenter?.setRefreshTime()
}
/**
* 查询返回绑定路线集合
* @param data
*/
override fun onBusLinesChange(data: MutableList<BusQueryLinesResponse.Result>?) {
if (data.isNullOrEmpty()) {
showNoData(true)
return
}
val lastCommitLineid = SharedPrefsMgr.getInstance().getLong(LASTCOMMITLINEID, -1)
if (data.size > 0) {
showNoData(false)
mData.clear()
mData.addAll(data)
mAdapter.notifyDataSetChanged()
if(lastCommitLineid>0){
mData.forEachIndexed { index, line ->
if(line.lineId==lastCommitLineid){
line.open = true
mPresenter?.queryBusLineTasks(line.lineId,index,false)
return
}
}
}
} 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()
}
override fun onBusLineTasks(lineTaskInfo: List<BusQueryLineTaskResponse.Result>, position: Int, autoRefresh:Boolean) {
val result = mData[position]
if (result.taskList == null) {
result.taskList = ArrayList()
}
if (lineTaskInfo == null) {
result.haveTask = true
// 打开操作
mAdapter.notifyItemChanged(position)
} else {
if ( lineTaskInfo.isEmpty()) {
result.haveTask = true
}
if (lineTaskInfo.size != result.taskList.size) { // 不相等有变动 重新赋值
result.taskList.clear()
result.taskList.addAll(lineTaskInfo)
if(autoRefresh) {
mAdapter.checkTask = null
mAdapter.checkLine = null
lineTaskInfo.forEach {lineTaskInfoInner->
mAdapter.checkTask?.let {
if (lineTaskInfoInner.id == it.id) {
mAdapter.checkTask = lineTaskInfoInner
mAdapter.checkLine = result
}
}
}
}
// 打开操作
mAdapter.notifyItemChanged(position)
linearLayoutManager.stackFromEnd = (position==mData.size-1||position==mData.size-2)&&mData.size>6
mLinesListView.smoothScrollToPosition(position)
}else if(lineTaskInfo.isEmpty()){
mAdapter.notifyItemChanged(position)
}
}
}
override fun refreshDate(formatLongToString: String?) {
UiThreadHandler.post({
formatLongToString?.let {
actv_last_refresh_date.text = ResourcesUtils.getString(R.string.bus_refresh_time,it)
animator?.cancel()
}
},UiThreadHandler.MODE.QUEUE)
}
/**
* 有无数据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(mAdapter.checkLine!=null&&mAdapter.checkTask!=null){
mPresenter?.let {
it.commitSwitchLineId(mAdapter.checkTask!!,mAdapter.checkLine!!)
startTaskLoading()
}
}else{
ToastUtils.showLong("请选择任务")
}
}
}
override fun startTaskState(success: Boolean) {
pb_start_task.visibility = View.GONE
if(success){
tv_start_task.text = "创建成功"
}else{
tv_start_task.text = "创建失败"
UiThreadHandler.postDelayed({
tv_start_task.text = "确定"
},1_000)
}
}
fun startTaskLoading(){
pb_start_task.visibility = View.VISIBLE
tv_start_task.text = "创建中"
}
override fun onDestroy() {
mPresenter!!.removeListener()
super.onDestroy()
}
}

View File

@@ -1,26 +0,0 @@
package com.mogo.och.weaknet.ui;
import com.mogo.commons.mvp.IView;
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse;
import com.mogo.och.weaknet.bean.BusQueryLinesResponse;
import org.jetbrains.annotations.Nullable;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2022/2/10
*/
public interface BusSwitchLineView extends IView {
void onBusLinesChange(List<BusQueryLinesResponse.Result> data);
void onChangeLineIdSuccess();
void onBusLineTasks(List<BusQueryLineTaskResponse.Result> o, int position,boolean autoRefresh);
void refreshDate(@Nullable String formatLongToString);
void startTaskState(boolean b);
}

View File

@@ -1,643 +0,0 @@
package com.mogo.och.weaknet.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);
}
}

View File

@@ -1,172 +0,0 @@
package com.mogo.och.weaknet.ui.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.weaknet.ui.adapter.SwitchLineAdapter.SwitchLineViewHolder
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import kotlin.text.StringBuilder
/**
* 路线列表adapter
*/
class SwitchLineAdapter(
private val mContext: Context,
private val mData: List<BusQueryLinesResponse.Result>
) : RecyclerView.Adapter<SwitchLineViewHolder>() {
companion object{
const val TAG = "SwitchLineAdapter"
}
// RecyclerView设置点击事件
private var mItemClickListener: LineItemClickListener? = null
var checkLine:BusQueryLinesResponse.Result? = null
var checkTask: BusQueryLineTaskResponse.Result? = null
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): SwitchLineViewHolder {
val view = LayoutInflater.from(mContext).inflate(
R.layout.shuttle_weak_switch_line_list_item, parent, false
)
return SwitchLineViewHolder(view)
}
override fun onBindViewHolder(holder: SwitchLineViewHolder, position: Int) {
val currentPosition = holder.bindingAdapterPosition
val line = mData[currentPosition]
holder.lineName.text = line.name
val string = mContext.getString(R.string.bus_line_goto_end, line.endSiteName)
holder.lineEndName.text = string
holder.rvLineTask.layoutManager = GridLayoutManager(mContext, 3)
val switchLineTaskAdapter = SwitchLineTaskAdapter(
mContext,
if(checkTask==null) -1 else checkTask!!.id,
line.taskList,
object : SwitchLineTaskAdapter.TaskItemClickListener {
override fun onItemClick(position: Int,isCheck:Boolean) {
try {
if(isCheck) {
checkLine = line
checkTask = line.taskList[position]
}else{
checkLine=null
checkTask=null
}
}catch (e:Exception){
e.printStackTrace()
checkLine=null
checkTask=null
}
}
})
holder.rvLineTask.adapter = switchLineTaskAdapter
holder.rvLineTask.isFocusableInTouchMode = false
holder.actvShowMore.visibility = View.VISIBLE
if(line.open){
if(line.taskList==null||line.taskList.isEmpty()){
holder.actvShowMore.text = mContext.getString(R.string.bus_switch_line_no_task)
holder.actvShowMore.setTextColor(ContextCompat.getColor(mContext,R.color.bus_color_4dffffff))
holder.vLineTask.visibility = View.GONE
holder.rvLineTask.visibility = View.GONE
holder.selectIv.visibility = View.INVISIBLE
holder.itemView.setBackgroundResource(R.drawable.bus_shape_select_line_item_bg_normal)
}else {
holder.actvShowMore.text = mContext.getString(R.string.bus_switch_line_select_task)
holder.actvShowMore.setTextColor(ContextCompat.getColor(mContext,android.R.color.white))
holder.vLineTask.visibility = View.VISIBLE
holder.rvLineTask.visibility = View.VISIBLE
holder.selectIv.visibility = View.VISIBLE
holder.itemView.setBackgroundResource(R.drawable.bus_shape_select_line_item_bg_selected)
holder.selectIv.apply {
pivotX = 9.5f
pivotY = 17f
rotation = 90f
}
}
}else{
if(line.haveTask){
holder.actvShowMore.text = mContext.getString(R.string.bus_switch_line_no_task)
holder.actvShowMore.setTextColor(ContextCompat.getColor(mContext,R.color.bus_color_4dffffff))
holder.vLineTask.visibility = View.GONE
holder.rvLineTask.visibility = View.GONE
holder.selectIv.visibility = View.INVISIBLE
holder.itemView.setBackgroundResource(R.drawable.bus_shape_select_line_item_bg_normal)
}else {
holder.actvShowMore.text = mContext.getString(R.string.bus_switch_line_select_task)
holder.actvShowMore.setTextColor(ContextCompat.getColor(mContext,android.R.color.white))
holder.vLineTask.visibility = View.GONE
holder.rvLineTask.visibility = View.GONE
holder.selectIv.visibility = View.VISIBLE
holder.itemView.setBackgroundResource(R.drawable.bus_shape_select_line_item_bg_normal)
holder.selectIv.apply {
pivotX = 9.5f
pivotY = 17f
rotation = 0f
}
}
}
//设置item点击事件
holder.itemView.setOnClickListener {
if(holder.actvShowMore.text==mContext.getString(R.string.bus_switch_line_no_task)){
return@setOnClickListener
}
mData.forEachIndexed { index, result ->
if(result.open){
result.open = false;
notifyItemChanged(index)
if(result.taskList!=null) {
result.taskList.clear()
}
if(index==currentPosition){// 点击当前已经打开的item 去关闭定时网络请求
mItemClickListener?.onItemClick(currentPosition,true)
return@setOnClickListener
}
}
}
mItemClickListener?.onItemClick(currentPosition,false)
line.open = holder.rvLineTask.visibility == View.GONE
}
}
override fun getItemCount(): Int {
return mData.size
}
fun setOnLineItemClickListener(itemClickListener: LineItemClickListener?) {
mItemClickListener = itemClickListener
}
class SwitchLineViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val selectIv: ImageView
val lineName: AppCompatTextView//线路名称
val lineEndName: AppCompatTextView //终点
val actvShowMore: AppCompatTextView //选择时间
val rvLineTask: RecyclerView// 排班时间
val vLineTask: View// 白色分割线
init {
selectIv = itemView.findViewById(R.id.switch_line_item_select_iv)
lineName = itemView.findViewById(R.id.switch_line_name)
lineEndName = itemView.findViewById(R.id.switch_line_end_station)
rvLineTask = itemView.findViewById(R.id.rv_line_task_list)
vLineTask = itemView.findViewById(R.id.v_line_task)
actvShowMore = itemView.findViewById(R.id.actv_show_more)
}
}
interface LineItemClickListener {
fun onItemClick(position: Int,close:Boolean)
}
}

View File

@@ -1,76 +0,0 @@
package com.mogo.och.weaknet.ui.adapter
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import com.mogo.och.weaknet.ui.adapter.SwitchLineTaskAdapter.SwitchLineTaskViewHolder
import com.mogo.och.shuttle.weaknet.R
/**
* 路线列表adapter
*/
class SwitchLineTaskAdapter(
private val mContext: Context,
private var checkTaskId:Long,
private val mData: List<BusQueryLineTaskResponse.Result>?,
private val mTaskItemClickListener: TaskItemClickListener?
) : RecyclerView.Adapter<SwitchLineTaskViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SwitchLineTaskViewHolder {
val view = LayoutInflater.from(mContext).inflate(
R.layout.shuttle_weak_switch_line_list_task_item, parent, false
)
return SwitchLineTaskViewHolder(view)
}
override fun onBindViewHolder(holder: SwitchLineTaskViewHolder, position: Int) {
val currentPosition = holder.bindingAdapterPosition
val task = mData!![currentPosition]
val taskStartTime = TimeUtils.millis2String(task.taskStartTime, "HH:mm")
holder.lineTask.text = taskStartTime
if(checkTaskId==task.id){
holder.lineTask.setBackgroundResource(R.drawable.bus_shape_select_line_item_time_bg_selected)
}else{
holder.lineTask.setBackgroundResource(R.drawable.bus_shape_select_line_item_time_bg)
}
holder.lineTask.setOnClickListener {
if(checkTaskId==task.id){
checkTaskId = -1
mTaskItemClickListener?.onItemClick(currentPosition,false)
}else {
resetOther()
checkTaskId = task.id
mTaskItemClickListener?.onItemClick(currentPosition,true)
}
notifyItemChanged(currentPosition)
}
}
private fun resetOther() {
mData?.forEachIndexed { index, result ->
if(result.id==checkTaskId){
checkTaskId = -1
notifyItemChanged(index)
}
}
}
override fun getItemCount(): Int {
return mData?.size ?: 0
}
class SwitchLineTaskViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val lineTask: TextView // 时间
init {
lineTask = itemView.findViewById(R.id.actv_line_task)
}
}
interface TaskItemClickListener {
fun onItemClick(position: Int,isCheck:Boolean)
}
}

View File

@@ -0,0 +1,121 @@
package com.mogo.och.weaknet.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.util.ThreadUtils
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.common.module.wigets.WindowRelativeLayout
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import kotlinx.android.synthetic.main.shuttle_weak_switch_biz.view.loading_biz
import kotlinx.android.synthetic.main.shuttle_weak_switch_biz.view.swtichLine
import kotlinx.android.synthetic.main.shuttle_weak_switch_biz.view.swtichTask
import kotlinx.android.synthetic.main.shuttle_weak_switch_biz.view.taskRunning
class SwitchBizView: WindowRelativeLayout, SwtichBizeModel.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 = "SwitchBizView"
}
private var viewModel: SwtichBizeModel?=null
init {
LayoutInflater.from(context).inflate(R.layout.shuttle_weak_switch_biz, this, true)
initView()
}
private fun initView(){
loading_biz.setEmptyText(ResourcesUtils.getString(R.string.bus_switch_biz_loading))
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(SwtichBizeModel::class.java)
}
viewModel?.setDistanceCallback(this)
}
var startLoading = System.currentTimeMillis()
// 展示loading页面
override fun showLoadingView(){
startLoading = System.currentTimeMillis()
loading_biz.visibility = VISIBLE
swtichLine.visibility = GONE
swtichTask.visibility = GONE
}
/**
* 初始化数据
*/
override fun loadLineData() {
swtichLine.loadingDatas()
}
override fun showSwitchTaskByLineInfo(lineInfo: BusQueryLinesResponse.Result) {
// 展示loading
showLoadingView()
swtichTask.queryTaskByLineInfo(lineInfo)
}
// 展示选择任务页面
override fun showSwitchTaskInfo() {
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
swtichTask.visibility = VISIBLE
taskRunning.visibility = GONE
},dex,ThreadUtils.MODE.QUEUE)
}
// 展示选择线路页面
override fun showSwtichLineView() {
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
swtichTask.visibility = GONE
taskRunning.visibility = GONE
},dex,ThreadUtils.MODE.QUEUE)
}
// 展示正在进行的任务
override fun loadRunningTask() {
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
swtichTask.visibility = GONE
taskRunning.visibility = VISIBLE
taskRunning.showRunningTaskInfo()
},dex,ThreadUtils.MODE.QUEUE)
}
}

View File

@@ -0,0 +1,86 @@
package com.mogo.och.weaknet.ui.bizswitch
import androidx.lifecycle.ViewModel
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.data.bean.BusStationBean
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.weaknet.callback.IBusLinesCallback
import com.mogo.och.weaknet.database.bean.TaskDataBean
import com.mogo.och.weaknet.model.BusLineModel
/**
* @author XuXinChao
* @description BadCase录包管理页面
* @since: 2022/12/15
*/
class SwtichBizeModel : ViewModel(), IBusLinesCallback {
private val TAG = SwtichBizeModel::class.java.simpleName
private var viewCallback: SwtichLineViewCallback? = null
override fun onCleared() {
BusLineModel.setBusLinesCallback(TAG, null)
}
fun setDistanceCallback(viewCallback: SwtichLineViewCallback) {
this.viewCallback = viewCallback
BusLineModel.setBusLinesCallback(TAG, this)
this.viewCallback?.showLoadingView()
ThreadUtils.getIoPool().execute {
BusLineModel.loadStartedTaskAndDefaultInfo()
}
}
fun loadingSwitchTask(lineInfo: BusQueryLinesResponse.Result) {
viewCallback?.showSwitchTaskByLineInfo(lineInfo)
}
fun showSwitchTaskInfo() {
viewCallback?.showSwitchTaskInfo()
}
fun showSwitchLineInfo() {
viewCallback?.showLoadingView()
viewCallback?.loadLineData()
}
fun showSwitchLineInfoResult() {
viewCallback?.showSwtichLineView()
}
fun showRunningTaskView() {
}
interface SwtichLineViewCallback {
fun showSwtichLineView()
fun showLoadingView()
fun showSwitchTaskByLineInfo(lineInfo: BusQueryLinesResponse.Result)
fun showSwitchTaskInfo()
fun loadLineData()
fun loadRunningTask()
}
override fun onNoRunningTask() {
this.viewCallback?.loadLineData()
CallerLogger.d(TAG,"没有任务去加载线路")
}
override fun onRunningTask() {
this.viewCallback?.loadRunningTask()
CallerLogger.d(TAG,"有任务去加载正在执行的任务")
}
override fun onCompleteTask() {
super.onCompleteTask()
ThreadUtils.getIoPool().execute {
BusLineModel.loadStartedTaskAndDefaultInfo()
}
}
}

View File

@@ -0,0 +1,121 @@
package com.mogo.och.weaknet.ui.switchline
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import androidx.appcompat.widget.AppCompatTextView
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.DiffUtil.Callback
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.weaknet.ui.switchline.SwitchLineAdapter.SwitchLineViewHolder
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
/**
* 路线列表adapter
*/
class SwitchLineAdapter(
private val mContext: Context,
val mData: MutableList<BusQueryLinesResponse.Result>
) : RecyclerView.Adapter<SwitchLineViewHolder>() {
companion object{
const val TAG = "SwitchLineAdapter"
}
// RecyclerView设置点击事件
private var mItemClickListener: LineItemClickListener? = null
var checkLine:BusQueryLinesResponse.Result? = null
var checkTask: BusQueryLineTaskResponse.Result? = null
fun setDataList(dataList: List<BusQueryLinesResponse.Result>) {
if (this.mData == dataList) {
// 如果新旧列表一致,则直接返回
return
}
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.shuttle_weak_switch_line_list_item, parent, false
)
return SwitchLineViewHolder(view)
}
override fun onBindViewHolder(holder: SwitchLineViewHolder, position: Int) {
val currentPosition = holder.bindingAdapterPosition
val line = mData[currentPosition]
holder.lineName.text = line.name
val string = mContext.getString(R.string.bus_line_goto_end, line.endSiteName)
holder.lineEndName.text = string
//设置item点击事件
holder.itemView.setOnClickListener {
mData.forEachIndexed { index, result ->
notifyItemChanged(index)
if(result.taskList!=null) {
result.taskList.clear()
}
if(index==currentPosition){// 点击当前已经打开的item 去关闭定时网络请求
mItemClickListener?.onItemClick(currentPosition,true)
return@setOnClickListener
}
}
mItemClickListener?.onItemClick(currentPosition,false)
}
}
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(position: Int,close:Boolean)
}
inner class MyDiffCallback(private val oldData:List<BusQueryLinesResponse.Result>, private val newData:List<BusQueryLinesResponse.Result>):
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
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldData[oldItemPosition]
val newItem = newData[newItemPosition]
return oldItem == newItem
}
}
}

View File

@@ -0,0 +1,168 @@
package com.mogo.och.weaknet.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 androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.view.SpacesItemDecoration
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.common.module.wigets.WindowRelativeLayout
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.weaknet.model.BusLineModel
import com.mogo.och.weaknet.ui.bizswitch.SwtichBizeModel
import kotlinx.android.synthetic.main.shuttle_wadk_task_running.view.no_order_data_view
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.view.aciv_refresh_task
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.view.actv_last_refresh_date
import kotlinx.android.synthetic.main.shuttle_weak_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 = "BadCaseManagerView"
}
private var viewModel:SwtichLineModel?=null
private var viewbizModel:SwtichBizeModel?=null
private lateinit var mAdapter: SwitchLineAdapter
private var animator:ObjectAnimator?=null
private lateinit var linearLayoutManager:LinearLayoutManager
private var animatorStart = System.currentTimeMillis()
init {
LayoutInflater.from(context).inflate(R.layout.shuttle_weak_switch_line, this, true)
initView()
}
private fun initView(){
linearLayoutManager = LinearLayoutManager(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(position: Int, close: Boolean) {
viewbizModel?.loadingSwitchTask(mAdapter.mData[position])
//viewModel?.queryBusLineTasks(mAdapter.mData[position].lineId, position, close)
}
})
aciv_refresh_task.onClick {
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()
}
}
/**
* 初始化数据
*/
fun loadingDatas() {
CallerLogger.d(TAG,"加载线路去")
viewModel?.queryBusLines()
viewModel?.setRefreshTime()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(SwtichLineModel::class.java)
}
viewbizModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(SwtichBizeModel::class.java)
}
viewModel?.setDistanceCallback(this)
}
override fun startTaskState(success: Boolean) {
}
override fun onBusLinesChange(data: MutableList<BusQueryLinesResponse.Result>?) {
if (data.isNullOrEmpty()) {
showNoData(true)
}else{
showNoData(false)
mAdapter.setDataList(data)
}
CallerLogger.d(TAG,"加载线路成功")
viewbizModel?.showSwitchLineInfoResult()
}
/**
* 有无数据UI显示
* @param b
*/
private fun showNoData(b: Boolean) {
if (b) {
switch_line_rv.visibility = View.GONE
no_order_data_view.visibility = View.VISIBLE
} else {
switch_line_rv.visibility = View.VISIBLE
no_order_data_view.visibility = View.GONE
}
}
override fun onChangeLineIdSuccess() {
ToastUtils.showLong(resources.getString(R.string.bus_change_line_commit_tip_s))
viewModel?.queryBusRoutes()
mAdapter.setOnLineItemClickListener(null)
}
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.bus_refresh_time,it)
animator?.cancel()
}
},dex,UiThreadHandler.MODE.QUEUE,)
}
}

View File

@@ -0,0 +1,81 @@
package com.mogo.och.weaknet.ui.switchline
import androidx.lifecycle.ViewModel
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.weaknet.callback.IBusLinesCallback
import com.mogo.och.weaknet.model.BusLineModel
import com.mogo.och.weaknet.model.BusLineModel.executableChangeTime
import com.mogo.och.weaknet.model.OrderModel
/**
* @author XuXinChao
* @description BadCase录包管理页面
* @since: 2022/12/15
*/
class SwtichLineModel : ViewModel(), IBusLinesCallback {
private val TAG = SwtichLineModel::class.java.simpleName
private var viewCallback:SwtichLineViewCallback?=null
override fun onCleared() {
BusLineModel.setBusLinesCallback(TAG,null)
}
fun setDistanceCallback(viewCallback:SwtichLineViewCallback){
this.viewCallback = viewCallback
BusLineModel.setBusLinesCallback(TAG,this)
}
fun queryBusLines() {
BusLineModel.queryBusLines()
}
fun setRefreshTime() {
val lastUpdateTime = SharedPrefsMgr.getInstance().getLong(executableChangeTime, -1)
if(lastUpdateTime>0){
this.onRefreshSuccess(lastUpdateTime)
}
}
fun refreshTask() {
BusLineModel.refreshTask()
}
fun queryBusRoutes() {
OrderModel.queryBusRoutes()
}
interface SwtichLineViewCallback{
fun startTaskState(success: Boolean)
fun onBusLinesChange(data: MutableList<BusQueryLinesResponse.Result>?)
fun onChangeLineIdSuccess()
fun refreshDate(formatLongToString: String?)
}
override fun onBusLinesChange(data: MutableList<BusQueryLinesResponse.Result>?) {
viewCallback?.onBusLinesChange(data)
}
override fun onChangeLineIdSuccess() {
ThreadUtils.runOnUiThread( {
viewCallback?.onChangeLineIdSuccess()
},ThreadUtils.MODE.QUEUE)
}
override fun onRefreshSuccess(currentTimeStamp: Long) {
viewCallback?.refreshDate(
DateTimeUtil.formatLongToString(currentTimeStamp, DateTimeUtil.HH_mm_ss)
)
}
override fun onChangeLineIdFail() {
viewCallback?.startTaskState(false)
}
}

View File

@@ -0,0 +1,129 @@
package com.mogo.och.weaknet.ui.switchtask
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.widget.AppCompatCheckedTextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.DiffUtil.Callback
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import com.mogo.och.weaknet.ui.switchtask.SwitchLineTaskAdapter.SwitchLineTaskViewHolder
import com.mogo.och.shuttle.weaknet.R
/**
* 路线列表adapter
*/
@Suppress("UNUSED_EXPRESSION")
class SwitchLineTaskAdapter(
private val mContext: Context,
private var checkTask:BusQueryLineTaskResponse.Result?,
private val mData: MutableList<BusQueryLineTaskResponse.Result>,
) : RecyclerView.Adapter<SwitchLineTaskViewHolder>() {
fun setDataList(dataList: List<BusQueryLineTaskResponse.Result>) {
if (this.mData == dataList) {
// 如果新旧列表一致,则直接返回
return
}
checkTask = null
val diffResult = DiffUtil.calculateDiff(MyDiffCallback(this.mData, dataList))
this.mData.clear()
this.mData.addAll(dataList)
diffResult.dispatchUpdatesTo(this)
}
fun getCheckTask():BusQueryLineTaskResponse.Result?{
return checkTask
}
private var mTaskItemClickListener: TaskItemClickListener? = null
fun setOnLineItemClickListener(mTaskItemClickListener: TaskItemClickListener?) {
this.mTaskItemClickListener = mTaskItemClickListener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SwitchLineTaskViewHolder {
val view = LayoutInflater.from(mContext).inflate(
R.layout.shuttle_weak_switch_task_item, parent, false
)
return SwitchLineTaskViewHolder(view)
}
override fun onBindViewHolder(holder: SwitchLineTaskViewHolder, position: Int) {
val currentPosition = holder.bindingAdapterPosition
val task = mData[currentPosition]
val taskStartTime = TimeUtils.millis2String(task.taskStartTime, "HH:mm")
holder.taskTime.text = taskStartTime
holder.taskTime.isChecked = if(checkTask!=null) checkTask!!.id == task.id else false
holder.taskTime.setOnClickListener {
if(checkTask==null){
resetOther()
checkTask = task
mTaskItemClickListener?.onItemClick(currentPosition,true)
}else{
if(checkTask!!.id==task.id){
checkTask = null
mTaskItemClickListener?.onItemClick(currentPosition,false)
}else {
resetOther()
checkTask = task
mTaskItemClickListener?.onItemClick(currentPosition,true)
}
}
notifyItemChanged(currentPosition)
}
}
private fun resetOther() {
mData.forEachIndexed { index, result ->
if(checkTask!=null && result.id==checkTask!!.id){
checkTask = null
notifyItemChanged(index)
}
}
}
override fun getItemCount(): Int {
return mData.size
}
class SwitchLineTaskViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
val taskTime: AppCompatCheckedTextView = itemView.findViewById(R.id.actv_task_time) // 时间
}
interface TaskItemClickListener {
fun onItemClick(position: Int,isCheck:Boolean)
}
inner class MyDiffCallback(private val oldData:List<BusQueryLineTaskResponse.Result>, private val newData:List<BusQueryLineTaskResponse.Result>):
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.id == newItem.id
}
override fun areContentsTheSame(oldItemPosition: Int, newItemPosition: Int): Boolean {
val oldItem = oldData[oldItemPosition]
val newItem = newData[newItemPosition]
return oldItem.id == newItem.id
}
}
}

View File

@@ -0,0 +1,146 @@
package com.mogo.och.weaknet.ui.switchtask
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.view.SpacesItemDecoration
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.common.module.wigets.WindowRelativeLayout
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.weaknet.ui.bizswitch.SwtichBizeModel
import com.mogo.och.weaknet.ui.switchtask.SwitchLineTaskAdapter.TaskItemClickListener
import kotlinx.android.synthetic.main.shuttle_weak_switch_task.view.actvLineEndStationName
import kotlinx.android.synthetic.main.shuttle_weak_switch_task.view.actv_cancle_task
import kotlinx.android.synthetic.main.shuttle_weak_switch_task.view.actv_submit_task
import kotlinx.android.synthetic.main.shuttle_weak_switch_task.view.busLineName
import kotlinx.android.synthetic.main.shuttle_weak_switch_task.view.cl_submit_task
import kotlinx.android.synthetic.main.shuttle_weak_switch_task.view.include_empty
import kotlinx.android.synthetic.main.shuttle_weak_switch_task.view.loading_start_line
import kotlinx.android.synthetic.main.shuttle_weak_switch_task.view.rv_switch_task
import me.jessyan.autosize.utils.AutoSizeUtils
class SwitchTaskView: WindowRelativeLayout, SwtichTaskModel.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 = "BadCaseManagerView"
}
private var viewModel:SwtichTaskModel?=null
private var viewbizModel:SwtichBizeModel?=null
private lateinit var mAdapter: SwitchLineTaskAdapter
private lateinit var linearLayoutManager:LinearLayoutManager
init {
LayoutInflater.from(context).inflate(R.layout.shuttle_weak_switch_task, this, true)
initView()
}
private fun initView(){
linearLayoutManager = GridLayoutManager(context, 3)
rv_switch_task.setLayoutManager(linearLayoutManager)
mAdapter = SwitchLineTaskAdapter(context,null, mutableListOf())
rv_switch_task.setAdapter(mAdapter)
mAdapter.setOnLineItemClickListener(object : TaskItemClickListener{
override fun onItemClick(position: Int, isCheck: Boolean) {
}
})
//rv_switch_task.setRecycledViewPool(null);
rv_switch_task.addItemDecoration(
TaskBottomDecoration(
AutoSizeUtils.dp2px(context, 174f)
)
)
actv_submit_task.onClick {
val tempCheckTask = mAdapter.getCheckTask()
if(tempCheckTask==null){
ToastUtils.showShort("请选择任务")
}else{
viewModel?.changeLineStart(tempCheckTask)
}
}
actv_cancle_task.onClick {
viewbizModel?.showSwitchLineInfo()
}
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(SwtichTaskModel::class.java)
}
viewbizModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(SwtichBizeModel::class.java)
}
viewModel?.setDistanceCallback(this)
}
fun queryTaskByLineInfo(lineInfo: BusQueryLinesResponse.Result) {
viewModel?.queryBusLineTasksById(lineInfo)
busLineName.text = lineInfo.name
actvLineEndStationName.text = "${lineInfo.endSiteName}方向"
}
override fun showTaskByLineIdResult(taskList: MutableList<BusQueryLineTaskResponse.Result>) {
if(taskList.isEmpty()){
showEmptyView()
}else {
showData()
mAdapter.setDataList(taskList)
}
viewbizModel?.showSwitchTaskInfo()
}
private fun showData(){
actv_submit_task.setTextColor(ResourcesUtils.getColors(R.color.bus_task_submit_text_color_selector))
actv_submit_task.isEnabled = true
rv_switch_task.visibility = VISIBLE
include_empty.visibility = GONE
}
override fun showLoading(){
loading_start_line.visibility = VISIBLE
actv_submit_task.isEnabled = false
actv_cancle_task.isEnabled = false
}
override fun hideLoading(){
loading_start_line.visibility = GONE
actv_submit_task.isEnabled = true
actv_cancle_task.isEnabled = true
}
override fun startTaskSuccess() {
viewbizModel?.showRunningTaskView()
}
private fun showEmptyView(){
actv_submit_task.setTextColor(ResourcesUtils.getColor(R.color.bus_color_66666))
actv_submit_task.isEnabled = false
rv_switch_task.visibility = GONE
include_empty.visibility = VISIBLE
}
}

View File

@@ -0,0 +1,94 @@
package com.mogo.och.weaknet.ui.switchtask
import androidx.lifecycle.ViewModel
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.och.common.module.utils.RxUtils
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.weaknet.callback.IBusLinesCallback
import com.mogo.och.weaknet.model.BusLineModel
import io.reactivex.disposables.Disposable
/**
* @author XuXinChao
* @description BadCase录包管理页面
* @since: 2022/12/15
*/
class SwtichTaskModel : ViewModel(), IBusLinesCallback {
private val TAG = SwtichTaskModel::class.java.simpleName
private var viewCallback:SwtichLineViewCallback?=null
private var tasksBelongLine: BusQueryLinesResponse.Result? = null
private var subscribe: Disposable? = null
override fun onCleared() {
RxUtils.disposeSubscribe(subscribe)
BusLineModel.setBusLinesCallback(TAG,null)
}
fun setDistanceCallback(viewCallback:SwtichLineViewCallback){
this.viewCallback = viewCallback
BusLineModel.setBusLinesCallback(TAG,this)
}
fun queryBusLineTasksById(lineInfo: BusQueryLinesResponse.Result) {
tasksBelongLine = lineInfo
BusLineModel.queryBusLineTasksById(lineInfo.lineId)
}
interface SwtichLineViewCallback{
fun showTaskByLineIdResult(taskList: MutableList<BusQueryLineTaskResponse.Result>)
fun showLoading()
fun hideLoading()
fun startTaskSuccess()
}
override fun onBusLineTasks(o: MutableList<BusQueryLineTaskResponse.Result>) {
viewCallback?.showTaskByLineIdResult(o)
}
override fun onRefreshSuccess(currentTimeStamp: Long) {
TODO("Not yet implemented")
}
// 选择线路成功
override fun onChangeLineIdSuccess() {
if (ThreadUtils.isMainThread()) {
viewCallback?.hideLoading()
viewCallback?.startTaskSuccess()
}else{
ThreadUtils.runOnUiThread({
viewCallback?.hideLoading()
viewCallback?.startTaskSuccess()
},ThreadUtils.MODE.QUEUE)
}
}
// 选择线路失败
override fun onChangeLineIdFail() {
if (ThreadUtils.isMainThread()) {
viewCallback?.hideLoading()
}else{
ThreadUtils.runOnUiThread({
viewCallback?.hideLoading()
},ThreadUtils.MODE.QUEUE)
}
viewCallback?.hideLoading()
}
fun changeLineStart(checkTask:BusQueryLineTaskResponse.Result) {
if(tasksBelongLine==null){
ToastUtils.showShort("请重新选择线路")
return
}
viewCallback?.showLoading()
BusLineModel.commitSwitchLineId(checkTask,tasksBelongLine!!)
}
}

View File

@@ -0,0 +1,46 @@
package com.mogo.och.weaknet.ui.switchtask
import android.graphics.Rect
import android.view.View
import android.widget.LinearLayout
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
class TaskBottomDecoration(val distance: Int) : RecyclerView.ItemDecoration() {
private val TAG = "TaskBottomDecoration"
override fun getItemOffsets(
outRect: Rect,
view: View,
parent: RecyclerView,
state: RecyclerView.State
) {
val pos = parent.getChildAdapterPosition(view)
/**
* 通过设置Item左右边距实现第一个左侧和最后一个右侧设置边距,确保显示的视图位于屏幕中间
*/
val itemCount = parent.adapter!!.itemCount
val layoutManager = parent.layoutManager
if(layoutManager is GridLayoutManager){
var lastPathCount = itemCount % layoutManager.spanCount
//2 5 % 3
CallerLogger.d(TAG,"位置---${pos}_lastPathCount:${lastPathCount}_____itemCount:${itemCount}__spanCount:${layoutManager.spanCount}")
if(lastPathCount==0){
lastPathCount = layoutManager.spanCount
}
if(pos<itemCount-lastPathCount){
}else{
outRect.bottom = distance
}
// if(pos==itemCount-1){
// outRect.bottom = distance
// }
}
//super.getItemOffsets(outRect, view, parent, state)
}
}

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.ui.taskrunning;
package com.mogo.och.weaknet.ui.taskrunned;
import android.graphics.Rect;
import android.view.View;

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.ui.taskrunning
package com.mogo.och.weaknet.ui.taskrunned
import android.content.Context
import android.view.LayoutInflater
@@ -8,10 +8,7 @@ import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.DiffUtil.Callback
import androidx.recyclerview.widget.RecyclerView
import com.mogo.eagle.core.function.business.travelreality.EventDrawBean
import com.mogo.eagle.core.utilcode.util.TimeUtils
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import com.mogo.och.weaknet.ui.adapter.SwitchLineTaskAdapter.SwitchLineTaskViewHolder
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.bean.WaitUploadLine

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.ui.taskrunning
package com.mogo.och.weaknet.ui.taskrunned
import android.content.Context
@@ -25,6 +25,7 @@ import com.mogo.eagle.core.utilcode.kotlin.lifeCycleOwner
import com.mogo.eagle.core.utilcode.reminder.Reminder
import com.mogo.eagle.core.utilcode.reminder.api.impl.PopupWindowReminder
import com.mogo.eagle.core.utilcode.util.*
import com.mogo.och.weaknet.ui.bizswitch.SwitchBizView
import me.jessyan.autosize.utils.AutoSizeUtils
import kotlin.math.abs

View File

@@ -1,8 +1,6 @@
package com.mogo.och.weaknet.ui.taskrunning
package com.mogo.och.weaknet.ui.taskrunned
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.lifecycle.ViewModelProvider
@@ -13,10 +11,8 @@ import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.common.module.wigets.WindowRelativeLayout
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.bean.WaitUploadLine
import com.mogo.och.weaknet.ui.adapter.OpenItemAnimator
import kotlinx.android.synthetic.main.shuttle_wadk_task_running.view.aciv_show_data
import kotlinx.android.synthetic.main.shuttle_wadk_task_running.view.actvCurrentDate
import kotlinx.android.synthetic.main.shuttle_wadk_task_running.view.clLayout
import kotlinx.android.synthetic.main.shuttle_wadk_task_running.view.ivTaskRunningClose
import kotlinx.android.synthetic.main.shuttle_wadk_task_running.view.no_order_data_view
import kotlinx.android.synthetic.main.shuttle_wadk_task_running.view.rvDataLiet
@@ -62,7 +58,6 @@ class RunningTaskManagerView: WindowRelativeLayout, RunningTastViewModel.Running
linearLayoutManager = LinearLayoutManager(context)
rvDataLiet.setLayoutManager(linearLayoutManager)
rvDataLiet.setItemAnimator(OpenItemAnimator())
mAdapter = RunningTaskAdapter(context, mutableListOf())
rvDataLiet.addItemDecoration(
BottomDecoration(

View File

@@ -1,4 +1,4 @@
package com.mogo.och.weaknet.ui.taskrunning
package com.mogo.och.weaknet.ui.taskrunned
import androidx.lifecycle.ViewModel
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger

View File

@@ -0,0 +1,106 @@
package com.mogo.och.weaknet.ui.taskrunning
import android.annotation.SuppressLint
import android.content.Context
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.DiffUtil
import androidx.recyclerview.widget.DiffUtil.Callback
import androidx.recyclerview.widget.RecyclerView
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.data.bean.BusStationBean
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.bean.BusQueryLineTaskResponse
import com.mogo.och.weaknet.ui.writeoff.WriteOffView
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 = "TaskRunningAdapter"
}
private var startStationIndex:Int = -1
fun setDataList(dataList: List<BusStationBean>, startStationIndex:Int) {
this.startStationIndex = startStationIndex
val tempData = this.mData
this.mData.clear()
this.mData.addAll(dataList)
notifyDataSetChanged()
}
override fun onCreateViewHolder(
parent: ViewGroup,
viewType: Int
): TaskRunningViewHolder {
val view = LayoutInflater.from(mContext).inflate(
R.layout.shuttle_weak_running_station_list_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
if(currentPosition<startStationIndex){
holder.actvStationName.setTextSize(TypedValue.COMPLEX_UNIT_PX, AutoSizeUtils.dp2px(mContext,40f).toFloat())
holder.actvStationName.setTextColor(ResourcesUtils.getColor(R.color.bus_color_4dffffff))
holder.itemView.background = null
holder.actvWriteOffCount.visibility = View.GONE
}else if(currentPosition==startStationIndex){
holder.actvStationName.setTextSize(TypedValue.COMPLEX_UNIT_PX, AutoSizeUtils.dp2px(mContext,45f).toFloat())
holder.actvStationName.setTextColor(ResourcesUtils.getColor(R.color.bus_color_2EACFF))
holder.itemView.setBackgroundResource(R.drawable.bus_task_current_station_bg)
holder.actvWriteOffCount.visibility = View.VISIBLE
}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.actvWriteOffCount.visibility = View.GONE
}
when (currentPosition) {
0 -> {
holder.acivStationHeadBig.visibility = View.VISIBLE
holder.acivStationHead.visibility = View.INVISIBLE
holder.acivStationHeadBig.setImageResource(R.drawable.bus_runnint_task_start)
}
mData.size-1 -> {
holder.acivStationHeadBig.visibility = View.VISIBLE
holder.acivStationHead.visibility = View.INVISIBLE
holder.acivStationHeadBig.setImageResource(R.drawable.bus_runnint_task_end)
}
else -> {
holder.acivStationHeadBig.visibility = View.GONE
holder.acivStationHead.visibility = View.VISIBLE
holder.acivStationHead.setImageResource(R.drawable.bus_runnint_task_middle)
}
}
}
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 actvWriteOffCount: WriteOffView = itemView.findViewById(R.id.actv_write_off_count) //此战核销的人数
}
}

View File

@@ -0,0 +1,77 @@
package com.mogo.och.weaknet.ui.taskrunning
import androidx.lifecycle.ViewModel
import com.mogo.commons.storage.SharedPrefsMgr
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.utils.DateTimeUtil
import com.mogo.och.weaknet.bean.BusQueryLinesResponse
import com.mogo.och.weaknet.callback.IBusLinesCallback
import com.mogo.och.weaknet.model.BusLineModel
import com.mogo.och.weaknet.model.BusLineModel.executableChangeTime
import com.mogo.och.weaknet.model.OrderModel
/**
* @author XuXinChao
* @description BadCase录包管理页面
* @since: 2022/12/15
*/
class TaskRunningModel : ViewModel(), IBusLinesCallback {
private val TAG = TaskRunningModel::class.java.simpleName
private var viewCallback:SwtichLineViewCallback?=null
override fun onCleared() {
}
fun setDistanceCallback(viewCallback:SwtichLineViewCallback){
this.viewCallback = viewCallback
BusLineModel.setBusLinesCallback(TAG,this)
}
fun leaveStation() {
OrderModel.autoDriveToNextStation()
}
interface SwtichLineViewCallback{
fun showRunningTaskInfo()
}
override fun onLeaveStaionSuccess() {
BizLoopManager.runInMainThread{
viewCallback?.showRunningTaskInfo()
}
}
override fun onLeaveStaionFail() {
BizLoopManager.runInMainThread{
viewCallback?.showRunningTaskInfo()
}
}
fun arriveStation() {
OrderModel.onArriveAt(null, "页面触发到站")
}
override fun onArriveStationSuccess() {
BizLoopManager.runInMainThread{
viewCallback?.showRunningTaskInfo()
}
}
override fun onCompleteTask() {
BizLoopManager.runInMainThread{
viewCallback?.showRunningTaskInfo()
}
}
fun completeTask() {
OrderModel.abortTask()
}
}

View File

@@ -0,0 +1,145 @@
package com.mogo.och.weaknet.ui.taskrunning
import android.animation.ObjectAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.utilcode.kotlin.onClick
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.view.SpacesItemDecoration
import com.mogo.och.common.module.manager.autopilot.line.LineManager
import com.mogo.och.common.module.utils.ResourcesUtils
import com.mogo.och.common.module.wigets.OCHCommitDialog
import com.mogo.och.shuttle.weaknet.R
import com.mogo.och.weaknet.model.BusLineModel
import com.mogo.och.weaknet.ui.bizswitch.SwtichBizeModel
import com.mogo.och.weaknet.ui.switchline.SwitchLineAdapter
import com.mogo.och.weaknet.view.BizLeaveStationView.SlideListener
import kotlinx.android.synthetic.main.shuttle_weak_switch_line.view.switch_line_rv
import kotlinx.android.synthetic.main.shuttle_weak_task_running.view.aciv_task_leave_station_slide_bg
import kotlinx.android.synthetic.main.shuttle_weak_task_running.view.actv_arriver_station
import kotlinx.android.synthetic.main.shuttle_weak_task_running.view.actv_complete_task
import kotlinx.android.synthetic.main.shuttle_weak_task_running.view.actv_running_task_last_station
import kotlinx.android.synthetic.main.shuttle_weak_task_running.view.actv_running_task_time
import kotlinx.android.synthetic.main.shuttle_weak_task_running.view.bus_task_running_line_name
import kotlinx.android.synthetic.main.shuttle_weak_task_running.view.rl_running_task_station_list
import me.jessyan.autosize.utils.AutoSizeUtils
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 = "TaskRunningView"
}
private var viewModel:TaskRunningModel?=null
private var viewbizModel:SwtichBizeModel?=null
private lateinit var mAdapter: TaskRunningAdapter
private lateinit var linearLayoutManager:LinearLayoutManager
init {
LayoutInflater.from(context).inflate(R.layout.shuttle_weak_task_running, this, true)
initView()
}
private fun initView(){
linearLayoutManager = LinearLayoutManager(context)
rl_running_task_station_list.setLayoutManager(linearLayoutManager)
mAdapter = TaskRunningAdapter(context, mutableListOf())
rl_running_task_station_list.addItemDecoration(
SpacesItemDecoration(
AutoSizeUtils.dp2px(context,20f)
)
)
rl_running_task_station_list.setAdapter(mAdapter)
aciv_task_leave_station_slide_bg.setSlideListener(object : SlideListener{
override fun slideEnd() {
viewModel?.leaveStation()
}
})
actv_arriver_station.onClick {
viewModel?.arriveStation()
}
actv_complete_task.onClick {
val builder = OCHCommitDialog.Builder()
val closeLineConfirmDialog = builder
.title(ResourcesUtils.getString(R.string.bus_dialog_title))
.tips(ResourcesUtils.getString(R.string.bus_dialog_tips))
.confirmStr(ResourcesUtils.getString(R.string.bus_dialog_confirm))
.cancelStr(ResourcesUtils.getString(R.string.bus_dialog_cancel))
.build(AbsMogoApplication.getApp())
closeLineConfirmDialog!!.setClickListener(object : OCHCommitDialog.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(SwtichBizeModel::class.java)
}
viewModel?.setDistanceCallback(this)
}
override fun showRunningTaskInfo() {
bus_task_running_line_name.text = LineManager.lineInfos?.lineName?:""
actv_running_task_time.text = BusLineModel.getTaskTime()
BusLineModel.stationList?.takeIf { it.size>2 }?.let {
actv_running_task_last_station.text = "${it.last().name ?: ""}"
mAdapter.setDataList(it,BusLineModel.startStationIndex)
CallerLogger.d(TAG,"BusLineModel.startStationIndex:${BusLineModel.startStationIndex}___$it")
val currentStation = it.get(BusLineModel.startStationIndex)
if(currentStation.isLeaving){
showArriverStationAndCompleteTask()
}else{
showLeaveStationView()
}
if(BusLineModel.startStationIndex==it.size-1){
aciv_task_leave_station_slide_bg.setTextValue("单程结束")
}else{
aciv_task_leave_station_slide_bg.setTextValue("滑动出发")
}
}
}
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
}
}

View File

@@ -3,13 +3,14 @@ package com.mogo.och.weaknet.ui.writeoff
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import androidx.appcompat.widget.AppCompatTextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.findViewTreeViewModelStoreOwner
import com.mogo.och.shuttle.weaknet.R
import kotlinx.android.synthetic.main.shuttle_weak_wirte_off_view.view.tv_write_off_count
class WriteOffView : ConstraintLayout, WriteOffViewModel.IwriteOffViewCallback {
class WriteOffView : AppCompatTextView, WriteOffViewModel.IwriteOffViewCallback {
private val TAG = "ItineraryView"
@@ -19,35 +20,45 @@ class WriteOffView : ConstraintLayout, WriteOffViewModel.IwriteOffViewCallback {
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)
constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int, defStyleRes: Int) : super(context, attributeSet, defStyleAttr, defStyleRes)
private fun initView() {
LayoutInflater.from(context).inflate(R.layout.shuttle_weak_wirte_off_view, this, true)
}
private var viewModel:WriteOffViewModel? = null
override fun onAttachedToWindow() {
super.onAttachedToWindow()
val viewModel = findViewTreeViewModelStoreOwner()?.let {
viewModel = findViewTreeViewModelStoreOwner()?.let {
ViewModelProvider(it).get(WriteOffViewModel::class.java)
}
viewModel?.setWriteOffCallback(this)
}
private fun startListenerWriteOff(){
viewModel?.setWriteOffCallback(this)
visibility = VISIBLE
}
private fun stopListenerWriteOff(){
viewModel?.setWriteOffCallback(null)
visibility = GONE
}
override fun onVisibilityAggregated(isVisible: Boolean) {
super.onVisibilityAggregated(isVisible)
if(isVisible){
startListenerWriteOff()
}else{
stopListenerWriteOff()
}
}
init {
try {
initView()
} catch (e: Exception) {
e.printStackTrace()
}
}
override fun setWriteOffCount(showText: String) {
tv_write_off_count.text = showText
text = showText
}

View File

@@ -43,7 +43,7 @@ class WriteOffViewModel : ViewModel() {
}
fun setWriteOffCallback(viewCallback: IwriteOffViewCallback) {
fun setWriteOffCallback(viewCallback: IwriteOffViewCallback?) {
this.viewCallback = viewCallback
TicketModel
.getWriteOffCountObservable()

View File

@@ -0,0 +1,134 @@
package com.mogo.och.weaknet.view
import android.animation.ObjectAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.MotionEvent
import androidx.appcompat.widget.AppCompatTextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.och.shuttle.weaknet.R
import kotlinx.android.synthetic.main.shuttle_weak_task_leave_station_view.view.actv_draggable
class BizLeaveStationView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr) {
companion object {
const val TAG = "LoadingMapStatusView"
}
private var initialX = 0f
private var initialY = 0f
private val tempSet = ConstraintSet()
private var draggableButton: AppCompatTextView
private var slideListener:SlideListener?=null
fun setSlideListener(slideListener:SlideListener){
this.slideListener = slideListener
}
init {
LayoutInflater.from(context).inflate(R.layout.shuttle_weak_task_leave_station_view, this, true)
draggableButton = findViewById(R.id.actv_draggable)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerLogger.d(TAG,"onAttachedToWindow")
}
/**
* 为该组件的触碰事件重写事件处理方法
*/
override fun onTouchEvent(event: MotionEvent?): Boolean {
when (event?.action) {
MotionEvent.ACTION_DOWN -> {
initialX = event.rawX;
initialY = event.rawY;
}
MotionEvent.ACTION_MOVE -> {
val dx = event.rawX - initialX;
val dy = event.rawY - initialY;
initialX = event.rawX;
initialY = event.rawY;
if(draggableButton.translationX<0){
tempSet.clone(this)
tempSet.setTranslationX(draggableButton.id, 0f)
tempSet.applyTo(this)
}else if(draggableButton.translationX>=0&&draggableButton.translationX<=width-draggableButton.width){
tempSet.clone(this)
val dex = (draggableButton.translationX + dx).takeIf { it>=0 }?:0f
val newDex = dex.takeIf { it<=width-draggableButton.width }?:(width-draggableButton.width).toFloat()
tempSet.setTranslationX(draggableButton.id, newDex)
tempSet.applyTo(this)
}else{
tempSet.clone(this)
val dex = (draggableButton.translationX + dx).takeIf { it<=width-draggableButton.width }?:(width-draggableButton.width).toFloat()
tempSet.setTranslationX(draggableButton.id, dex)
tempSet.applyTo(this)
}
}
MotionEvent.ACTION_UP -> {
if(draggableButton.translationX<(width-draggableButton.width)){
ObjectAnimator.ofFloat(
draggableButton, "translationX", draggableButton.translationX,
0f
).apply {
duration = 100
}.start()
}else if (draggableButton.translationX>=(width-draggableButton.width)){
slideListener?.slideEnd()
}else{
ObjectAnimator.ofFloat(
draggableButton, "translationX", draggableButton.translationX,
0f
).apply {
duration = 100
}.start()
}
}
else -> {}
}
return true
}
override fun onVisibilityAggregated(isVisible: Boolean) {
super.onVisibilityAggregated(isVisible)
if(isVisible){
ObjectAnimator.ofFloat(
draggableButton, "translationX", draggableButton.translationX,
0f
).apply {
duration = 100
}.start()
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerLogger.d(TAG,"onDetachedFromWindow")
}
fun setTextValue(value: String) {
actv_draggable.text = value
}
interface SlideListener{
fun slideEnd()
}
}

View File

@@ -0,0 +1,69 @@
package com.mogo.och.weaknet.view
import android.animation.ObjectAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.animation.LinearInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.util.ThreadUtils
import com.mogo.map.listener.IMogoMapListener
import com.mogo.och.shuttle.weaknet.R
import kotlinx.android.synthetic.main.shuttle_weak_loading_view.view.actv_loading_text
import kotlinx.android.synthetic.main.shuttle_weak_loading_view.view.loading_view
class LoadingViewBig @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr),IMogoMapListener {
companion object {
const val TAG = "LoadingMapStatusView"
}
private var autopilotLoadingAnimator: ObjectAnimator? = null
init {
LayoutInflater.from(context).inflate(R.layout.shuttle_weak_loading_view, this, true)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerLogger.d(TAG,"onAttachedToWindow")
if (autopilotLoadingAnimator == null) {
autopilotLoadingAnimator = ObjectAnimator.ofFloat(loading_view, "rotation", 0f, 360f)
autopilotLoadingAnimator?.setInterpolator(LinearInterpolator())
autopilotLoadingAnimator?.setRepeatCount(-1) //无限循环
autopilotLoadingAnimator?.setDuration(1000) //设置持续时间
}
}
override fun onVisibilityAggregated(isVisible: Boolean) {
super.onVisibilityAggregated(isVisible)
if(isVisible){
autopilotLoadingAnimator?.start()
}else{
autopilotLoadingAnimator?.cancel()
}
}
fun setEmptyText(text:CharSequence){
if (ThreadUtils.isMainThread()) {
actv_loading_text.text = text
}else{
ThreadUtils.runOnUiThread( {
actv_loading_text.text = text
},ThreadUtils.MODE.QUEUE)
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerLogger.d(TAG,"onDetachedFromWindow")
}
}

View File

@@ -0,0 +1,56 @@
package com.mogo.och.weaknet.view
import android.animation.ObjectAnimator
import android.content.Context
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.animation.LinearInterpolator
import androidx.constraintlayout.widget.ConstraintLayout
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.map.listener.IMogoMapListener
import com.mogo.och.shuttle.weaknet.R
import kotlinx.android.synthetic.main.shuttle_weak_loading_view_samll.view.loading_view_samll
class LoadingViewSmall @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0
) : ConstraintLayout(context, attrs, defStyleAttr),IMogoMapListener {
companion object {
const val TAG = "LoadingMapStatusView"
}
private var autopilotLoadingAnimator: ObjectAnimator? = null
init {
LayoutInflater.from(context).inflate(R.layout.shuttle_weak_loading_view_samll, this, true)
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
CallerLogger.d(TAG,"onAttachedToWindow")
if (autopilotLoadingAnimator == null) {
autopilotLoadingAnimator = ObjectAnimator.ofFloat(loading_view_samll, "rotation", 0f, 360f)
autopilotLoadingAnimator?.setInterpolator(LinearInterpolator())
autopilotLoadingAnimator?.setRepeatCount(-1) //无限循环
autopilotLoadingAnimator?.setDuration(1000) //设置持续时间
}
}
override fun onVisibilityAggregated(isVisible: Boolean) {
super.onVisibilityAggregated(isVisible)
if(isVisible){
autopilotLoadingAnimator?.start()
}else{
autopilotLoadingAnimator?.cancel()
}
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
CallerLogger.d(TAG,"onDetachedFromWindow")
}
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/bus_color_2EACFF" android:state_pressed="true"/>
<item android:color="@color/white" android:state_pressed="false"/>
<item android:color="@color/white"/>
</selector>

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 310 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 491 B

After

Width:  |  Height:  |  Size: 137 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 521 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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