[项目结构、扫码枪添加手机号]
This commit is contained in:
yangyakun
2024-08-08 10:44:47 +08:00
parent e519886a58
commit 579d706cbf
376 changed files with 604 additions and 1130 deletions

View File

@@ -2,8 +2,6 @@ package com.mogo.och.shuttle.bean;
import com.mogo.eagle.core.data.BaseData;
import java.util.List;
/**
* @author: wangmingjun
* @date: 2022/2/9

View File

@@ -1,9 +1,6 @@
package com.mogo.och.shuttle.model;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
import static com.mogo.och.shuttle.constant.BusConst.DELAY_10S;
import static com.mogo.och.shuttle.constant.BusConst.STATION_STATUS_ARRIVING;
import static com.mogo.och.shuttle.constant.BusConst.STATION_STATUS_STOPPED;
import android.content.Context;
import android.text.TextUtils;
@@ -12,51 +9,59 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.elegant.network.utils.GsonUtil;
import com.mogo.aicloud.services.socket.IMogoOnMessageListener;
import com.mogo.eagle.core.function.api.telematic.IReceivedMsgListener;
import com.mogo.eagle.core.function.call.telematic.CallerTelematicListenerManager;
import com.mogo.eagle.core.utilcode.util.CoordinateUtils;
import com.mogo.commons.AbsMogoApplication;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters;
import com.mogo.eagle.core.data.config.FunctionBuildConfig;
import com.mogo.eagle.core.data.map.MogoLocation;
import com.mogo.eagle.core.utilcode.util.DateTimeUtils;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener;
import com.mogo.eagle.core.function.api.telematic.IReceivedMsgListener;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotStatusListenerManager;
import com.mogo.eagle.core.function.call.telematic.CallerTelematicListenerManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.CoordinateUtils;
import com.mogo.eagle.core.utilcode.util.GsonUtils;
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
import com.mogo.eagle.core.utilcode.util.StringUtils;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.common.module.biz.login.LoginStatusManager;
import com.mogo.och.common.module.callback.OchAdasStartFailureCallback;
import com.mogo.och.common.module.constant.OchCommonConst;
import com.mogo.och.common.module.manager.autopilot.OCHAdasAbilityManager;
import com.mogo.och.common.module.manager.autopilot.autopilot.ArrivedStation;
import com.mogo.och.common.module.manager.autopilot.autopilot.OchAutoPilotManager;
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager;
import com.mogo.och.common.module.manager.autopilot.line.LineManager;
import com.mogo.och.common.module.manager.autopilot.location.OchLocationManager;
import com.mogo.och.common.module.manager.distance.TrajectoryAndDistanceManager;
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager;
import com.mogo.och.common.module.manager.socket.cloud.AbnormalFactorsLoopManager;
import com.mogo.och.common.module.manager.socket.cloud.IOchOnMessageListener;
import com.mogo.och.common.module.manager.socket.cloud.OCHSocketMessageManager;
import com.mogo.och.common.module.manager.socket.cloud.data.SystemMsg;
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager;
import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType;
import com.mogo.och.common.module.voice.VoiceNotice;
import com.mogo.och.shuttle.bean.BusRoutesResponse;
import com.mogo.och.shuttle.util.ShuttleVoiceManager;
import com.mogo.och.common.module.manager.socket.lan.bean.AppConnectMsg;
import com.mogo.och.common.module.manager.socket.lan.bean.BaseDPMsg;
import com.mogo.och.common.module.manager.socket.lan.bean.BusCacheKey;
import com.mogo.och.common.module.manager.socket.lan.bean.BusinessType;
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType;
import com.mogo.och.common.module.manager.socket.lan.bean.LoginCacheStatus;
import com.mogo.och.common.module.manager.socket.lan.bean.TaskDetailsMsg;
import com.mogo.och.common.module.biz.login.LoginStatusManager;
import com.mogo.och.common.module.manager.autopilot.autopilot.ArrivedStation;
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager;
import com.mogo.och.common.module.network.OchCommonServiceCallback;
import com.mogo.och.common.module.utils.DateTimeUtil;
import com.mogo.och.common.module.utils.MultiRequestLimitChecker;
import com.mogo.och.common.module.utils.NumberFormatUtil;
import com.mogo.och.common.module.utils.OCHThreadPoolManager;
import com.mogo.och.data.bean.BusStationBean;
import com.mogo.och.common.module.manager.socket.cloud.data.SystemMsg;
import com.mogo.och.common.module.constant.OchCommonConst;
import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener;
import com.mogo.eagle.core.function.api.autopilot.IMoGoChassisLocationGCJ02Listener;
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.GsonUtils;
import com.mogo.eagle.core.utilcode.util.NetworkUtils;
import com.mogo.eagle.core.utilcode.util.ToastUtils;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.shuttle.R;
import com.mogo.och.common.module.utils.PinYinUtil;
import com.mogo.och.common.module.voice.VoiceNotice;
import com.mogo.och.data.bean.BusRoutesResult;
import com.mogo.och.data.bean.BusStationBean;
import com.mogo.och.data.bean.BusTransferData;
import com.mogo.och.data.manager.cache.CacheDataManager;
import com.mogo.och.shuttle.R;
import com.mogo.och.shuttle.bean.BusRoutesResponse;
import com.mogo.och.shuttle.callback.IBusADASStatusCallback;
import com.mogo.och.shuttle.callback.IBusControllerStatusCallback;
import com.mogo.och.shuttle.callback.IRefreshBusStationsCallback;
@@ -66,17 +71,7 @@ import com.mogo.och.shuttle.net.OrderServiceManager;
import com.mogo.och.shuttle.util.BusAnalyticsManager;
import com.mogo.och.shuttle.util.BusSendTripInfoManager;
import com.mogo.och.shuttle.util.BusTrajectoryManager;
import com.mogo.och.common.module.manager.socket.cloud.OCHSocketMessageManager;
import com.mogo.och.common.module.network.OchCommonServiceCallback;
import com.mogo.och.common.module.callback.OchAdasStartFailureCallback;
import com.mogo.och.common.module.manager.socket.cloud.AbnormalFactorsLoopManager;
import com.mogo.och.common.module.manager.autopilot.OCHAdasAbilityManager;
import com.mogo.och.common.module.utils.DateTimeUtil;
import com.mogo.och.common.module.utils.NumberFormatUtil;
import com.mogo.och.common.module.utils.PinYinUtil;
import com.mogo.och.common.module.manager.socket.lan.bean.BusCacheKey;
import com.mogo.och.data.bean.BusTransferData;
import com.mogo.och.data.manager.cache.CacheDataManager;
import com.mogo.och.shuttle.util.ShuttleVoiceManager;
import org.jetbrains.annotations.NotNull;
@@ -451,15 +446,15 @@ public class OrderModel {
BusStationBean station = stations.get(i);
if (i == 0) { // 首发站 显示在最上面
if (station.getDrivingStatus() == STATION_STATUS_STOPPED
if (station.getDrivingStatus() == BusConst.STATION_STATUS_STOPPED
&& !station.isLeaving()) { //到达第一站
arrivingOrArrivedStationIndex = i;
break;
}
} else {
BusStationBean preStation = stations.get(i - 1);
if ((station.getDrivingStatus() == STATION_STATUS_STOPPED && !station.isLeaving())
|| (station.getDrivingStatus() == STATION_STATUS_ARRIVING
if ((station.getDrivingStatus() == BusConst.STATION_STATUS_STOPPED && !station.isLeaving())
|| (station.getDrivingStatus() == BusConst.STATION_STATUS_ARRIVING
&& preStation.isLeaving())) {
//到站未离开 | 即将到站 显示在最中间
arrivingOrArrivedStationIndex = i;
@@ -475,7 +470,7 @@ public class OrderModel {
DateTimeUtil.HH_mm);
if (arrivingOrArrivedStationIndex == 0 ||
arrivingOrArrivedStation.getDrivingStatus() == STATION_STATUS_STOPPED
arrivingOrArrivedStation.getDrivingStatus() == BusConst.STATION_STATUS_STOPPED
&& !arrivingOrArrivedStation.isLeaving()) {
if (refreshBusStationsCallback != null) {
refreshBusStationsCallback.updateBusTaskStatus(busRoutesResult.getName(), lineTime,
@@ -599,7 +594,7 @@ public class OrderModel {
bean.setDrivingStatus(currentDrivingStatus);
bean.setLeaving(isLeaving);
sites.set(currentIndex,bean);
if (currentDrivingStatus == STATION_STATUS_STOPPED && !isLeaving){
if (currentDrivingStatus == BusConst.STATION_STATUS_STOPPED && !isLeaving){
BusStationBean beanPre = sites.get(currentIndex -1);
beanPre.setDrivingStatus(BusConst.STATION_STATUS_LEAVING);
beanPre.setLeaving(false);
@@ -804,7 +799,7 @@ public class OrderModel {
.getString(R.string.bus_leave_station_tip),
nextStation),-1);
UiThreadHandler.postDelayed(()-> LanSocketManager.sendMsgToClient(startMsg),DELAY_10S);
UiThreadHandler.postDelayed(()-> LanSocketManager.sendMsgToClient(startMsg), BusConst.DELAY_10S);
}
private void sendEndTaskToClient() {
@@ -813,10 +808,6 @@ public class OrderModel {
LanSocketManager.sendMsgToClient(endMsg);
}
public void sendWriteOffNumToClient(String msg){
AppConnectMsg passengerMsg = new AppConnectMsg(false,true,msg,-1);
LanSocketManager.sendMsgToClient(passengerMsg);
}
/**
* 离站上报
@@ -885,7 +876,7 @@ public class OrderModel {
public void run() {//延迟10s播报
ShuttleVoiceManager.INSTANCE.leaveStationBus(nextStation,nextStationKr);
}
},DELAY_10S);
}, BusConst.DELAY_10S);
}
@@ -940,14 +931,14 @@ public class OrderModel {
isGoingToNextStation = true;
}
// 当前站点信息
if (s.getDrivingStatus() == STATION_STATUS_STOPPED) {
if (s.getDrivingStatus() == BusConst.STATION_STATUS_STOPPED) {
backgroundCurrentStationIndex = i;
break;
}
}
if (backgroundCurrentStationIndex == 0 &&
stationList.get(0).getDrivingStatus() == STATION_STATUS_STOPPED
stationList.get(0).getDrivingStatus() == BusConst.STATION_STATUS_STOPPED
&& !stationList.get(0).isLeaving()) { //默认是第一站到站查询
if (busRoutesResult != null) { // 第一站到站也是行程开始的时候
BusSendTripInfoManager.INSTANCE.sendBusTripInfo(BusSendTripInfoManager.START_TRIP
@@ -1022,7 +1013,7 @@ public class OrderModel {
@Override
public void run() {
if (backgroundCurrentStationIndex == 0 && stationList.get(0).getDrivingStatus() == STATION_STATUS_STOPPED
if (backgroundCurrentStationIndex == 0 && stationList.get(0).getDrivingStatus() == BusConst.STATION_STATUS_STOPPED
&& !stationList.get(0).isLeaving()){
tipStartTask("3");
}else {
@@ -1045,7 +1036,7 @@ public class OrderModel {
@Override
public void run() {
if (backgroundCurrentStationIndex == 0 && stationList != null &&
stationList.get(0).getDrivingStatus() == STATION_STATUS_STOPPED
stationList.get(0).getDrivingStatus() == BusConst.STATION_STATUS_STOPPED
&& !stationList.get(0).isLeaving()){
tipStartTask("1");
}else {

View File

@@ -1,7 +1,6 @@
package com.mogo.och.shuttle.model
import com.elegant.network.utils.GsonUtil
import com.mogo.aicloud.services.socket.IMogoOnMessageListener
import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.data.enums.EventTypeEnumNew
import com.mogo.eagle.core.data.msgbox.MsgBoxBean
@@ -14,20 +13,20 @@ import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.d
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger.i
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.eagle.core.utilcode.util.GsonUtils
import com.mogo.och.shuttle.bean.WriteOffCountResponse
import com.mogo.och.shuttle.bean.WriteOffPassenger
import com.mogo.och.shuttle.net.OrderServiceManager
import com.mogo.och.shuttle.util.ShuttleVoiceManager
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.manager.loop.LoopInfo
import com.mogo.och.common.module.manager.socket.cloud.IOchOnMessageListener
import com.mogo.och.common.module.manager.socket.cloud.OCHSocketMessageManager
import com.mogo.och.common.module.manager.socket.lan.bean.BaseDPMsg
import com.mogo.och.common.module.manager.socket.lan.bean.DPMsgType
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffDevicesMsg
import com.mogo.och.common.module.manager.socket.lan.bean.WriteOffMsg
import com.mogo.och.common.module.manager.socket.cloud.OCHSocketMessageManager
import com.mogo.och.common.module.constant.OchCommonConst
import com.mogo.och.common.module.network.OchCommonServiceCallback
import com.mogo.och.common.module.manager.loop.BizLoopManager
import com.mogo.och.common.module.manager.loop.LoopInfo
import com.mogo.och.common.module.manager.socket.cloud.IOchOnMessageListener
import com.mogo.och.shuttle.bean.WriteOffCountResponse
import com.mogo.och.shuttle.bean.WriteOffPassenger
import com.mogo.och.shuttle.net.OrderServiceManager
import com.mogo.och.shuttle.util.ShuttleVoiceManager
import io.reactivex.Observable
import io.reactivex.ObservableEmitter
import io.reactivex.ObservableOnSubscribe
@@ -139,12 +138,27 @@ object TicketModel : IReceivedMsgListener, IOchOnMessageListener<WriteOffPasseng
// writeOffMsg.orderNo?:""
// )
} else { // 核验失败
ShuttleVoiceManager.writeOffFaile("验票失败,${writeOffMsg.failedReason ?: ""}")
ShuttleVoiceManager.writeOffFaile(writeOffMsg.failedReason ?: "")
var tempPhone = writeOffMsg.phone
tempPhone?.let {
if (it.length > 8) {
//截取电话号码前三位
val phoneNumPre = it.substring(0, 3)
//截取电话号码后四位
val phoneNumFix = it.substring(7)
tempPhone = "$phoneNumPre****$phoneNumFix"
}
}
val reaseonAndPhone = if(tempPhone.isNullOrEmpty()) {
"${writeOffMsg.failedReason}"
}else{
"${writeOffMsg.failedReason};乘客:${tempPhone}"
}
saveMsgBox(
MsgBoxBean(
MsgBoxType.V2X, V2XMsg(
EventTypeEnumNew.TYPE_ABNORMAL_VERIFICATION.poiType,
writeOffMsg.failedReason ?: "",
reaseonAndPhone,
EventTypeEnumNew.TYPE_ABNORMAL_VERIFICATION.tts,
""
)
@@ -189,9 +203,9 @@ object TicketModel : IReceivedMsgListener, IOchOnMessageListener<WriteOffPasseng
private fun playPassenger(ticketSize: Int,phone:String,ticketName:String,orderNo:String) {
if (ticketSize > 1) { //多人播报 "x人" ---》x人核验通过
OrderModel.getInstance().sendWriteOffNumToClient(ticketSize.toString() + "人核验通过")
ShuttleVoiceManager.sendWriteOffNumToClient(ticketSize.toString() + "人核验通过")
} else { //是 1 播放 "滴" 2022.11.09 改为: "核验通过"
OrderModel.getInstance().sendWriteOffNumToClient("核验通过")
ShuttleVoiceManager.sendWriteOffNumToClient("核验通过")
}
ShuttleVoiceManager.writeOffCount(ticketSize)

View File

@@ -1,13 +1,10 @@
package com.mogo.och.shuttle.net;
import com.mogo.eagle.core.data.BaseData;
import com.mogo.och.shuttle.bean.BusCloseTaskRequest;
import com.mogo.och.shuttle.bean.BusOrdersResponse;
import com.mogo.och.shuttle.bean.BusQueryLineTaskResponse;
import com.mogo.och.shuttle.bean.BusQueryLinesResponse;
import com.mogo.och.shuttle.bean.BusQueryLineStationsRequest;
import com.mogo.och.shuttle.bean.BusRoutesResponse;
import com.mogo.och.shuttle.bean.QueryLeaveAwayPassengersRequest;
import com.mogo.och.shuttle.bean.QueryLeaveAwayPassengersResponse;
import com.mogo.och.shuttle.bean.BusResetDrivingLineRequest;
import com.mogo.och.shuttle.bean.BusUpdateSiteStatusRequest;
import com.mogo.och.shuttle.bean.WriteOffCountResponse;

View File

@@ -11,15 +11,12 @@ import com.mogo.och.common.module.network.OchCommonSubscribeImpl
import com.mogo.och.common.module.network.interceptor.transformIoTry
import com.mogo.och.common.module.network.interceptor.transformTry
import com.mogo.och.shuttle.bean.BusCloseTaskRequest
import com.mogo.och.shuttle.bean.BusOrdersResponse
import com.mogo.och.shuttle.bean.BusQueryLineStationsRequest
import com.mogo.och.shuttle.bean.BusQueryLineTaskResponse
import com.mogo.och.shuttle.bean.BusQueryLinesResponse
import com.mogo.och.shuttle.bean.BusResetDrivingLineRequest
import com.mogo.och.shuttle.bean.BusRoutesResponse
import com.mogo.och.shuttle.bean.BusUpdateSiteStatusRequest
import com.mogo.och.shuttle.bean.QueryLeaveAwayPassengersRequest
import com.mogo.och.shuttle.bean.QueryLeaveAwayPassengersResponse
import com.mogo.och.shuttle.bean.WriteOffCountResponse
/**

View File

@@ -1,7 +1,5 @@
package com.mogo.och.shuttle.presenter;
import android.os.Looper;
import androidx.annotation.NonNull;
import androidx.lifecycle.LifecycleOwner;

View File

@@ -15,7 +15,6 @@ 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.DateTimeUtils;
import com.mogo.eagle.core.utilcode.util.UiThreadHandler;
import com.mogo.och.common.module.biz.login.LoginStatusEnum;
import com.mogo.och.common.module.manager.autopilot.autopilot.ArrivedStation;

View File

@@ -5,8 +5,8 @@ import com.mogo.commons.AbsMogoApplication
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger
import com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant
import com.mogo.och.shuttle.R
import com.mogo.och.shuttle.model.TicketModel
import com.mogo.och.common.module.utils.RxUtils
import com.mogo.och.shuttle.model.TicketModel
import io.reactivex.Observable
import io.reactivex.Observer
import io.reactivex.android.schedulers.AndroidSchedulers

View File

@@ -26,7 +26,7 @@ public class BusAnalyticsManager extends OchAutopilotAnalytics {
}
public static BusAnalyticsManager getInstance() {
return BusAnalyticsManager.SingletonHolder.INSTANCE;
return SingletonHolder.INSTANCE;
}
@NonNull

View File

@@ -1,16 +1,18 @@
package com.mogo.och.shuttle.util;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
import androidx.annotation.Nullable;
import com.mogo.eagle.core.data.autopilot.AutopilotControlParameters;
import com.mogo.eagle.core.function.call.autopilot.CallerAutoPilotControlManager;
import com.mogo.eagle.core.utilcode.mogo.logger.CallerLogger;
import com.mogo.eagle.core.utilcode.util.GsonUtils;
import com.mogo.och.common.module.biz.login.LoginStatusManager;
import com.mogo.och.common.module.manager.logchainanalytic.OchChainLogManager;
import com.mogo.och.data.bean.BusRoutesResult;
import com.mogo.och.shuttle.constant.BusConst;
import com.mogo.och.shuttle.model.OrderModel;
import com.mogo.och.common.module.biz.login.LoginStatusManager;
import java.util.concurrent.TimeUnit;
@@ -20,8 +22,6 @@ import io.reactivex.disposables.Disposable;
import io.reactivex.schedulers.Schedulers;
import mogo_msg.MogoReportMsg;
import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_BUS;
/**
* Bus轨迹管理给MEC下发用于轨迹下载的信息
* Created on 2022/6/23
@@ -34,7 +34,7 @@ public class BusTrajectoryManager {
}
public static BusTrajectoryManager getInstance() {
return BusTrajectoryManager.SingletonHolder.INSTANCE;
return SingletonHolder.INSTANCE;
}
private AutopilotControlParameters.AutoPilotLine mAutoPilotLine = null;

View File

@@ -2,16 +2,21 @@ package com.mogo.och.shuttle.util
import com.mogo.commons.AbsMogoApplication
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.data.config.FunctionBuildConfig
import com.mogo.eagle.core.utilcode.mogo.AppIdentityModeUtils
import com.mogo.och.shuttle.R
import com.mogo.och.common.module.manager.socket.lan.LanSocketManager.sendMsgToClient
import com.mogo.och.common.module.manager.socket.lan.bean.AppConnectMsg
import com.mogo.och.common.module.voice.VoiceNotice
import com.mogo.och.shuttle.R
import com.mogo.tts.base.LangTtsEntity
import com.mogo.tts.base.LanguageType
import java.util.ArrayList
object ShuttleVoiceManager {
fun sendWriteOffNumToClient(msg: String?) {
val passengerMsg = AppConnectMsg(false, true, msg!!, -1)
sendMsgToClient(passengerMsg)
}
fun arrivedStationBus(siteNameCN: String?, siteNameKR: String?) {
val context = AbsMogoApplication.getApp()
val list: MutableList<LangTtsEntity> = ArrayList()
@@ -87,7 +92,7 @@ object ShuttleVoiceManager {
}
fun writeOffFaile(reaseon:String) {
VoiceNotice.showNotice("验票失败,${reaseon}", AIAssist.LEVEL3)
VoiceNotice.showNotice(reaseon, AIAssist.LEVEL3)
}
}

View File

@@ -1,68 +0,0 @@
<?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="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tap_p"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="P"
android:textAlignment="center"
android:textColor="@color/p_default_txt_color"
android:textSize="@dimen/dp_34"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toLeftOf="@+id/tap_r"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tap_r"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="R"
android:textAlignment="center"
android:textColor="@color/p_default_txt_color"
android:textSize="@dimen/dp_34"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/tap_p"
app:layout_constraintRight_toLeftOf="@+id/tap_n"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tap_n"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="N"
android:textAlignment="center"
android:textColor="@color/p_default_txt_color"
android:textSize="@dimen/dp_34"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/tap_r"
app:layout_constraintRight_toLeftOf="@+id/tap_d"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/tap_d"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:text="D"
android:textAlignment="center"
android:textColor="@color/p_default_txt_color"
android:textSize="@dimen/dp_34"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toRightOf="@+id/tap_n"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>