Merge branch 'refs/heads/dev_robotaxi-d_240807_6.6.0_yyk' into dev_robotaxi-d_240912_6.7.0

# Conflicts:
#	core/mogo-core-res/src/main/res/values/dimens.xml
This commit is contained in:
yangyakun
2024-09-13 19:41:30 +08:00
111 changed files with 2941 additions and 2434 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

@@ -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

@@ -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

@@ -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

@@ -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,15 @@ 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(){}
}

View File

@@ -1,8 +1,6 @@
package com.mogo.och.weaknet.fragment
import android.content.Intent
import android.graphics.BitmapFactory
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
@@ -16,7 +14,6 @@ import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListener
import com.mogo.eagle.core.function.call.map.CallerMapUIServiceManager.getOverlayManager
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.util.ToastUtils
import com.mogo.eagle.core.utilcode.util.UiThreadHandler
import com.mogo.map.MogoMap
@@ -36,12 +33,10 @@ 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 me.jessyan.autosize.utils.AutoSizeUtils
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.util.Objects
/**
* 网约车小巴界面
@@ -516,8 +511,9 @@ class ShuttleFragment : BaseShuttleTabFragment<ShuttleFragment?, BusPresenter?>(
return
}
if (mSwitchLine!!.tag as Int == 0) { //切换路线
val intent = Intent(context, BusSwitchLineActivity::class.java)
ActivityUtils.startActivity(intent)
context?.let {
RunningTaskManager.showSwitchLineWindow(it)
}
} else { //结束任务
val builder = OCHCommitDialog.Builder()
val closeLineConfirmDialog = builder

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,6 +70,8 @@ object BusLineModel {
// 展示上一次刷新时间
const val executableChangeTime = "executablechangetime"
const val LASTCOMMITLINEID = "lastcommitlineid"
var currentTask: TaskDataBean?=null
// 当前任务的站点列表
@@ -100,13 +104,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 +147,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 +213,9 @@ object BusLineModel {
}
override fun onNext(data: List<BusQueryLinesResponse.Result>) {
mBusLinesCallback?.onBusLinesChange(data)
mBusLinesCallbackMap.forEach {
it.value.onBusLinesChange(data)
}
}
})
@@ -214,7 +227,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 +244,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 +264,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 +323,9 @@ object BusLineModel {
val contraiInfoTemp = ContraiRepository.queryAutopilotInfoByLineid(it)
ContrailDataBean.save2Common(contraiInfoTemp)
}
mBusLinesCallbackMap.forEach { callback->
callback.value.onRunningTask()
}
}
}
@@ -324,7 +344,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 +362,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())

View File

@@ -320,30 +320,6 @@ object OrderModel {
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
@@ -468,18 +444,6 @@ object OrderModel {
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播报
@@ -518,7 +482,27 @@ object OrderModel {
abortTask()
return
}
leaveStation()
if (LineManager.endStation==null) {
OchChainLogManager.writeChainLog("滑动出发", "未设置终点坐标")
return
}
isArrivedStation = false
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()
}
/**

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

@@ -214,7 +214,7 @@ 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()

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,78 @@
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,"有任务去加载正在执行的任务")
}
}

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
@@ -58,6 +59,14 @@ object RunningTaskManager : LifecycleEventObserver{
}
}
/**
* 展示BadCase配置页面
*/
fun showSwitchLineWindow(context: Context) {
val badCaseConfigView = SwitchBizView(context)
}
override fun onStateChanged(source: LifecycleOwner, event: Event) {
}

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,129 @@
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 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
@SuppressLint("NotifyDataSetChanged")
fun setDataList(dataList: List<BusStationBean>, startStationIndex:Int) {
this.startStationIndex = startStationIndex
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
}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)
}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
}
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: AppCompatTextView = itemView.findViewById(R.id.actv_write_off_count) //此战核销的人数
}
interface LineItemClickListener {
fun onItemClick(position: Int,close:Boolean)
}
inner class MyDiffCallback(private val oldData:List<BusStationBean>, private val newData:List<BusStationBean>):
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,41 @@
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.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() {
private val TAG = TaskRunningModel::class.java.simpleName
private var viewCallback:SwtichLineViewCallback?=null
override fun onCleared() {
}
fun setDistanceCallback(viewCallback:SwtichLineViewCallback){
this.viewCallback = viewCallback
}
fun leaveStation() {
OrderModel.autoDriveToNextStation()
}
interface SwtichLineViewCallback{
}
}

View File

@@ -0,0 +1,96 @@
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.eagle.core.utilcode.mogo.view.SpacesItemDecoration
import com.mogo.och.common.module.manager.autopilot.line.LineManager
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_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 var animator:ObjectAnimator?=null
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()
}
})
}
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)
}
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)
}
}
}

View File

@@ -0,0 +1,129 @@
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
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")
}
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

@@ -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>

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,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_80000000"/>
<corners android:radius="@dimen/dp_30"/>
</shape>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android: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,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="@dimen/dp_30"/>
<solid android:color="@color/bus_color_4dffffff"/>
</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">
<corners android:radius="@dimen/dp_30"/>
<gradient android:startColor="@color/bus_color_19E6D4"
android:angle="-100"
android:endColor="@color/bus_color_198BF6"/>
</shape>

View File

@@ -364,4 +364,10 @@
app:layout_constraintStart_toStartOf="parent"
/>
<com.mogo.och.weaknet.ui.bizswitch.SwitchBizView
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:background="@color/bus_switch_line_bg"
android:id="@+id/no_order_data_view">
<ImageView
android:id="@+id/no_order_data_iv"
android:layout_width="@dimen/dp_198"
android:layout_height="@dimen/dp_158"
android:src="@drawable/shuttle_weak_empty"
android:scaleType="fitXY"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"/>
<TextView
android:id="@+id/no_order_data_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/bus_color_B3FFFFFF"
android:textSize="@dimen/dp_40"
android:gravity="center"
android:layout_marginTop="@dimen/dp_31"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="@+id/no_order_data_iv"
android:text="@string/bus_no_task"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/ll_loaing_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
tools:background="@color/bus_switch_line_bg"
android:orientation="vertical"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/loading_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="@dimen/dp_16"
android:src="@drawable/bus_switch_biz_loading_big" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_loading_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="@dimen/dp_15"
android:text="@string/bus_switch_biz_loading"
android:textColor="@color/bus_color_b3ffffff"
android:textSize="@dimen/dp_40" />
</LinearLayout>

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.AppCompatImageView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/loading_view_samll"
android:layout_width="@dimen/dp_61"
android:layout_height="@dimen/dp_60"
android:layout_marginBottom="@dimen/dp_16"
android:src="@drawable/bus_switch_biz_loading_samll" />

View File

@@ -0,0 +1,60 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_100"
tools:background="@drawable/bus_switch_line_selector">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/aciv_station_head"
android:src="@drawable/bus_switch_line_adapter_point"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="@dimen/dp_33"
android:layout_width="@dimen/dp_30"
android:layout_height="@dimen/dp_30"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/aciv_station_head_big"
android:src="@drawable/bus_switch_line_adapter_point"
app:layout_constraintTop_toTopOf="@+id/aciv_station_head"
app:layout_constraintStart_toStartOf="@+id/aciv_station_head"
app:layout_constraintBottom_toBottomOf="@+id/aciv_station_head"
app:layout_constraintEnd_toEndOf="@+id/aciv_station_head"
android:layout_width="@dimen/dp_45"
android:layout_height="@dimen/dp_45"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_station_name"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toEndOf="@+id/aciv_station_head"
android:layout_marginStart="@dimen/dp_36"
android:layout_marginEnd="@dimen/dp_36"
app:layout_constraintEnd_toStartOf="@+id/actv_write_off_count"
android:text="天安门天安门天安门…"
android:singleLine="true"
android:textColor="@color/white"
android:ellipsize="end"
android:textSize="@dimen/dp_45"
android:layout_width="0dp"
android:layout_height="wrap_content"/>
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/actv_write_off_count"
android:text="核销66人"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:textSize="@dimen/dp_36"
android:textColor="@color/white"
android:layout_marginEnd="@dimen/dp_30"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="@dimen/dp_964"
android:layout_height="@dimen/dp_1051"
xmlns:tools="http://schemas.android.com/tools"
android:background="@drawable/bus_biz_bg">
<androidx.appcompat.widget.AppCompatImageView
android:src="@drawable/bus_biz_bg_header"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="@dimen/dp_23"
android:layout_marginEnd="@dimen/dp_42"
android:layout_width="@dimen/dp_856"
android:layout_height="@dimen/dp_100"/>
<com.mogo.och.weaknet.view.LoadingViewBig
android:id="@+id/loading_biz"
android:visibility="gone"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.mogo.och.weaknet.ui.switchline.SwitchLineView
android:id="@+id/swtichLine"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="@dimen/dp_23"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.mogo.och.weaknet.ui.switchtask.SwitchTaskView
android:id="@+id/swtichTask"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="@dimen/dp_23"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<com.mogo.och.weaknet.ui.taskrunning.TaskRunningView
android:id="@+id/taskRunning"
app:layout_constraintStart_toStartOf="parent"
android:layout_marginTop="@dimen/dp_23"
android:visibility="gone"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</androidx.constraintlayout.widget.ConstraintLayout>

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