行车超视距功能

Signed-off-by: chenfufeng <chenfufeng@zhidaoauto.com>
This commit is contained in:
chenfufeng
2021-11-04 15:41:22 +08:00
parent fa8d6e3731
commit d73275ae37
26 changed files with 709 additions and 7 deletions

View File

@@ -8,16 +8,19 @@ import android.view.WindowManager
import android.view.animation.OvershootInterpolator
import com.mogo.commons.mvp.MvpFragment
import com.mogo.commons.voice.AIAssist
import com.mogo.eagle.core.data.camera.Camera
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
import com.mogo.eagle.core.data.notice.NoticeNormalData
import com.mogo.eagle.core.data.notice.NoticeTrafficStylePushData
import com.mogo.eagle.core.function.api.hmi.warning.IMoGoWarningStatusListener
import com.mogo.eagle.core.function.call.monitor.CallerMonitorManager
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.function.hmi.notification.WarningFloat
import com.mogo.eagle.core.function.hmi.notification.anim.DefaultAnimator
import com.mogo.eagle.core.function.hmi.notification.enums.SidePattern
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeBannerView
import com.mogo.eagle.core.function.hmi.ui.notice.NoticeFloatView
import com.mogo.eagle.core.function.hmi.ui.camera.CameraListView
import com.mogo.eagle.core.function.hmi.ui.widget.V2XNotificationView
import com.mogo.module.common.enums.EventTypeEnum
import com.mogo.utils.logger.Logger
@@ -32,9 +35,15 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
MoGoWarningContract.View {
var mWarningFloat: WarningFloat.Builder? = null
private var cameraListView: CameraListView? = null
private var cameraViewFloat: WarningFloat.Builder? = null
override fun initViews() {
ivCameraIcon.setOnClickListener {
if (cameraViewFloat == null) {
showCameraList(CallerMonitorManager.getCameraList())
}
}
}
override fun getLayoutId(): Int {
@@ -61,7 +70,6 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
viewCheckStatus.visibility = visibility
}
/**
* 展示VR下V2X预警
*
@@ -289,9 +297,80 @@ class MoGoHmiFragment : MvpFragment<MoGoWarningContract.View?, WaringPresenter?>
*/
override fun showNoticeNormal(normalData: NoticeNormalData) {
if (floatView == null) {
floatView = this.getContext()?.let { NoticeFloatView(it) }
floatView = this.context?.let { NoticeFloatView(it) }
}
floatView?.pushBeanChanged(normalData)
}
private fun showCameraList(cameraList: List<Camera>?) {
context?.let {
if (cameraViewFloat == null) {
if (cameraListView == null) {
cameraListView = CameraListView(it)
cameraListView!!.updateCameraData(cameraList)
}
cameraListView!!.setClickListener(object : CameraListView.ClickListener {
override fun onClose(v: View) {
dismissFloatView()
}
override fun onShowLive(isShow: Boolean) {
when {
isShow -> ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_selected)
else -> ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_nor)
}
}
})
cameraViewFloat = WarningFloat.with(it)
.setTag("CameraListFloat")
.setLayout(cameraListView!!)
.setSidePattern(SidePattern.RIGHT)
.setLocation(1742, 280)
.setImmersionStatusBar(true)
.setAnimator(object : DefaultAnimator() {
override fun enterAnim(
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
): Animator? =
super.enterAnim(view, params, windowManager, sidePattern)
?.apply {
interpolator = OvershootInterpolator()
}
override fun exitAnim(
view: View,
params: WindowManager.LayoutParams,
windowManager: WindowManager,
sidePattern: SidePattern
): Animator? =
super.exitAnim(view, params, windowManager, sidePattern)
?.setDuration(200)
})
.addWarningStatusListener(object : IMoGoWarningStatusListener {
override fun onDismiss() {
cameraViewFloat = null
cameraListView = null
ivCameraIcon.setBackgroundResource(R.drawable.icon_camera_nor)
}
})
.show()
} else {
cameraViewFloat?.show()
}
}
}
private fun dismissFloatView() {
cameraViewFloat?.let {
WarningFloat.dismiss(it.config.floatTag, false)
cameraViewFloat = null
cameraListView = null
}
}
override fun onDestroy() {
super.onDestroy()
}
}

View File

@@ -0,0 +1,55 @@
package com.mogo.eagle.core.function.hmi.ui.camera
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.Adapter
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.mogo.eagle.core.data.camera.Camera
import com.mogo.eagle.core.function.hmi.R
class CameraListAdapter: Adapter<CameraListAdapter.CameraListHolder> {
private var context: Context? = null
var data: List<Camera>? = null
private var clickListener: View.OnClickListener? = null
constructor(context: Context, data: List<Camera>?, clickListener: View.OnClickListener? = null) {
this.context = context
this.data = data
this.clickListener = clickListener
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CameraListHolder {
var view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_camera_info, parent, false)
return CameraListHolder(view)
}
override fun onBindViewHolder(holder: CameraListHolder, position: Int) {
data?.let {
holder.cameraInfo.text = with(it[position]) {
"${roadName}${crossingName}"
}
holder.bottomLine.visibility = if (it.size - 1 == position) View.INVISIBLE else View.VISIBLE
if (position == 0) {
// 顺义可直接查看摄像头视频的地址,用来测试
holder.itemView.tag = "https://video.zhidaohulian.com/live/origin_13_48.flv?txSecret=397b1296eb548c737871fca242ff7ec5&txTime=6AABBEB2"
} else {
holder.itemView.tag = it[position].flvUrl
}
holder.itemView.setOnClickListener(clickListener)
}
}
override fun getItemCount() = data?.size ?: 0
class CameraListHolder : ViewHolder {
var cameraInfo: TextView = itemView.findViewById(R.id.tvCameraInfo)
var bottomLine: View = itemView.findViewById(R.id.viewBottomLine)
constructor(itemView: View): super(itemView)
}
}

View File

@@ -0,0 +1,216 @@
package com.mogo.eagle.core.function.hmi.ui.camera
import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Color
import android.text.SpannableStringBuilder
import android.text.Spanned
import android.text.style.ForegroundColorSpan
import android.util.AttributeSet
import android.view.LayoutInflater
import android.view.View
import android.widget.FrameLayout
import androidx.recyclerview.widget.LinearLayoutManager
import com.mogo.eagle.core.data.camera.Camera
import com.mogo.eagle.core.function.hmi.R
import com.mogo.eagle.core.utilcode.util.ToastUtils
import com.mogo.eagle.core.widget.media.video.SimpleVideoPlayer
import com.shuyu.gsyvideoplayer.GSYVideoManager
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
import com.shuyu.gsyvideoplayer.utils.GSYVideoType
import kotlinx.android.synthetic.main.view_camera_list.view.*
import java.lang.Exception
/**
* @author ChenFufeng
* 行车超视距摄像头列表View
*/
class CameraListView : FrameLayout {
private val TAG = "CameraListView"
var cameraInfoList = ArrayList<Camera>()
private var clickListener: ClickListener? = null
private val gsyVideoOptionBuilder by lazy {
GSYVideoOptionBuilder()
}
private val spannableStringBuilder by lazy {
SpannableStringBuilder("当前设备暂无信号,切换其他摄像头 3S")
}
private val spannableStringBuilder2 by lazy {
SpannableStringBuilder("当前路口信号丢失3S 后自动关闭")
}
private var isCloseStatus = true
private val valueAnimator by lazy {
ValueAnimator.ofInt(3, 0)
}
@JvmOverloads
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : super(
context,
attrs,
defStyleAttr
)
init {
LayoutInflater.from(context).inflate(R.layout.view_camera_list, this, true)
initView()
}
private fun initView() {
rvCameraList.layoutManager =
LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
rvCameraList.adapter = CameraListAdapter(context, cameraInfoList) {
it.tag?.let { tag ->
isCloseStatus = false
showLiveView()
clickListener?.onShowLive(true)
val flvUrl = tag as String
gsyVideoOptionBuilder.setUrl(flvUrl)
.setCacheWithPlay(false)
.setAutoFullWithSize(false)
.setPlayTag(TAG).build(svpPlayer)
svpPlayer.startButton.performClick()
}
}
ivCloseIcon.setOnClickListener {
when {
isCloseStatus -> clickListener?.onClose(it)
else -> {
hideLiveView()
isCloseStatus = true
}
}
clickListener?.onShowLive(false)
}
GSYVideoType.setShowType(GSYVideoType.SCREEN_MATCH_FULL)
svpPlayer.setPlayListener(object : SimpleVideoPlayer.PlayListener {
override fun onPlayEvent(event: Int) {
when (event) {
SimpleVideoPlayer.PLAY_EVT_PLAY_LOADING -> {
}
SimpleVideoPlayer.PLAY_EVT_PLAY_BEGIN -> {
progressBar.visibility = View.GONE
}
else -> {
showNoSignalView()
valueAnimator.start()
}
}
}
})
// 后期可改为动态获取3s起始位置暂时写死
spannableStringBuilder.setSpan(
ForegroundColorSpan(Color.parseColor("#2966EE")),
spannableStringBuilder.length - 2,
spannableStringBuilder.length,
Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
)
spannableStringBuilder2.setSpan(
ForegroundColorSpan(Color.parseColor("#2966EE")),
spannableStringBuilder2.length - 8,
spannableStringBuilder2.length - 6,
Spanned.SPAN_INCLUSIVE_INCLUSIVE
)
valueAnimator.duration = 3000
valueAnimator.addUpdateListener {
when (val currentValue = it.animatedValue as Int) {
0 -> {
if (cameraInfoList.isNullOrEmpty()) {
clickListener?.onClose(ivSignalIcon)
} else {
hideNoSignalView()
}
}
else -> {
if (cameraInfoList.isNullOrEmpty()) {
spannableStringBuilder2.replace(9, 10, currentValue.toString())
tvTipContent.text = spannableStringBuilder2
} else {
spannableStringBuilder.replace(17, 18, currentValue.toString())
tvTipContent.text = spannableStringBuilder
}
}
}
}
}
fun updateCameraData(cameraInfoList: List<Camera>?) {
if (cameraInfoList.isNullOrEmpty()) {
showNoSignalView()
valueAnimator.start()
} else {
this.cameraInfoList.clear()
this.cameraInfoList.addAll(cameraInfoList)
}
}
fun setClickListener(clickListener: ClickListener) {
this.clickListener = clickListener
}
@SuppressLint("NotifyDataSetChanged")
fun refreshCameraList() {
rvCameraList.adapter?.notifyDataSetChanged()
}
override fun onAttachedToWindow() {
super.onAttachedToWindow()
}
override fun onDetachedFromWindow() {
super.onDetachedFromWindow()
stopLive()
valueAnimator.cancel()
}
private fun stopLive() {
svpPlayer.removeAllViews()
try {
GSYVideoManager.releaseAllVideos()
} catch (e: Exception) {
e.printStackTrace()
}
}
private fun showLiveView() {
tvCameraTitle.visibility = View.GONE
rvCameraList.visibility = View.GONE
svpPlayer.visibility = View.VISIBLE
progressBar.visibility = View.VISIBLE
ivCloseIcon.setBackgroundResource(R.drawable.icon_back)
}
private fun hideLiveView() {
tvCameraTitle.visibility = View.VISIBLE
rvCameraList.visibility = View.VISIBLE
svpPlayer.visibility = View.GONE
progressBar.visibility = View.GONE
stopLive()
ivCloseIcon.setBackgroundResource(R.drawable.icon_close_nor)
}
private fun showNoSignalView() {
ivSignalIcon.visibility = View.VISIBLE
tvTipContent.visibility = View.VISIBLE
tvCameraTitle.visibility = View.GONE
rvCameraList.visibility = View.GONE
svpPlayer.visibility = View.GONE
progressBar.visibility = View.GONE
}
private fun hideNoSignalView() {
ivSignalIcon.visibility = View.GONE
tvTipContent.visibility = View.GONE
hideLiveView()
clickListener?.onShowLive(false)
}
interface ClickListener {
fun onShowLive(isShow: Boolean)
fun onClose(v: View)
}
}

View File

@@ -5,6 +5,7 @@ import android.util.Log
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
import com.alibaba.android.arouter.facade.annotation.Route
import com.mogo.eagle.core.data.camera.Camera
import com.mogo.eagle.core.data.constants.MogoServicePaths
import com.mogo.eagle.core.data.enums.WarningDirectionEnum
import com.mogo.eagle.core.data.notice.NoticeNormalData

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

View File

@@ -85,5 +85,15 @@
app:layout_constraintStart_toEndOf="@+id/viewPerspectiveSwitch"
app:layout_goneMarginStart="50px" />
<ImageView
android:id="@+id/ivCameraIcon"
android:layout_width="130px"
android:layout_height="130px"
app:layout_constraintEnd_toStartOf="@id/viewTrafficLightVr"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="38px"
android:layout_marginEnd="30px"
android:background="@drawable/icon_camera_nor"
tools:visibility="visible"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="130px"
android:paddingStart="64px"
android:paddingEnd="64px"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto">
<ImageView
android:id="@+id/ivCameraIcon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/icon_rideo_nor"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
/>
<TextView
android:id="@+id/tvCameraInfo"
android:layout_width="wrap_content"
android:layout_height="53px"
app:layout_constraintStart_toEndOf="@id/ivCameraIcon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="28px"
android:maxWidth="570px"
android:singleLine="true"
android:ellipsize="end"
android:textSize="38px"
android:textColor="#FFFFFF"
tools:text="衡州大道路口大道路口道路口大衡州大道路口大道路口道路口大"
/>
<View
android:id="@+id/viewBottomLine"
android:layout_width="match_parent"
android:layout_height="1px"
app:layout_constraintBottom_toBottomOf="parent"
android:background="#6A78BB"
/>
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -0,0 +1,91 @@
<?xml version="1.0" encoding="utf-8"?>
<com.mogo.eagle.core.widget.RoundConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:roundLayoutRadius="30px"
android:minWidth="777px"
android:minHeight="485px"
android:background="@color/notice_check_dialog_bg_color">
<TextView
android:id="@+id/tvCameraTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="24px"
android:text="视频设备"
android:textColor="#FFFFFF"
android:textSize="42px"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvCameraList"
android:layout_width="778px"
android:layout_height="664px"
android:layout_marginTop="24px"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvCameraTitle" />
<ImageView
android:id="@+id/ivSignalIcon"
android:layout_width="190px"
android:layout_height="142px"
android:background="@drawable/icon_signal"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="81px"
android:visibility="gone"
/>
<TextView
android:id="@+id/tvTipContent"
android:layout_width="448px"
android:layout_height="100px"
android:text="当前设备暂无信号,切换其他摄像头 3S"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/ivSignalIcon"
android:layout_marginTop="60px"
android:gravity="center"
android:textColor="#FFFFFF"
android:textSize="36px"
android:visibility="gone"
/>
<com.mogo.eagle.core.widget.media.video.SimpleVideoPlayer
android:id="@+id/svpPlayer"
android:layout_width="778px"
android:layout_height="487px"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:visibility="gone"
/>
<androidx.core.widget.ContentLoadingProgressBar
android:id="@+id/progressBar"
style="?android:attr/progressBarStyleSmall"
android:layout_width="36dp"
android:layout_height="36dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:visibility="gone"
/>
<ImageView
android:id="@+id/ivCloseIcon"
android:layout_width="86px"
android:layout_height="86px"
android:background="@drawable/icon_close_nor"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginStart="30px"
android:layout_marginTop="17px"
/>
</com.mogo.eagle.core.widget.RoundConstraintLayout>