diff --git a/OCH/mogo-och-bus/build.gradle b/OCH/mogo-och-bus/build.gradle
index d2a1a0614e..91a03380a4 100644
--- a/OCH/mogo-och-bus/build.gradle
+++ b/OCH/mogo-och-bus/build.gradle
@@ -52,6 +52,8 @@ dependencies {
implementation rootProject.ext.dependencies.rxjava
implementation rootProject.ext.dependencies.rxandroid
+ implementation project(":OCH:mogo-och-common-module")
+
implementation rootProject.ext.dependencies.androidxrecyclerview
if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
implementation rootProject.ext.dependencies.mogoutils
diff --git a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java
index 33515d6cb1..441c4a28b6 100644
--- a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java
+++ b/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/model/BusOrderModel.java
@@ -46,7 +46,7 @@ import com.mogo.och.bus.net.IBusServiceCallback;
import com.mogo.och.bus.presenter.BusModelLoopManager;
import com.mogo.och.bus.util.BusAnalyticsUtil;
import com.mogo.och.bus.util.CoordinateCalculateRouteUtil;
-import com.mogo.och.bus.util.PinYinUtil;
+import com.mogo.och.common.module.utils.PinYinUtil;
import com.mogo.service.statusmanager.IMogoStatusChangedListener;
import com.mogo.service.statusmanager.StatusDescriptor;
diff --git a/OCH/mogo-och-common-module/.gitignore b/OCH/mogo-och-common-module/.gitignore
new file mode 100644
index 0000000000..42afabfd2a
--- /dev/null
+++ b/OCH/mogo-och-common-module/.gitignore
@@ -0,0 +1 @@
+/build
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/build.gradle b/OCH/mogo-och-common-module/build.gradle
new file mode 100644
index 0000000000..e00cb61887
--- /dev/null
+++ b/OCH/mogo-och-common-module/build.gradle
@@ -0,0 +1,53 @@
+apply plugin: 'com.android.library'
+apply plugin: 'kotlin-android'
+apply plugin: 'kotlin-android-extensions'
+
+android {
+ compileSdkVersion 31
+ buildToolsVersion "30.0.2"
+
+ defaultConfig {
+ minSdkVersion 23
+ targetSdkVersion 31
+ versionCode 1
+ versionName "1.0"
+
+ testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
+ consumerProguardFiles "consumer-rules.pro"
+ }
+
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+}
+
+dependencies {
+ implementation fileTree(dir: "libs", include: ["*.jar"])
+ implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
+ implementation 'androidx.core:core-ktx:1.1.0'
+ implementation 'androidx.appcompat:appcompat:1.1.0'
+ testImplementation 'junit:junit:4.12'
+ androidTestImplementation 'androidx.test.ext:junit:1.1.1'
+ androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
+ implementation rootProject.ext.dependencies.amapnavi3dmap
+
+ if (Boolean.valueOf(USE_MAVEN_PACKAGE)) {
+ implementation rootProject.ext.dependencies.mogoutils
+ implementation rootProject.ext.dependencies.mogocommons
+ implementation rootProject.ext.dependencies.modulecommon
+ implementation rootProject.ext.dependencies.mogo_core_data
+ implementation rootProject.ext.dependencies.mogo_core_function_call
+ implementation rootProject.ext.dependencies.mogo_core_function_v2x
+ }else {
+ implementation project(":core:mogo-core-utils")
+ implementation project(":foudations:mogo-commons")
+ implementation project(':modules:mogo-module-common')
+ implementation project(':core:mogo-core-data')
+ implementation project(':core:mogo-core-function-call')
+ implementation project(':core:function-impl:mogo-core-function-v2x')
+ }
+
+}
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/consumer-rules.pro b/OCH/mogo-och-common-module/consumer-rules.pro
new file mode 100644
index 0000000000..e69de29bb2
diff --git a/OCH/mogo-och-common-module/libs/pinyin4j-2.5.1.jar b/OCH/mogo-och-common-module/libs/pinyin4j-2.5.1.jar
new file mode 100644
index 0000000000..8446c53fce
Binary files /dev/null and b/OCH/mogo-och-common-module/libs/pinyin4j-2.5.1.jar differ
diff --git a/OCH/mogo-och-common-module/proguard-rules.pro b/OCH/mogo-och-common-module/proguard-rules.pro
new file mode 100644
index 0000000000..481bb43481
--- /dev/null
+++ b/OCH/mogo-och-common-module/proguard-rules.pro
@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+# http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+# public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/src/androidTest/java/com/mogo/och/common/module/ExampleInstrumentedTest.kt b/OCH/mogo-och-common-module/src/androidTest/java/com/mogo/och/common/module/ExampleInstrumentedTest.kt
new file mode 100644
index 0000000000..fbe4e2ef7f
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/androidTest/java/com/mogo/och/common/module/ExampleInstrumentedTest.kt
@@ -0,0 +1,24 @@
+package com.mogo.och.common.module
+
+import androidx.test.platform.app.InstrumentationRegistry
+import androidx.test.ext.junit.runners.AndroidJUnit4
+
+import org.junit.Test
+import org.junit.runner.RunWith
+
+import org.junit.Assert.*
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+@RunWith(AndroidJUnit4::class)
+class ExampleInstrumentedTest {
+ @Test
+ fun useAppContext() {
+ // Context of the app under test.
+ val appContext = InstrumentationRegistry.getInstrumentation().targetContext
+ assertEquals("com.mogo.och.common.module.test", appContext.packageName)
+ }
+}
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/src/main/AndroidManifest.xml b/OCH/mogo-och-common-module/src/main/AndroidManifest.xml
new file mode 100644
index 0000000000..fad19aeea9
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+ /
+
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/CommonUtilsInterface.kt b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/CommonUtilsInterface.kt
new file mode 100644
index 0000000000..c393a2cd7a
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/CommonUtilsInterface.kt
@@ -0,0 +1,9 @@
+package com.mogo.och.common.module
+
+/**
+ * @author: wangmingjun
+ * @date: 2022/4/27
+ */
+interface CommonUtilsInterface {
+
+}
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/OchCommonApi.kt b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/OchCommonApi.kt
new file mode 100644
index 0000000000..b46ad23a84
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/OchCommonApi.kt
@@ -0,0 +1,24 @@
+package com.mogo.och.common.module
+
+/**
+ * @author: wangmingjun
+ * @date: 2022/4/26
+ */
+class OchCommonApi private constructor(){
+ companion object{
+ private var instance: OchCommonApi? = null
+ get() {
+ if (field == null){
+ field = OchCommonApi();
+ }
+ return field
+ }
+ @Synchronized
+ fun get():OchCommonApi{
+ return instance!!
+ }
+ }
+
+
+
+}
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/callback/IShadow.kt b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/callback/IShadow.kt
new file mode 100644
index 0000000000..d41de5968d
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/callback/IShadow.kt
@@ -0,0 +1,65 @@
+package com.mogo.och.common.module.callback
+
+import androidx.annotation.ColorRes
+
+/**
+ * @author: wangmingjun
+ * @date: 2022/1/21
+ */
+interface IShadow {
+ //设置阴影半径
+ fun setShadowRadius(radius:Float): IShadow
+
+ //添加单位设置
+ fun setShadowRadius(unit:Int,radius: Float): IShadow
+
+ //设置应用颜色
+ fun setShadowColor(color:Int): IShadow
+
+ //设置阴影颜色资源文件id
+ fun setShadowColorRes(@ColorRes color: Int): IShadow
+ /**
+ * 设置模糊半径
+ * @param radius
+ */
+ fun setBlurRadius(radius:Float): IShadow
+
+ /**
+ *
+ * @param unit @{@link android.util.TypedValue#TYPE_DIMENSION}
+ * @param radius 模糊半径
+ */
+ fun setBlurRadius(unit:Int,radius:Float): IShadow
+
+ /**
+ * 设置水平方向的偏移量
+ * @param offset x轴偏移
+ */
+ fun setXOffset(offset:Float): IShadow
+
+
+ /**
+ * 设置x方向的偏移量,设置单位
+ * @param unit @{@link android.util.TypedValue#TYPE_DIMENSION}
+ * @param offset x轴偏移
+ */
+ fun setXOffset(unit:Int,offset:Float): IShadow
+
+ /**
+ * 设置竖直方向的偏移量
+ * @param offset y轴偏移
+ */
+ fun setYOffset(offset:Float): IShadow
+
+ /**
+ * 设置竖直方向的偏移量,带单位
+ * @param unit @{@link android.util.TypedValue#TYPE_DIMENSION}
+ * @param offset y轴偏移
+ */
+ fun setYOffset(unit:Int,offset:Float): IShadow
+
+ /**
+ * 更新绘制
+ */
+ fun commit();
+}
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/CoordinateCalculateRouteUtil.java b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/CoordinateCalculateRouteUtil.java
new file mode 100644
index 0000000000..c403c599d8
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/CoordinateCalculateRouteUtil.java
@@ -0,0 +1,164 @@
+package com.mogo.och.common.module.utils;
+
+import static com.mogo.eagle.core.utilcode.mogo.logger.scene.SceneConstant.M_TAXI;
+
+import android.content.Context;
+
+import com.amap.api.maps.CoordinateConverter;
+import com.amap.api.maps.model.LatLng;
+import com.mogo.cloud.commons.utils.CoordinateUtils;
+import com.mogo.eagle.core.utilcode.mogo.logger.Logger;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import mogo.telematics.pad.MessagePad;
+
+/**
+ * @author: wangmingjun
+ * @date: 2022/3/28
+ */
+public class CoordinateCalculateRouteUtil {
+
+ public static float calculateRouteSumLength(List points){
+ if (null == points || points.size() == 0) return 0;
+
+ float sumLength = 0;
+
+ //计算全路径总距离
+ for (int i = 0;i + 1< points.size();i++){
+ double preLat = points.get(i).latitude;
+ double preLon = points.get(i).longitude;
+ double laLat = points.get(i+1).latitude;
+ double laLon = points.get(i+1).longitude;
+
+ float length = CoordinateUtils.calculateLineDistance(laLon,laLat,preLon,preLat);
+ sumLength += length;
+ }
+ return sumLength;
+ }
+
+ public static List coordinateConverterWgsToGcjListCommon(Context mContext, List models) {
+ //转成MogoLatLng集合
+ List list = new ArrayList<>();
+ for (MessagePad.Location m : models) {
+ LatLng mogoLatLng = coordinateConverterWgsToGcj(mContext, m);
+ list.add(mogoLatLng);
+ }
+ return list;
+ }
+
+ public static LatLng coordinateConverterWgsToGcj(Context mContext, MessagePad.Location mogoLatLng) {
+ CoordinateConverter mCoordinateConverter = new CoordinateConverter(mContext);
+ mCoordinateConverter.from(CoordinateConverter.CoordType.GPS);
+ mCoordinateConverter.coord(new LatLng(mogoLatLng.getLatitude(), mogoLatLng.getLongitude()));
+ LatLng latLng = mCoordinateConverter.convert();
+ return latLng;
+ }
+
+
+ /**
+ * 根据实时定位的坐标确定出已行驶到那个坐标点 todo 有问题 暂不使用
+ * @param mRoutePoints
+ * @param realLon
+ * @param realLat
+ * @return 返回剩余路径集合
+ */
+ @Deprecated
+ public static List getCurrentPoinByCompare(List mRoutePoints,double realLon,double realLat) {
+ // 疑似坐标 先以坐标中间1/2为第一个比对点
+ int currentIndex = Math.round(mRoutePoints.size()/2);
+ LatLng currentLatLng = mRoutePoints.get(currentIndex);
+
+ //差值初始化
+ float baseDiffDis = CoordinateUtils.calculateLineDistance(realLon,realLat
+ ,currentLatLng.longitude,currentLatLng.latitude);// lon,lat, prelon, prelat
+
+ List latePoints = new ArrayList<>();
+ //与选中点左右比较
+ if (currentIndex -1 >= 0 && currentIndex+1<= mRoutePoints.size()-1){
+ LatLng leftCurrentLatLng = mRoutePoints.get(currentIndex -1);
+ LatLng rightCurentLatLng = mRoutePoints.get(currentIndex + 1);
+ float leftDiffDis = CoordinateUtils.calculateLineDistance(realLon,realLat
+ ,leftCurrentLatLng.longitude,leftCurrentLatLng.latitude);
+ float rightDiffDis = CoordinateUtils.calculateLineDistance(realLon,realLat,rightCurentLatLng.longitude,rightCurentLatLng.latitude);
+
+ if (rightDiffDis < leftDiffDis){ //靠近了右半边
+ baseDiffDis = rightDiffDis;
+ for (int i = currentIndex +1; i+1 = diff){
+ baseDiffDis = diff;
+ currentIndex = i;
+ if (i == mRoutePoints.size()-1){
+ latePoints.addAll(mRoutePoints);
+ }
+ }else {
+ latePoints.addAll(mRoutePoints.subList(currentIndex,mRoutePoints.size()-1));
+ return latePoints;
+ }
+ }
+ }else if (rightDiffDis > leftDiffDis){ //靠近左半边
+ baseDiffDis = leftDiffDis;
+ for (int j = currentIndex-1; j -1 >=0 ;j++){
+ float diff = CoordinateUtils.calculateLineDistance(realLon,realLat,mRoutePoints.get(j).longitude,mRoutePoints.get(j).latitude);
+ Logger.d(M_TAXI + "Compare左半边集合", "点:"+j+"------------baseDiffDis = "+baseDiffDis+"---diff="+diff);
+ if (baseDiffDis >= diff){
+ baseDiffDis = diff;
+ currentIndex = j;
+ if (j == 0){
+ latePoints.addAll(mRoutePoints);
+ }
+ }else {
+ latePoints.addAll(mRoutePoints.subList(currentIndex,mRoutePoints.size()-1));
+ return latePoints;
+ }
+ }
+ }else {
+ Logger.d(M_TAXI + "正好相等", "点:"+currentIndex+"------------baseDiffDis = "+baseDiffDis+"---diff="+leftDiffDis);
+ latePoints.addAll(mRoutePoints.subList(currentIndex,currentIndex));
+ return latePoints;
+ }
+ }
+ return latePoints;
+ }
+
+ /**
+ * 简单粗暴 直接比较 todo 需要优化
+ * @param mRoutePoints
+ * @param realLon
+ * @param realLat
+ * @return
+ */
+ public static List getRemainPointListByCompare(List mRoutePoints,double realLon,double realLat) {
+ List latePoints = new ArrayList<>();
+ int currentIndex = 0; //记录疑似点
+ if (mRoutePoints.size() > 0){
+ //基础点
+ LatLng baseLatLng = mRoutePoints.get(0);
+ float baseDiffDis = CoordinateUtils.calculateLineDistance(realLon,realLat
+ ,baseLatLng.longitude,baseLatLng.latitude);// lon,lat, prelon, prelat
+
+ for (int i= 1; i < mRoutePoints.size(); i++){
+ LatLng latLng = mRoutePoints.get(i);
+ float diff = CoordinateUtils.calculateLineDistance(realLon,realLat
+ ,latLng.longitude,latLng.latitude);
+ if (baseDiffDis > diff){
+// Logger.d(M_TAXI + "calculateRouteSumLength", "点:"+i+"-------先记录点----- ");
+ baseDiffDis = diff;
+ currentIndex = i;
+ }
+ }
+ Logger.d(M_TAXI + "calculateRouteSumLength", "点:"+currentIndex+"-------是最近的点------ ");
+ if (currentIndex == mRoutePoints.size()-1){
+ latePoints.add(mRoutePoints.get(currentIndex));
+ }else {
+ latePoints.addAll(mRoutePoints.subList(currentIndex,mRoutePoints.size()-1));
+ }
+ return latePoints;
+ }
+ return latePoints;
+ }
+}
diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/DateTimeUtil.kt b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/DateTimeUtil.kt
new file mode 100644
index 0000000000..e0d3749a3f
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/DateTimeUtil.kt
@@ -0,0 +1,95 @@
+package com.mogo.och.common.module.utils
+
+import com.mogo.eagle.core.utilcode.util.DateTimeUtils
+import java.math.BigDecimal
+import java.math.RoundingMode
+import java.text.SimpleDateFormat
+import java.util.*
+import kotlin.math.ceil
+
+/**
+ * @author: wangmingjun
+ * @date: 2022/4/27
+ */
+class DateTimeUtil {
+ fun formatCalendarToString(calendar: Calendar?, format: String?): String {
+ if (calendar == null) return ""
+ try {
+ val dateFormat = SimpleDateFormat(format)
+ return dateFormat.format(calendar.time)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ return ""
+ }
+
+ fun compareDateIsCurrentDay(targetCalendar: Calendar?): Boolean {
+ val currentCale = DateTimeUtils.getCurrentDateTime()
+ val currentDay = formatCalendarToString(currentCale, COMMON_yyyy_MM_dd)
+ return currentDay == formatCalendarToString(targetCalendar, COMMON_yyyy_MM_dd)
+ }
+
+ fun formatLongToCalendar(time: Long): Calendar? {
+ var calendar: Calendar? = null
+ try {
+ calendar = Calendar.getInstance()
+ calendar.timeInMillis = time
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ return calendar
+ }
+
+ fun formatLongToString(time: Long, format: String?): String? {
+ try {
+ val dateFormat = SimpleDateFormat(format)
+ return dateFormat.format(time)
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ return ""
+ }
+
+ fun getYMDTime(time: Long): String? { //格式为 2021.8.21
+ try {
+ val calendar = Calendar.getInstance()
+ calendar.timeInMillis = time
+ val month = calendar[Calendar.MONTH] + 1
+ return calendar[Calendar.YEAR].toString() + "." + month + "." + calendar[Calendar.DAY_OF_MONTH]
+ } catch (e: Exception) {
+ e.printStackTrace()
+ }
+ return ""
+ }
+
+ /**
+ *
+ * @param seconds 60
+ * @return 1 时
+ */
+ fun secondsToHourStr(seconds: Long): String? { //秒数转成相应的 小时分钟数
+ if (seconds >= 3600) {
+ val hours = seconds.toInt() / 3600
+ return hours.toString()
+ }
+ return ""
+ }
+
+ /**
+ *
+ * @param seconds 60
+ * @return 1 时
+ */
+ fun secondsToMinuteStr(seconds: Long): String? { //秒数转成相应的 小时分钟数
+ val minute = (seconds % 3600).toInt() / 60
+ return minute.toString()
+ }
+
+ companion object {
+ const val COMMON_HH_mm = "HH:mm"
+ const val COMMON_MM_dd = "MM-dd"
+ const val COMMON_MM_dd_HH_mm = "MM-dd HH:mm"
+ const val COMMON_yyyy_MM_dd = "yyyy-MM-dd"
+ const val COMMON_yyyy_MM_dd_HH_mm = "yyyy-MM-dd HH:mm"
+ }
+}
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/DimenUtil.kt b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/DimenUtil.kt
new file mode 100644
index 0000000000..23bebec7f2
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/DimenUtil.kt
@@ -0,0 +1,13 @@
+package com.mogo.och.common.module.utils
+
+import android.content.res.Resources
+
+/**
+ * @author: wangmingjun
+ * @date: 2022/1/21
+ */
+object DimenUtil{
+ fun dp2px(value:Float):Float{
+ return (0.5f + value * Resources.getSystem().displayMetrics.density)
+ }
+}
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/NumerFormatUtil.kt b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/NumerFormatUtil.kt
new file mode 100644
index 0000000000..5a1ffc118e
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/NumerFormatUtil.kt
@@ -0,0 +1,27 @@
+package com.mogo.och.common.module.utils
+
+import java.math.BigDecimal
+import java.math.RoundingMode
+import kotlin.math.ceil
+
+/**
+ * @author: wangmingjun
+ * @date: 2022/4/28
+ */
+class NumerFormatUtil {
+
+ /**
+ * 有小数两位, 没有小数保留整数
+ * @param d
+ * @param scaleInt 若有小数保留几位小数
+ * @return
+ */
+ fun formatLong(d: Double, scaleInt: Int): String? {
+ val bg = BigDecimal(d).setScale(scaleInt, RoundingMode.HALF_UP)
+ val num = bg.toDouble()
+ if (ceil(num) - num == 0.0) {
+ return (num as Long).toString()
+ }
+ return num.toString()
+ }
+}
\ No newline at end of file
diff --git a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/util/PinYinUtil.java b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/PinYinUtil.java
similarity index 95%
rename from OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/util/PinYinUtil.java
rename to OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/PinYinUtil.java
index aa826c9a68..543a898081 100644
--- a/OCH/mogo-och-bus/src/main/java/com/mogo/och/bus/util/PinYinUtil.java
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/utils/PinYinUtil.java
@@ -1,4 +1,4 @@
-package com.mogo.och.bus.util;
+package com.mogo.och.common.module.utils;
import net.sourceforge.pinyin4j.PinyinHelper;
diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/OCHBorderShadowLayout.java b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/OCHBorderShadowLayout.java
new file mode 100644
index 0000000000..3fc8ff97dd
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/OCHBorderShadowLayout.java
@@ -0,0 +1,360 @@
+package com.mogo.och.common.module.wigets;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.graphics.BlurMaskFilter;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.util.TypedValue;
+import android.widget.LinearLayout;
+
+import com.mogo.och.common.module.R;
+import com.mogo.och.common.module.callback.IShadow;
+import com.mogo.och.common.module.utils.DimenUtil;
+
+/**
+ * @author: wangmingjun
+ * @date: 2022/1/21
+ * 边框阴影
+ */
+public class OCHBorderShadowLayout extends LinearLayout {
+
+
+ private static final String TAG = "ShadowLayout";
+
+ //默认阴影半径
+ public static final float SHADOW_DEFAULT_RADIUS = DimenUtil.INSTANCE.dp2px(5);
+
+ //阴影最大偏移量
+ public static final float SHADOW_MAX_OFFSET = DimenUtil.INSTANCE.dp2px(20);
+
+ //阴影最大模糊半径
+ public static final float SHADOW_MAX_BLUR = DimenUtil.INSTANCE.dp2px(20);
+
+
+
+ //默认模糊半径
+ public static final float SHADOW_DEFAULT_BLUR_RADIUS = DimenUtil.INSTANCE.dp2px(5);
+
+
+ //阴影颜色
+ private int shadowColor = Color.parseColor("#333333");
+
+ //阴影类型,0:默认为单边 1:单边 2:邻边 3:四边所有
+ private int shadowType;
+
+ //阴影半径
+ private float shadowRadius = 0f;
+
+ //模糊度半径
+ private float blurRadius = SHADOW_DEFAULT_BLUR_RADIUS ;
+
+ //水平位移
+ private float xOffset = DimenUtil.INSTANCE.dp2px(10);
+
+
+ //竖直方向位移
+ private float yOffset = DimenUtil.INSTANCE.dp2px(10);
+
+ //背景色
+ private int bgColor = Color.WHITE;
+
+ //是否有点击效果
+ private boolean hasEffect = false ;
+
+
+ int left =0 ,right =0,top = 0,bottom = 0 ;
+
+ //代理方式
+ private IShadow shadow = new OCHBorderShadowLayout.ShadowConfig(this);
+
+ private float mWidthMode;
+ private float mHeightMode;
+ private Paint mPaint = new Paint();
+ private Paint locationPaint = new Paint();
+
+ public OCHBorderShadowLayout(Context context) {
+ super(context,null);
+ }
+
+ public OCHBorderShadowLayout(Context context, AttributeSet attrs) {
+ this(context, attrs,0);
+ }
+
+ public OCHBorderShadowLayout(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ this.setLayerType(LAYER_TYPE_SOFTWARE, null);//取消硬件加速
+ TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ShadowLayout);
+ shadowColor = typedArray.getColor(R.styleable.ShadowLayout_shadowColor, Color.BLUE);
+ blurRadius = typedArray.getDimension(R.styleable.ShadowLayout_blurRadius, SHADOW_DEFAULT_BLUR_RADIUS);
+ shadowRadius = typedArray.getDimension(R.styleable.ShadowLayout_shadowRadius,0);
+ hasEffect = typedArray.getBoolean(R.styleable.ShadowLayout_hasEffect, false);
+ xOffset = typedArray.getDimension(R.styleable.ShadowLayout_xOffset,DimenUtil.INSTANCE.dp2px(10));
+ yOffset = typedArray.getDimension(R.styleable.ShadowLayout_yOffset,DimenUtil.INSTANCE.dp2px(10));
+ bgColor = typedArray.getColor(R.styleable.ShadowLayout_bgColor,Color.WHITE);
+ typedArray.recycle();
+
+ if (shadowRadius<0){
+ shadowRadius = -shadowRadius;
+ }
+ if (blurRadius < 0) {
+ blurRadius = -blurRadius;
+ }
+
+ blurRadius = Math.min(SHADOW_MAX_BLUR,blurRadius);
+
+ if (Math.abs(xOffset)> SHADOW_MAX_OFFSET){
+ xOffset = xOffset/Math.abs(xOffset) * SHADOW_MAX_OFFSET;
+ }
+
+ if (Math.abs(yOffset) > SHADOW_MAX_OFFSET){
+ yOffset = yOffset/Math.abs(yOffset) * SHADOW_MAX_OFFSET;
+ }
+
+ init();
+ }
+
+ private void init(){
+ setBackgroundColor(Color.parseColor("#00ffffff"));
+ if (xOffset>0){
+ //水平偏移量为正数,右侧有阴影,阴影长度为blurRadius+|xOffset|
+ right = (int)(blurRadius + Math.abs(xOffset));
+ }else if (xOffset==0){
+ //水平偏移为0,水平间距为blurRadius
+ left = (int)blurRadius;
+ right = (int)blurRadius;
+ }else {
+ //水平偏移为负数,左侧有阴影,阴影长度为blurRadius+|xOffset|
+ left = (int)(blurRadius + Math.abs(xOffset));
+ }
+ if (yOffset>0){
+ //竖直偏移量为正数,底部有阴影,阴影长度为blurRadius+|yOffset|
+ bottom = (int)(blurRadius + Math.abs(yOffset));
+ }else if (yOffset==0){
+ //竖直偏移量为0,竖直间距为blurRadius
+ top = (int)blurRadius;
+ bottom = (int)blurRadius;
+ }else {
+ //竖直偏移量为负数,顶部有阴影,阴影长度为blurRadius+|yOffset|
+ top = (int)(blurRadius + Math.abs(yOffset));
+ }
+ setPadding(left,top,right,bottom);
+ }
+
+
+
+
+
+ /**
+ * 获取阴影设置
+ * @return 返回阴影设置配置
+ */
+ public IShadow getShadowConfig(){
+ return shadow;
+ }
+
+
+ @Override
+ protected void onLayout(boolean changed, int l, int t, int r, int b) {
+ super.onLayout(changed,l,t,r,b);
+ }
+
+
+ @Override
+ protected void dispatchDraw(Canvas canvas) {
+ super.dispatchDraw(canvas);
+ }
+
+
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ drawBackground(canvas);//放在super前是后景,相反是前景,前景会覆盖子布局
+ }
+
+ @Override
+ protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+ super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+ }
+
+
+
+
+ //绘制背景色(在子view底部)
+ private void drawBackground(Canvas canvas){
+
+ mWidthMode = getMeasuredWidth();
+ mHeightMode = getMeasuredHeight();
+ float startX = 0;
+ float startY = 0;
+ float endX = 0;
+ float endY = 0;
+
+ if (xOffset==0){
+ startX = right;
+ endX = mWidthMode-blurRadius;
+ }else {
+ startX = right+blurRadius;
+ endX = mWidthMode-left-blurRadius;
+ }
+
+ if (yOffset==0){
+ startY = bottom;
+ endY = mHeightMode-blurRadius;
+ }else {
+ startY = bottom+blurRadius;
+ endY = mHeightMode-top-blurRadius;
+ }
+// mPaint.setShadowLayer(blurRadius,0,0,shadowColor);
+ if (blurRadius>0){
+ mPaint.setMaskFilter(new BlurMaskFilter(blurRadius,BlurMaskFilter.Blur.NORMAL));
+ }
+ mPaint.setColor(shadowColor);
+ mPaint.setAntiAlias(true);
+
+ RectF shadowRect = new RectF(startX,startY,endX,endY);
+
+ RectF locationRectF = new RectF(left,top,mWidthMode-right,mHeightMode-bottom);
+ if (shadowRadius==0){
+ //不是圆角
+ canvas.drawRect(shadowRect,mPaint);
+ }else {
+ //圆角,角度为shadowRadius
+ canvas.drawRoundRect(shadowRect,shadowRadius,shadowRadius,mPaint);
+ }
+
+ locationPaint.setColor(bgColor);
+ locationPaint.setAntiAlias(true);
+
+ if (shadowRadius==0){
+ //不是圆角
+ canvas.drawRect(locationRectF,locationPaint);
+ }else {
+ //圆角,角度为shadowRadius
+ canvas.drawRoundRect(locationRectF,shadowRadius,shadowRadius,locationPaint);
+ }
+ }
+
+
+
+ /**
+ * 阴影配置
+ */
+ class ShadowConfig implements IShadow {
+
+ //代理
+ private OCHBorderShadowLayout shadow;
+
+ private ShadowConfig(OCHBorderShadowLayout shadow) {
+ this.shadow = shadow;
+ }
+
+ @Override
+ public IShadow setShadowRadius(float radius) {
+ return setShadowRadius(TypedValue.COMPLEX_UNIT_DIP,radius);
+ }
+
+ @Override
+ public IShadow setShadowRadius(int unit, float radius) {
+ Context c = getContext();
+ Resources r;
+
+ if (c == null) {
+ r = Resources.getSystem();
+ } else {
+ r = c.getResources();
+ }
+ shadow.shadowRadius = Math.abs(TypedValue.applyDimension(unit,radius,r.getDisplayMetrics()));
+ return this;
+ }
+
+ @Override
+ public IShadow setShadowColor(int color) {
+ shadow.shadowColor = color;
+ return this;
+ }
+
+ @Override
+ public IShadow setShadowColorRes(int colorRes) {
+ shadow.shadowColor = shadow.getResources().getColor(colorRes);
+ return this;
+ }
+
+ @Override
+ public IShadow setBlurRadius(float radius) {
+ return setBlurRadius(TypedValue.COMPLEX_UNIT_DIP,radius);
+ }
+
+ @Override
+ public IShadow setBlurRadius(int unit, float radius) {
+ Context c = getContext();
+ Resources r;
+ if (c == null) {
+ r = Resources.getSystem();
+ } else {
+ r = c.getResources();
+ }
+ shadow.blurRadius = Math.min(SHADOW_MAX_BLUR,Math.abs(TypedValue.applyDimension(unit,radius,r.getDisplayMetrics())));
+ return this;
+ }
+
+ @Override
+ public IShadow setXOffset(float offset) {
+ return setXOffset(TypedValue.COMPLEX_UNIT_DIP,offset);
+ }
+
+ @Override
+ public IShadow setXOffset(int unit, float offset) {
+ Context c = getContext();
+ Resources r;
+ if (c == null) {
+ r = Resources.getSystem();
+ } else {
+ r = c.getResources();
+ }
+
+ float x = TypedValue.applyDimension(unit,offset,r.getDisplayMetrics());
+ if (Math.abs(x)> SHADOW_MAX_OFFSET){
+ x = x/Math.abs(x) * SHADOW_MAX_OFFSET;
+ }
+ shadow.xOffset = x;
+ return this;
+ }
+
+ @Override
+ public IShadow setYOffset(float offset) {
+ return setYOffset(TypedValue.COMPLEX_UNIT_DIP,offset);
+ }
+
+ @Override
+ public IShadow setYOffset(int unit, float offset) {
+ Context c = getContext();
+ Resources r;
+ if (c == null) {
+ r = Resources.getSystem();
+ } else {
+ r = c.getResources();
+ }
+
+ float y = TypedValue.applyDimension(unit,offset,r.getDisplayMetrics());
+ if (Math.abs(y)> SHADOW_MAX_OFFSET){
+ y = y/Math.abs(y) * SHADOW_MAX_OFFSET;
+ }
+ shadow.yOffset = y;
+ return this;
+ }
+
+ @Override
+ public void commit() {
+ shadow.init();
+ shadow.requestLayout();
+ shadow.postInvalidate();
+ }
+ }
+
+
+}
diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/OCHGradientTextView.java b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/OCHGradientTextView.java
new file mode 100644
index 0000000000..41fe2c2e02
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/OCHGradientTextView.java
@@ -0,0 +1,115 @@
+package com.mogo.och.common.module.wigets;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.LinearGradient;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.Shader;
+import android.util.AttributeSet;
+
+import androidx.appcompat.widget.AppCompatTextView;
+
+/**
+ * 通用渐变文字
+ * @author: wangmingjun
+ * @date: 2022/3/22
+ */
+public class OCHGradientTextView extends AppCompatTextView {
+
+ private LinearGradient mLinearGradient;
+ private Paint mPaint;
+ private int mViewWidth = 0;//文字的宽度
+ private int mViewHeight = 0;//文字的高度
+ private Rect mTextBound = new Rect();
+ private int[] mColorList;//存放颜色的数组
+ private boolean isVertrial;//默认是横向
+
+ private float mRadius;
+ private float mdx;
+ private float mdy;
+ private int mColor;
+
+ public OCHGradientTextView(Context context) {
+ this(context, null);
+ }
+
+ public OCHGradientTextView(Context context,
+ AttributeSet attrs) {
+ super(context, attrs);
+ //设置默认的颜色
+ mColorList = new int[]{0xFFFFFFFF, 0xFFFFFFF};
+ }
+
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+
+ if (isVertrial) {
+ mViewHeight = getMeasuredHeight();
+ } else {
+ mViewWidth = getMeasuredWidth();
+ }
+ mPaint = getPaint();
+ String mTipText = getText().toString();
+
+ setStyle();
+
+ mPaint.getTextBounds(mTipText, 0, mTipText.length(), mTextBound);
+
+ mPaint.setShadowLayer(mRadius, mdx, mdy, mColor);
+
+ //画出文字
+ canvas.drawText(mTipText, getMeasuredWidth() / 2 - mTextBound.width() / 2, getMeasuredHeight() / 2 + mTextBound.height() / 2, mPaint);
+ }
+
+ /**
+ * true表示纵向渐变,false变身横向渐变
+ *
+ * @param vertrial
+ */
+ public void setVertrial(boolean vertrial) {
+ isVertrial = vertrial;
+ }
+
+ /**
+ * 设置渐变的颜色
+ *
+ * @param mColorList
+ */
+ public void setmColorList(int[] mColorList) {
+ if (mColorList != null && mColorList.length < 2) {
+ throw new RuntimeException("ClorList's length must be > 2");
+ } else {
+
+ this.mColorList = mColorList;
+ }
+ }
+
+ public void setStyle() {
+ mPaint.setAntiAlias(true);
+ mPaint.setDither(true);
+ mPaint.setFilterBitmap(true);
+ //前面4个参数分别表示渐变的开始x轴,开始y轴,结束的x轴,结束的y轴,mcolorList表示渐变的颜色数组
+ mLinearGradient = new LinearGradient(0, 0, mViewWidth, mViewHeight, mColorList, null, Shader.TileMode.CLAMP);
+ mPaint.setShader(mLinearGradient);
+ mPaint.setStrokeJoin(Paint.Join.ROUND);
+ mPaint.setStrokeCap(Paint.Cap.ROUND);
+ mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+ }
+
+ /**
+ * 设置投影层
+ * @param radius
+ * @param dx
+ * @param dy
+ * @param color
+ */
+ public void setShadowLayerCustom(float radius, float dx, float dy, int color) {
+ this.mRadius = radius;
+ this.mdx = dx;
+ this.mdy = dy;
+ this.mColor = color;
+ }
+}
+
diff --git a/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/OCHRadiusImageView.java b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/OCHRadiusImageView.java
new file mode 100644
index 0000000000..4fef3cb082
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/java/com/mogo/och/common/module/wigets/OCHRadiusImageView.java
@@ -0,0 +1,111 @@
+package com.mogo.och.common.module.wigets;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Path;
+import android.os.Build;
+import android.util.AttributeSet;
+import android.view.View;
+
+import androidx.appcompat.widget.AppCompatImageView;
+
+import com.mogo.och.common.module.R;
+
+/**
+ * 通用圆角ImageView
+ * @author: wangmingjun
+ * @date: 2021/9/29
+ */
+public class OCHRadiusImageView extends AppCompatImageView {
+ private float width, height;
+ private int defaultRadius = 0;
+ private int radius;
+ private int leftTopRadius;
+ private int rightTopRadius;
+ private int rightBottomRadius;
+ private int leftBottomRadius;
+
+
+ public OCHRadiusImageView(Context context) {
+ this(context, null);
+ init(context, null);
+ }
+
+ public OCHRadiusImageView(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ init(context, attrs);
+ }
+
+ public OCHRadiusImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ init(context, attrs);
+ }
+
+ private void init(Context context, AttributeSet attrs) {
+ if (Build.VERSION.SDK_INT < 18) {
+ setLayerType(View.LAYER_TYPE_SOFTWARE, null);
+ }
+ // 读取配置
+ TypedArray array = context.obtainStyledAttributes(attrs, R.styleable.OchRoundCornerImageView);
+ radius = array.getDimensionPixelOffset(R.styleable.OchRoundCornerImageView_och_image_radius, defaultRadius);
+ leftTopRadius = array.getDimensionPixelOffset(R.styleable.OchRoundCornerImageView_och_image_left_top_radius, defaultRadius);
+ rightTopRadius = array.getDimensionPixelOffset(R.styleable.OchRoundCornerImageView_och_image_right_top_radius, defaultRadius);
+ rightBottomRadius = array.getDimensionPixelOffset(R.styleable.OchRoundCornerImageView_och_image_right_bottom_radius, defaultRadius);
+ leftBottomRadius = array.getDimensionPixelOffset(R.styleable.OchRoundCornerImageView_och_image_left_bottom_radius, defaultRadius);
+
+
+ if (defaultRadius == leftTopRadius) {
+ leftTopRadius = radius;
+ }
+ if (defaultRadius == rightTopRadius) {
+ rightTopRadius = radius;
+ }
+ if (defaultRadius == rightBottomRadius) {
+ rightBottomRadius = radius;
+ }
+ if (defaultRadius == leftBottomRadius) {
+ leftBottomRadius = radius;
+ }
+ array.recycle();
+ }
+
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ width = getWidth();
+ height = getHeight();
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ //这里做下判断,只有图片的宽高大于设置的圆角距离的时候才进行裁剪
+ int maxLeft = Math.max(leftTopRadius, leftBottomRadius);
+ int maxRight = Math.max(rightTopRadius, rightBottomRadius);
+ int minWidth = maxLeft + maxRight;
+ int maxTop = Math.max(leftTopRadius, rightTopRadius);
+ int maxBottom = Math.max(leftBottomRadius, rightBottomRadius);
+ int minHeight = maxTop + maxBottom;
+ if (width >= minWidth && height > minHeight) {
+ Path path = new Path();
+ //右上,右下,左下,左上
+ path.moveTo(leftTopRadius, 0);
+ path.lineTo(width - rightTopRadius, 0);
+ path.quadTo(width, 0, width, rightTopRadius);
+
+ path.lineTo(width, height - rightBottomRadius);
+ path.quadTo(width, height, width - rightBottomRadius, height);
+
+ path.lineTo(leftBottomRadius, height);
+ path.quadTo(0, height, 0, height - leftBottomRadius);
+
+ path.lineTo(0, leftTopRadius);
+ path.quadTo(0, 0, leftTopRadius, 0);
+
+ canvas.clipPath(path);
+ }
+ super.onDraw(canvas);
+ }
+
+}
diff --git a/OCH/mogo-och-common-module/src/main/res/values/attrs.xml b/OCH/mogo-och-common-module/src/main/res/values/attrs.xml
new file mode 100644
index 0000000000..7e26211f11
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/main/res/values/attrs.xml
@@ -0,0 +1,29 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/OCH/mogo-och-common-module/src/test/java/com/mogo/och/common/module/ExampleUnitTest.kt b/OCH/mogo-och-common-module/src/test/java/com/mogo/och/common/module/ExampleUnitTest.kt
new file mode 100644
index 0000000000..76f5f67a00
--- /dev/null
+++ b/OCH/mogo-och-common-module/src/test/java/com/mogo/och/common/module/ExampleUnitTest.kt
@@ -0,0 +1,17 @@
+package com.mogo.och.common.module
+
+import org.junit.Test
+
+import org.junit.Assert.*
+
+/**
+ * Example local unit test, which will execute on the development machine (host).
+ *
+ * See [testing documentation](http://d.android.com/tools/testing).
+ */
+class ExampleUnitTest {
+ @Test
+ fun addition_isCorrect() {
+ assertEquals(4, 2 + 2)
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index 6b57ec55ca..f6bf16a6d6 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -84,5 +84,5 @@ include ':OCH:mogo-och-bus-passenger'
include ':OCH:mogo-och-taxi'
include ':OCH:mogo-och-taxi-passenger'
include ':OCH:mogo-och-noop'
-
+include(':OCH:mogo-och-common-module')