diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt index 387f7212b8..f483cb7346 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/DevaToolsProvider.kt @@ -11,7 +11,6 @@ import com.mogo.eagle.core.data.deva.scene.SceneModule import com.mogo.eagle.core.data.deva.scene.SceneTAG import com.mogo.eagle.core.function.api.devatools.IDevaToolsProvider import com.zhjt.mogo_core_function_devatools.badcase.BadCaseManager -import com.zhjt.mogo_core_function_devatools.feedback.FeedbackManager import com.zhjt.mogo_core_function_devatools.logcatch.MogoLogCatchManager import com.zhjt.mogo_core_function_devatools.scene.SceneManager.Companion.sceneManager import com.zhjt.mogo_core_function_devatools.status.* @@ -103,8 +102,8 @@ class DevaToolsProvider : IDevaToolsProvider { upgradeManager.downLoadPackage(mContext!!, downloadKey,downloadUrl) } - override fun showStatusBar(ctx: Context) { - StatusManager.init(ctx) + override fun showStatusBar(ctx: Context, anchor: View) { + StatusManager.init(ctx, anchor) StatusManager.show() } diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/ext/Extentions.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/ext/Extentions.kt index 64e6279d23..3246a6f238 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/ext/Extentions.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/ext/Extentions.kt @@ -144,7 +144,7 @@ fun Context.enqueuePop(content: View, width: Int, height: Int, key: String = "", @SuppressLint("ClickableViewAccessibility") -fun Context.normalPop(content: View, width: Int, height: Int, startX: Int = 0, startY: Int = 0, gravity: Int = Gravity.START, onOuterViewClicked:((focus: View) -> Unit)? = null, isFocusable: Boolean = true): () -> Unit { +fun Context.normalPop(content: View, width: Int, height: Int, startX: Int = 0, startY: Int = 0, gravity: Int = Gravity.START, onOuterViewClicked:((focus: View) -> Unit)? = null, isFocusable: Boolean = true): PopupWindow? { val activity = (this as? FragmentActivity) ?: throw IllegalStateException("please use Activity to trigger pop show.") val isImmersiveMode = BarUtils.isImmersiveMode(activity) var tempPop: PopupWindow? = null @@ -192,7 +192,7 @@ fun Context.normalPop(content: View, width: Int, height: Int, startX: Int = 0, s it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT)) } if (VERSION.SDK_INT >= VERSION_CODES.M) { - val transition = Slide(gravity).also { + val transition = Slide(if ((gravity and Gravity.START) != 0) Gravity.START else if ((gravity and Gravity.TOP) != 0) Gravity.TOP else if ((gravity and Gravity.END) != 0) Gravity.END else if ((gravity and Gravity.BOTTOM) != 0) Gravity.BOTTOM else throw AssertionError("gravity is not invalid.")).also { it.interpolator = AccelerateDecelerateInterpolator() it.duration = 200 } @@ -202,16 +202,14 @@ fun Context.normalPop(content: View, width: Int, height: Int, startX: Int = 0, s pop.contentView = content decorView.doOnAttach { try { - pop.showAtLocation(it, gravity, startX, if (isImmersiveMode) 0 else BarUtils.getStatusBarHeight() + startY) + pop.showAtLocation(it, gravity, startX, (if (isImmersiveMode) 0 else BarUtils.getStatusBarHeight()) + startY) tempPop = pop } catch (t: Throwable) { t.printStackTrace() } } } - return { - tempPop?.takeIf { it.isShowing }?.dismiss() - } + return tempPop } fun isVisibleOnPoint(content: View, x: Int, y: Int): Boolean { diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt index 649715fb79..177854b555 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/StatusManager.kt @@ -3,6 +3,7 @@ package com.zhjt.mogo_core_function_devatools.status import android.content.* import android.view.* import android.view.WindowManager.LayoutParams +import android.widget.* import androidx.core.view.* import androidx.lifecycle.* import androidx.lifecycle.Lifecycle.Event @@ -11,8 +12,7 @@ import androidx.lifecycle.Lifecycle.Event.ON_DESTROY import com.mogo.eagle.core.function.api.autopilot.IMoGoAutopilotStatusListener import com.mogo.eagle.core.function.call.autopilot.* import com.mogo.eagle.core.utilcode.kotlin.* -import com.mogo.eagle.core.utilcode.util.AppStateManager -import com.mogo.eagle.core.utilcode.util.IAppStateListener +import com.mogo.eagle.core.utilcode.util.* import com.zhjt.mogo_core_function_devatools.ext.* import com.zhjt.mogo_core_function_devatools.status.entity.CanStatus import com.zhjt.mogo_core_function_devatools.status.entity.GpsStatus @@ -41,14 +41,19 @@ object StatusManager { private lateinit var model: StatusModel - private var hidePop: (() -> Unit)? = null + private var pop: PopupWindow? = null private var timer: Job? = null private var context: WeakReference? = null + private var anchor: WeakReference? = null + private var hasInit = false + private var oldX = 0 + private var oldY = 0 + private val listener = object : IMoGoAutopilotStatusListener { override fun onAutopilotGuardian(guardianInfo: MogoReportMsg.MogoReportMessage?) { super.onAutopilotGuardian(guardianInfo) @@ -88,7 +93,7 @@ object StatusManager { } } - fun init(ctx: Context) { + fun init(ctx: Context, anchor: View) { if (hasInit) { return } @@ -106,6 +111,25 @@ object StatusManager { } }) context = WeakReference(ctx) + anchor.viewTreeObserver.addOnGlobalLayoutListener { + anchor.getLocationInWindow(IntArray(2).also { + val currentX = it[0] + val currentY = it[1] + var changed = false + if (oldX != currentX) { + oldX = currentX + changed = true + } + if (oldY != currentY) { + changed = true + oldY = currentY + } + if (changed && pop?.isShowing == true) { + pop?.update(getOffsetX(currentX), currentY + 130.PX, -1, -1) + } + }) + } + this.anchor = WeakReference(anchor) } private fun onCreate(ctx: Context) { @@ -133,20 +157,29 @@ object StatusManager { } fun show() { + val anchor = this.anchor?.get() ?: return context?.get()?.also { ctx -> - hidePop?.invoke() + pop?.takeIf { it.isShowing }?.dismiss() val content = StatusView(model, ctx) content.doOnAttach { for (f in flows) { f.onCreate() } } - ctx.normalPop(content, width = 665.PX, height = LayoutParams.WRAP_CONTENT, gravity = Gravity.END, startX = 55.PX, isFocusable = false).also { hidePop = it } + val out = IntArray(2) + anchor.getLocationInWindow(out) + ctx.normalPop(content, width = LayoutParams.WRAP_CONTENT, height = LayoutParams.WRAP_CONTENT, gravity = Gravity.END or Gravity.TOP, startX = getOffsetX(out[0]), startY = out[1] + 130.PX , isFocusable = false)?.also { + pop = it + } } } + private fun getOffsetX(anchorX: Int): Int { + return ScreenUtils.getScreenWidth() - anchorX + 40.PX + } + fun hide() { - hidePop?.invoke() + pop?.takeIf { it.isShowing }?.dismiss() } private fun onDestroy(ctx: Context) { @@ -158,6 +191,6 @@ object StatusManager { it.onDestroy() } flows.clear() - hidePop?.invoke() + pop?.takeIf { it.isShowing }?.dismiss() } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/StatusView.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/StatusView.kt index 7c9013a2dd..0adf523bb6 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/StatusView.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/StatusView.kt @@ -59,15 +59,14 @@ internal class StatusView(private val model: StatusModel, ctx: Context): Constra moveDuration = 0 removeDuration = 0 } - itx.layoutManager = GridLayoutManager(context, 3, GridLayoutManager.VERTICAL, false) + itx.layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false) itx.background = shape(solid = Color.parseColor("#80000000"), radius = 40.PX) itx.addItemDecoration( CommonDividerItemDecoration.Builder() - .horizontalExternalSpace(66.PX) - .verticalExternalSpace(60.PX) - .spanCountTBCare(false) - .verticalInnerSpace(50.PX) - .horizontalInnerSpace(116.PX) + .horizontalExternalSpace(38.PX) + .verticalExternalSpace(30.PX) + .spanCountLRCare(false) + .horizontalInnerSpace(50.PX) .build() ) val adapter = model.status.value?.let { data -> StatusAdapter(context, data.second) }?.also { adapter -> itx.adapter = adapter } @@ -92,7 +91,6 @@ internal class StatusView(private val model: StatusModel, ctx: Context): Constra } private fun animate(expand: Boolean) { - iv.animate().rotation(if (expand) 0f else -180f).setDuration(200).start() TransitionManager.beginDelayedTransition(this, AutoTransition().setDuration(200)) rv.visibility = if (expand) View.VISIBLE else View.INVISIBLE } diff --git a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/adapter/StatusAdapter.kt b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/adapter/StatusAdapter.kt index 4aa4d23e0b..c502a25195 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/adapter/StatusAdapter.kt +++ b/core/function-impl/mogo-core-function-devatools/src/main/java/com/zhjt/mogo_core_function_devatools/status/ui/adapter/StatusAdapter.kt @@ -5,7 +5,10 @@ import android.view.* import android.widget.* import androidx.core.content.* import androidx.recyclerview.widget.* +import com.mogo.eagle.core.utilcode.kotlin.* +import com.mogo.eagle.core.utilcode.util.* import com.zhjt.mogo_core_function_devatools.* +import com.zhjt.mogo_core_function_devatools.R import com.zhjt.mogo_core_function_devatools.R.drawable import com.zhjt.mogo_core_function_devatools.status.entity.* import com.zhjt.mogo_core_function_devatools.status.entity.IpcStatus @@ -30,11 +33,10 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList): Rec itemView.findViewById(R.id.iv) } - private val tv: TextView by lazy { - itemView.findViewById(R.id.tv) - } - fun bind(status: Status) { + itemView.onClick { + ToastUtils.showShort(getText(status)) + } when(status) { is IpcStatus -> { if (status.enabled) { @@ -42,7 +44,6 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList): Rec } else { iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_ipc_disable) } - tv.text = "工控机" } is CanStatus -> { if (status.enabled) { @@ -50,15 +51,12 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList): Rec } else { iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_can_disable) } - tv.text = "CAN" } is NetStatus -> { if (status.enabled) { iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_net_enable) - tv.text = status.name ?: "WI-FI" } else { iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_net_disable) - tv.text = "WI-FI" } } is GpsStatus -> { @@ -67,21 +65,17 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList): Rec } else { iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_gps_disable) } - tv.text = "GPS" } is TracingStatus -> { when(status.state) { ROUTE_FAILED, TRACK_LOAD_FAIL, TRACK_NOT_EXIST, TRACK_FINDED, UNKNOWN -> { iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_trace_unkown) - tv.text = "未知" } TRACK_LOADED -> { iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_track_enable) - tv.text = "T" } ROUTE_LOADED -> { iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_route_enable) - tv.text = "V" } } } @@ -91,9 +85,17 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList): Rec } else { iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_rtk_disable) } - tv.text = status.desc } } } + + private fun getText(status: Status): String = when(status) { + is CanStatus -> "CAN:${ if (status.enabled) "状态正常" else "非正常连接" }" + is GpsStatus -> "GPS:${ if (status.enabled) "状态正常" else "非正常连接" }" + is IpcStatus -> "工控机:${ if (status.enabled) "状态正常" else "非正常连接" }" + is NetStatus -> "WIFI:${ if (status.enabled) "${status.name}" else "非正常连接" }" + is RTKStatus -> "${status.desc.uppercase()}:${ if (status.enabled) "状态正常" else "非正常连接" }" + is TracingStatus -> "轨迹类型:${ if (status.state == TRACK_LOADED) "循迹" else if (status.state == ROUTE_LOADED) "自主算路" else "暂无轨迹" }" + } } } \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xxhdpi/icon_dev_status_un_fold.png b/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xxhdpi/icon_dev_status_un_fold.png index 5bd76829ae..290ecce308 100644 Binary files a/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xxhdpi/icon_dev_status_un_fold.png and b/core/function-impl/mogo-core-function-devatools/src/main/res/drawable-xxhdpi/icon_dev_status_un_fold.png differ diff --git a/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar.xml b/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar.xml index 4b6a95baf4..baecaea7f1 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar.xml +++ b/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar.xml @@ -8,22 +8,24 @@ + app:layout_constraintEnd_toStartOf="@+id/iv" + app:layout_constraintTop_toTopOf="parent" + android:layout_marginEnd="20px" + android:overScrollMode="never" + app:layout_constraintBottom_toBottomOf="parent"/> diff --git a/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar_item.xml b/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar_item.xml index b9e7610987..ca92ba33fc 100644 --- a/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar_item.xml +++ b/core/function-impl/mogo-core-function-devatools/src/main/res/layout/layout_status_bar_item.xml @@ -1,22 +1,5 @@ - - - - \ No newline at end of file + \ No newline at end of file diff --git a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt index 2697ddad0f..aa21b0bfd5 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt +++ b/core/function-impl/mogo-core-function-hmi/src/main/java/com/mogo/eagle/core/function/hmi/ui/MoGoHmiFragment.kt @@ -205,9 +205,8 @@ import java.util.* setProxyTrafficLightView(viewTrafficLightVr) setProxyLimitingSpeedView(viewLimitingVelocity) setViewNotificationProvider(this) - context?.also { - CallerDevaToolsManager.showStatusBar(it) + CallerDevaToolsManager.showStatusBar(it, vs_status_bar) } } @@ -1226,7 +1225,7 @@ import java.util.* } override fun hideSmallFragment() { - context?.let { CallerDevaToolsManager.showStatusBar(it) } + context?.let { CallerDevaToolsManager.showStatusBar(it, vs_status_bar) } val fragmentOverview = ARouter.getInstance().build(MoGoFragmentPaths.PATH_FRAGMENT_OVERVIEW) .navigation() as BaseFragment activity?.supportFragmentManager?.beginTransaction() diff --git a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml index e0bc4f03fd..ed3b74663e 100644 --- a/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml +++ b/core/function-impl/mogo-core-function-hmi/src/main/res/layout/fragment_hmi.xml @@ -112,23 +112,21 @@ android:id="@+id/ivBadCaseTools" android:layout_width="120px" android:layout_height="120px" - android:src="@drawable/bad_case_selector" - app:layout_constraintBottom_toBottomOf="parent" - app:layout_constraintStart_toEndOf="@id/ivToolsIcon" android:layout_marginStart="50px" android:layout_marginBottom="40px" - /> + android:src="@drawable/bad_case_selector" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/ivToolsIcon" /> + android:src="@drawable/ai_collect_selector" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintStart_toEndOf="@id/ivBadCaseTools" /> - + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintStart_toStartOf="parent" /> + diff --git a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt index df8eb59c45..fcbafafc21 100644 --- a/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt +++ b/core/mogo-core-function-api/src/main/java/com/mogo/eagle/core/function/api/devatools/IDevaToolsProvider.kt @@ -107,7 +107,7 @@ interface IDevaToolsProvider : IProvider { /** * 展示状态栏 */ - fun showStatusBar(ctx: Context) + fun showStatusBar(ctx: Context, anchor: View) /** * 隐藏状态栏 diff --git a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt index f4baa19770..509a611781 100644 --- a/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt +++ b/core/mogo-core-function-call/src/main/java/com/mogo/eagle/core/function/call/devatools/CallerDevaToolsManager.kt @@ -2,7 +2,7 @@ package com.mogo.eagle.core.function.call.devatools import android.app.Activity import android.content.Context -import android.view.View +import android.view.* import com.mogo.eagle.core.data.config.* import com.mogo.eagle.core.data.constants.MogoServicePaths import com.mogo.eagle.core.data.deva.chain.ChainLogParam @@ -150,9 +150,18 @@ object CallerDevaToolsManager { /** * 展示状态栏 */ - fun showStatusBar(ctx: Context) { + fun showStatusBar(ctx: Context, anchor: View) { if (!AppIdentityModeUtils.isPassenger(FunctionBuildConfig.appIdentityMode)) { - devaToolsProviderApi?.showStatusBar(ctx) + if (anchor.isLaidOut) { + devaToolsProviderApi?.showStatusBar(ctx, anchor) + } else { + anchor.viewTreeObserver.addOnGlobalLayoutListener(object : ViewTreeObserver.OnGlobalLayoutListener { + override fun onGlobalLayout() { + devaToolsProviderApi?.showStatusBar(ctx, anchor) + anchor.viewTreeObserver.removeOnGlobalLayoutListener(this) + } + }) + } } }