调试窗
控制中心HMI控制模块增加加速度面板
This commit is contained in:
@@ -0,0 +1,133 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.setting
|
||||
|
||||
import android.app.Activity
|
||||
import android.graphics.PixelFormat
|
||||
import android.util.DisplayMetrics
|
||||
import android.view.*
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
import com.mogo.eagle.core.data.gnss.AccelerationEntity
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
import java.lang.reflect.Field
|
||||
|
||||
/**
|
||||
* @author XuXinChao
|
||||
* @description 可拖拽实时加速度面板
|
||||
* @since: 2022/4/21
|
||||
*/
|
||||
class AccelerationFloatWindow constructor(activity: Activity) : View.OnTouchListener{
|
||||
|
||||
private var mActivity: Activity = activity
|
||||
private var mWindowParams: WindowManager.LayoutParams? = null
|
||||
private var mWindowManager: WindowManager? = null
|
||||
private lateinit var rvAccelerationList: RecyclerView
|
||||
private var accelerationListAdapter: AccelerationListAdapter?=null
|
||||
|
||||
private lateinit var mFloatLayout: View
|
||||
private var mInViewX = 0f
|
||||
private var mInViewY = 0f
|
||||
private var mDownInScreenX = 0f
|
||||
private var mDownInScreenY = 0f
|
||||
private var mInScreenX = 0f
|
||||
private var mInScreenY = 0f
|
||||
|
||||
init {
|
||||
initFloatWindow();
|
||||
}
|
||||
|
||||
private fun initFloatWindow() {
|
||||
mFloatLayout = LayoutInflater.from(mActivity).inflate(R.layout.view_acceleration_float, null) as View
|
||||
mFloatLayout.setOnTouchListener(this)
|
||||
rvAccelerationList= mFloatLayout.findViewById(R.id.rvAccelerationList)
|
||||
mWindowParams = WindowManager.LayoutParams()
|
||||
// mWindowManager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
|
||||
// if (Build.VERSION.SDK_INT >= 26) {//8.0新特性
|
||||
// mWindowParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
|
||||
// }else{
|
||||
// mWindowParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;
|
||||
// }
|
||||
mWindowManager = mActivity.windowManager
|
||||
mWindowParams?.let {
|
||||
it.format = PixelFormat.RGBA_8888
|
||||
it.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
||||
it.gravity = Gravity.START or Gravity.TOP
|
||||
it.width = 600
|
||||
it.height = WindowManager.LayoutParams.WRAP_CONTENT
|
||||
it.alpha = 0.8f
|
||||
}
|
||||
accelerationListAdapter= AccelerationListAdapter(mActivity)
|
||||
rvAccelerationList.layoutManager = LinearLayoutManager(mActivity,
|
||||
LinearLayoutManager.VERTICAL,false)
|
||||
rvAccelerationList.adapter = accelerationListAdapter
|
||||
rvAccelerationList.isNestedScrollingEnabled = false
|
||||
}
|
||||
|
||||
fun refreshData(data:List<AccelerationEntity>){
|
||||
accelerationListAdapter?.setDada(data)
|
||||
accelerationListAdapter?.notifyDataSetChanged()
|
||||
}
|
||||
|
||||
|
||||
override fun onTouch(v: View?, motionEvent: MotionEvent?): Boolean {
|
||||
when (motionEvent?.action) {
|
||||
MotionEvent.ACTION_DOWN -> {
|
||||
// 获取相对View的坐标,即以此View左上角为原点
|
||||
mInViewX = motionEvent.x
|
||||
mInViewY = motionEvent.y
|
||||
// 获取相对屏幕的坐标,即以屏幕左上角为原点
|
||||
mDownInScreenX = motionEvent.rawX
|
||||
mDownInScreenY = motionEvent.rawY - getSysBarHeight(mActivity)
|
||||
mInScreenX = motionEvent.rawX
|
||||
mInScreenY = motionEvent.rawY - getSysBarHeight(mActivity)
|
||||
}
|
||||
MotionEvent.ACTION_MOVE -> {
|
||||
// 更新浮动窗口位置参数
|
||||
mInScreenX = motionEvent.rawX
|
||||
mInScreenY = motionEvent.rawY - getSysBarHeight(mActivity)
|
||||
mWindowParams!!.x = (mInScreenX - mInViewX).toInt()
|
||||
mWindowParams!!.y = (mInScreenY - mInViewY).toInt()
|
||||
// 手指移动的时候更新小悬浮窗的位置
|
||||
mWindowManager!!.updateViewLayout(mFloatLayout, mWindowParams)
|
||||
}
|
||||
// MotionEvent.ACTION_UP -> // 如果手指离开屏幕时,xDownInScreen和xInScreen相等,且yDownInScreen和yInScreen相等,则视为触发了单击事件。
|
||||
// if (mDownInScreenX === mInScreenX && mDownInScreenY === mInScreenY) {
|
||||
// }
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun showFloatWindow() {
|
||||
if (mFloatLayout.parent == null) {
|
||||
val metrics = DisplayMetrics()
|
||||
// 默认固定位置,靠屏幕右边缘的中间
|
||||
mWindowManager!!.defaultDisplay.getMetrics(metrics)
|
||||
mWindowParams!!.x = metrics.widthPixels
|
||||
mWindowParams!!.y = metrics.heightPixels / 2 - getSysBarHeight(mActivity)
|
||||
mWindowManager!!.addView(mFloatLayout, mWindowParams)
|
||||
}
|
||||
}
|
||||
|
||||
fun hideFloatWindow() {
|
||||
if (mFloatLayout.parent != null) mWindowManager!!.removeView(mFloatLayout)
|
||||
}
|
||||
|
||||
// 获取系统状态栏高度
|
||||
private fun getSysBarHeight(activity: Activity): Int {
|
||||
val c: Class<*>
|
||||
val obj: Any
|
||||
val field: Field
|
||||
val x: Int
|
||||
var sbar = 0
|
||||
try {
|
||||
c = Class.forName("com.android.internal.R\$dimen")
|
||||
obj = c.newInstance()
|
||||
field = c.getField("status_bar_height")
|
||||
x = field.get(obj).toString().toInt()
|
||||
sbar = activity.resources.getDimensionPixelSize(x)
|
||||
} catch (e1: Exception) {
|
||||
e1.printStackTrace()
|
||||
}
|
||||
return sbar
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.setting
|
||||
|
||||
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.data.gnss.AccelerationEntity
|
||||
import com.mogo.eagle.core.function.hmi.R
|
||||
|
||||
/**
|
||||
* @author XuXinChao
|
||||
* @description 实时加速度列表适配器
|
||||
* @since: 2022/4/20
|
||||
*/
|
||||
class AccelerationListAdapter(context: Context) :
|
||||
RecyclerView.Adapter<AccelerationListAdapter.AccelerationListHolder>() {
|
||||
|
||||
private var context: Context? = context
|
||||
private var data:List<AccelerationEntity>? = null
|
||||
|
||||
fun setDada( data: List<AccelerationEntity>?){
|
||||
this.data = data
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AccelerationListHolder {
|
||||
val view = LayoutInflater.from(parent.context)
|
||||
.inflate(R.layout.item_acceleration_detail, parent, false)
|
||||
return AccelerationListHolder(view)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: AccelerationListHolder, position: Int) {
|
||||
data?.let { it ->
|
||||
val accelerationEntity = it[position]
|
||||
holder.tvMoment.text = accelerationEntity.moment
|
||||
holder.tvAcceleration.text = accelerationEntity.acceleration
|
||||
}
|
||||
}
|
||||
|
||||
override fun getItemCount() = data?.size ?: 0
|
||||
|
||||
class AccelerationListHolder(itemView: View) : RecyclerView.ViewHolder(itemView){
|
||||
var tvMoment: TextView = itemView.findViewById(R.id.tvMoment)
|
||||
var tvAcceleration: TextView = itemView.findViewById(R.id.tvAcceleration)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.mogo.eagle.core.function.hmi.ui.setting
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.graphics.Color
|
||||
import android.os.Build
|
||||
@@ -24,6 +25,7 @@ import com.mogo.eagle.core.data.constants.MoGoConfig
|
||||
import com.mogo.eagle.core.data.deva.chain.ChainConstant
|
||||
import com.mogo.eagle.core.data.deva.scene.SceneModule
|
||||
import com.mogo.eagle.core.data.enums.TrafficTypeEnum
|
||||
import com.mogo.eagle.core.data.gnss.AccelerationEntity
|
||||
import com.mogo.eagle.core.data.map.MogoLocation
|
||||
import com.mogo.eagle.core.data.obu.ObuStatusInfo
|
||||
import com.mogo.eagle.core.data.upgrade.UpgradeVersionEntity
|
||||
@@ -66,6 +68,7 @@ import mogo.telematics.pad.MessagePad
|
||||
import mogo_msg.MogoReportMsg
|
||||
import java.util.*
|
||||
import kotlin.collections.ArrayList
|
||||
import kotlin.math.abs
|
||||
|
||||
/**
|
||||
* @author xiaoyuzhou
|
||||
@@ -91,6 +94,11 @@ class DebugSettingView @JvmOverloads constructor(
|
||||
private var mAutoPilotStatusInfo: AutopilotStatusInfo? = null
|
||||
private var mGnssInfo: MessagePad.GnssInfo? = null
|
||||
|
||||
private var accelerationFloatWindow: AccelerationFloatWindow?=null
|
||||
private var accelerationList = arrayListOf<AccelerationEntity>()
|
||||
private var accelerationIsShow: Boolean = false //实时加速度面板是否展示
|
||||
private var accelerationThresholdNum: Double = 0.0
|
||||
|
||||
// 感知识别「已知类型」数据个数
|
||||
private var mIdentifyDataSize = 0
|
||||
|
||||
@@ -973,6 +981,33 @@ class DebugSettingView @JvmOverloads constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 实时加速度面板控制
|
||||
*/
|
||||
tbOpenAcceleration.setOnCheckedChangeListener { _, isChecked ->
|
||||
if(isChecked){
|
||||
//打开实时加速度面板
|
||||
accelerationFloatWindow = context?.let { AccelerationFloatWindow(it as Activity) }
|
||||
accelerationFloatWindow?.showFloatWindow()
|
||||
etThreshold.visibility = View.VISIBLE
|
||||
btnThresholdDefine.visibility = View.VISIBLE
|
||||
}else{
|
||||
//关闭实时加速度面板
|
||||
accelerationFloatWindow?.hideFloatWindow()
|
||||
etThreshold.visibility = View.GONE
|
||||
btnThresholdDefine.visibility = View.GONE
|
||||
}
|
||||
accelerationIsShow = isChecked
|
||||
}
|
||||
|
||||
btnThresholdDefine.setOnClickListener {
|
||||
try{
|
||||
accelerationThresholdNum = etThreshold.text.toString().toDouble()
|
||||
}catch(e:java.lang.Exception){
|
||||
ToastUtils.showShort("请输入正确的阈值")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1606,6 +1641,26 @@ class DebugSettingView @JvmOverloads constructor(
|
||||
|
||||
override fun onAutopilotCarStateData(gnssInfo: MessagePad.GnssInfo?) {
|
||||
mGnssInfo = gnssInfo
|
||||
//实时加速度列表
|
||||
ThreadUtils.runOnUiThread{
|
||||
if(accelerationIsShow){
|
||||
if(accelerationList.size > 9){
|
||||
accelerationList.removeLast()
|
||||
}
|
||||
gnssInfo?.acceleration?.let {
|
||||
if(accelerationList.isEmpty()){
|
||||
accelerationList.add(AccelerationEntity(TimeUtils.millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat()),it.toString()))
|
||||
}
|
||||
if(abs(it.minus(accelerationList.first().acceleration.toDouble())) > abs(accelerationThresholdNum)){
|
||||
accelerationList.add(0, AccelerationEntity(TimeUtils.millis2String(System.currentTimeMillis(),TimeUtils.getHourMinSecondFormat()),it.toString()))
|
||||
}
|
||||
|
||||
accelerationFloatWindow?.refreshData(accelerationList)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@RequiresApi(Build.VERSION_CODES.N)
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMoment"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/foreground_wtf"
|
||||
android:gravity="center_horizontal"
|
||||
/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvAcceleration"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="10dp"
|
||||
android:textColor="@color/foreground_wtf"
|
||||
android:gravity="center_horizontal"
|
||||
/>
|
||||
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="500dp"
|
||||
android:layout_height="wrap_content"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:orientation="vertical">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/icon_drag"
|
||||
android:padding="15dp"
|
||||
android:layout_gravity="center_horizontal"
|
||||
/>
|
||||
|
||||
<com.mogo.eagle.core.widget.RoundConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/dialog_bg_color"
|
||||
app:roundLayoutRadius="10dp">
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rvAccelerationList"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="5dp"
|
||||
/>
|
||||
|
||||
</com.mogo.eagle.core.widget.RoundConstraintLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1105,6 +1105,46 @@
|
||||
android:textOff="关闭「SN绑定控制」"
|
||||
android:textOn="打开「SN绑定控制」"
|
||||
android:textSize="@dimen/dp_24" />
|
||||
|
||||
<ToggleButton
|
||||
android:id="@+id/tbOpenAcceleration"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="2dp"
|
||||
android:gravity="center"
|
||||
android:textOff="打开「加速度面板」"
|
||||
android:textOn="关闭「加速度面板」"
|
||||
android:textSize="@dimen/dp_24"/>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatEditText
|
||||
android:id="@+id/etThreshold"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="2dp"
|
||||
android:paddingTop="5dp"
|
||||
android:paddingBottom="5dp"
|
||||
android:background="@drawable/debug_setting_edit_bg"
|
||||
android:gravity="center"
|
||||
android:textSize="14sp"
|
||||
android:hint="过滤阈值"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnThresholdDefine"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_columnWeight="1"
|
||||
android:layout_margin="2dp"
|
||||
android:gravity="center"
|
||||
android:text="设置加速度变化幅度过滤阈值"
|
||||
android:textSize="@dimen/dp_24"
|
||||
android:visibility="gone"
|
||||
/>
|
||||
|
||||
|
||||
</GridLayout>
|
||||
|
||||
<ToggleButton
|
||||
|
||||
Reference in New Issue
Block a user