[v2.13.0][状态栏]状态窗口部分状态上移

This commit is contained in:
renwj
2022-11-23 16:56:20 +08:00
parent 4dff132dcf
commit 716b6257e4
27 changed files with 233 additions and 290 deletions

View File

@@ -17,7 +17,7 @@ import com.mogo.eagle.core.utilcode.util.*
import com.zhjt.mogo_core_function_devatools.status.entity.CanStatus
import com.zhjt.mogo_core_function_devatools.status.entity.GpsStatus
import com.zhjt.mogo_core_function_devatools.status.entity.IpcStatus
import com.zhjt.mogo_core_function_devatools.status.entity.NetStatus
//import com.zhjt.mogo_core_function_devatools.status.entity.NetStatus
import com.zhjt.mogo_core_function_devatools.status.entity.RTKStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus
@@ -26,7 +26,7 @@ import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
import com.zhjt.mogo_core_function_devatools.status.flow.can.CanImpl
import com.zhjt.mogo_core_function_devatools.status.flow.gps.GpsImpl
import com.zhjt.mogo_core_function_devatools.status.flow.ipc.IpcImpl
import com.zhjt.mogo_core_function_devatools.status.flow.nets.NetsImpl
//import com.zhjt.mogo_core_function_devatools.status.flow.nets.NetsImpl
import com.zhjt.mogo_core_function_devatools.status.flow.rtk.RTKImpl
import com.zhjt.mogo_core_function_devatools.status.flow.trace.TracingImpl
import com.zhjt.mogo_core_function_devatools.status.ui.StatusView
@@ -116,7 +116,7 @@ object StatusManager {
when (it) {
is CanStatus -> CanImpl(ctx)
is IpcStatus -> IpcImpl(ctx)
is NetStatus -> NetsImpl(ctx)
// is NetStatus -> NetsImpl(ctx)
is GpsStatus -> GpsImpl(ctx)
is TracingStatus -> TracingImpl(ctx)
is RTKStatus -> RTKImpl(ctx)

View File

@@ -37,28 +37,28 @@ class IpcStatus(val enabled: Boolean = false): Status() {
override fun isException(): Boolean = !enabled
}
class NetStatus(val enabled: Boolean = false, var name: String? = null): Status() {
override fun equals(other: Any?): Boolean {
if (javaClass != other?.javaClass) return false
other as NetStatus
if (enabled != other.enabled) return false
if (name != other.name) return false
return true
}
override fun hashCode(): Int {
var result = enabled.hashCode()
result = 31 * result + (name?.hashCode() ?: 0)
return result
}
override fun toString(): String {
return "NetStatus(enabled=$enabled, name=$name)"
}
override fun isException(): Boolean = !enabled
}
//class NetStatus(val enabled: Boolean = false, var name: String? = null): Status() {
//
// override fun equals(other: Any?): Boolean {
// if (javaClass != other?.javaClass) return false
// other as NetStatus
// if (enabled != other.enabled) return false
// if (name != other.name) return false
// return true
// }
//
// override fun hashCode(): Int {
// var result = enabled.hashCode()
// result = 31 * result + (name?.hashCode() ?: 0)
// return result
// }
//
// override fun toString(): String {
// return "NetStatus(enabled=$enabled, name=$name)"
// }
//
// override fun isException(): Boolean = !enabled
//}
/**
* android系统定位状态

View File

@@ -1,122 +1,122 @@
package com.zhjt.mogo_core_function_devatools.status.flow.nets
import android.*
import android.content.*
import android.location.*
import android.net.*
import android.net.wifi.*
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import androidx.core.location.*
import com.mogo.eagle.core.utilcode.kotlin.*
import com.mogo.eagle.core.utilcode.util.*
import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
import com.zhjt.mogo_core_function_devatools.status.entity.NetStatus
import kotlinx.coroutines.*
import java.util.concurrent.atomic.*
internal class NetsImpl(ctx: Context): IFlow<NetStatus>(ctx) {
companion object {
const val TAG = "NetsImpl"
}
private val registered = AtomicBoolean(false)
private val connectMgr by lazy {
ctx.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
}
private val wifiMgr by lazy {
ctx.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
}
private val cb = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
checkAndSend()
}
override fun onLosing(network: Network, maxMsToLive: Int) {
super.onLosing(network, maxMsToLive)
}
override fun onLost(network: Network) {
super.onLost(network)
checkAndSend()
}
override fun onUnavailable() {
super.onUnavailable()
checkAndSend()
}
override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
super.onCapabilitiesChanged(network, networkCapabilities)
checkAndSend()
}
override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
super.onLinkPropertiesChanged(network, linkProperties)
}
}
override fun onCreate() {
checkAndSend()
val builder = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
if (VERSION.SDK_INT >= VERSION_CODES.O) {
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
}
if (registered.compareAndSet(false, true)) {
connectMgr.registerNetworkCallback(builder.build(), cb)
}
}
private var loopCheckAndSendJob: Job? = null
private fun checkAndSend() {
loopCheckAndSendJob?.safeCancel()
launch(Dispatchers.Unconfined) {
val connectionInfo = wifiMgr.connectionInfo
val enabled = isNetConnected()
val name =
try {
if (isLocationEnabled()) connectionInfo.ssid?.replace(Regex("[\\W]"), "") else "WI-FI"
} catch (t: Throwable) {
t.printStackTrace()
"WI-FI"
}
send(enabled, name)
delay(1000);
checkAndSend()
}.also { loopCheckAndSendJob = it }
}
private fun isLocationEnabled() =
LocationManagerCompat.isLocationEnabled(ctx.getSystemService(Context.LOCATION_SERVICE) as LocationManager) && PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION)
private fun isNetConnected(): Boolean =
if (VERSION.SDK_INT >= VERSION_CODES.M) {
val networkCapabilities = connectMgr.getNetworkCapabilities(connectMgr.activeNetwork)
networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) ?: false
} else {
val activeNetworkInfo = connectMgr.activeNetworkInfo
activeNetworkInfo != null && activeNetworkInfo.isConnected
}
private fun send(enabled: Boolean, name: String?) {
send(NetStatus(enabled, name))
}
override fun onDestroy() {
super.onDestroy()
if (registered.compareAndSet(true, false)) {
connectMgr.unregisterNetworkCallback(cb)
}
loopCheckAndSendJob?.safeCancel()
}
}
//import android.*
//import android.content.*
//import android.location.*
//import android.net.*
//import android.net.wifi.*
//import android.os.Build.VERSION
//import android.os.Build.VERSION_CODES
//import androidx.core.location.*
//import com.mogo.eagle.core.utilcode.kotlin.*
//import com.mogo.eagle.core.utilcode.util.*
//import com.zhjt.mogo_core_function_devatools.status.flow.IFlow
//import com.zhjt.mogo_core_function_devatools.status.entity.NetStatus
//import kotlinx.coroutines.*
//import java.util.concurrent.atomic.*
//
//internal class NetsImpl(ctx: Context): IFlow<NetStatus>(ctx) {
//
// companion object {
// const val TAG = "NetsImpl"
// }
//
// private val registered = AtomicBoolean(false)
//
// private val connectMgr by lazy {
// ctx.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
// }
//
// private val wifiMgr by lazy {
// ctx.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
// }
//
// private val cb = object : ConnectivityManager.NetworkCallback() {
//
// override fun onAvailable(network: Network) {
// super.onAvailable(network)
// checkAndSend()
// }
//
// override fun onLosing(network: Network, maxMsToLive: Int) {
// super.onLosing(network, maxMsToLive)
// }
//
// override fun onLost(network: Network) {
// super.onLost(network)
// checkAndSend()
// }
//
// override fun onUnavailable() {
// super.onUnavailable()
// checkAndSend()
// }
//
// override fun onCapabilitiesChanged(network: Network, networkCapabilities: NetworkCapabilities) {
// super.onCapabilitiesChanged(network, networkCapabilities)
// checkAndSend()
// }
//
// override fun onLinkPropertiesChanged(network: Network, linkProperties: LinkProperties) {
// super.onLinkPropertiesChanged(network, linkProperties)
// }
// }
//
//
// override fun onCreate() {
// checkAndSend()
// val builder = NetworkRequest.Builder()
// .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
// if (VERSION.SDK_INT >= VERSION_CODES.O) {
// builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI_AWARE)
// }
// if (registered.compareAndSet(false, true)) {
// connectMgr.registerNetworkCallback(builder.build(), cb)
// }
// }
//
// private var loopCheckAndSendJob: Job? = null
//
// private fun checkAndSend() {
// loopCheckAndSendJob?.safeCancel()
// launch(Dispatchers.Unconfined) {
// val connectionInfo = wifiMgr.connectionInfo
// val enabled = isNetConnected()
// val name =
// try {
// if (isLocationEnabled()) connectionInfo.ssid?.replace(Regex("[\\W]"), "") else "WI-FI"
// } catch (t: Throwable) {
// t.printStackTrace()
// "WI-FI"
// }
// send(enabled, name)
// delay(1000);
// checkAndSend()
// }.also { loopCheckAndSendJob = it }
// }
//
// private fun isLocationEnabled() =
// LocationManagerCompat.isLocationEnabled(ctx.getSystemService(Context.LOCATION_SERVICE) as LocationManager) && PermissionUtils.isGranted(Manifest.permission.ACCESS_FINE_LOCATION)
//
//
// private fun isNetConnected(): Boolean =
// if (VERSION.SDK_INT >= VERSION_CODES.M) {
// val networkCapabilities = connectMgr.getNetworkCapabilities(connectMgr.activeNetwork)
// networkCapabilities?.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED) ?: false
// } else {
// val activeNetworkInfo = connectMgr.activeNetworkInfo
// activeNetworkInfo != null && activeNetworkInfo.isConnected
// }
//
// private fun send(enabled: Boolean, name: String?) {
// send(NetStatus(enabled, name))
// }
//
// override fun onDestroy() {
// super.onDestroy()
// if (registered.compareAndSet(true, false)) {
// connectMgr.unregisterNetworkCallback(cb)
// }
// loopCheckAndSendJob?.safeCancel()
// }
//}

View File

@@ -5,7 +5,7 @@ import com.mogo.eagle.core.function.call.autopilot.*
import com.zhjt.mogo_core_function_devatools.status.entity.CanStatus
import com.zhjt.mogo_core_function_devatools.status.entity.GpsStatus
import com.zhjt.mogo_core_function_devatools.status.entity.IpcStatus
import com.zhjt.mogo_core_function_devatools.status.entity.NetStatus
//import com.zhjt.mogo_core_function_devatools.status.entity.NetStatus
import com.zhjt.mogo_core_function_devatools.status.entity.RTKStatus
import com.zhjt.mogo_core_function_devatools.status.entity.Status
import com.zhjt.mogo_core_function_devatools.status.entity.TracingStatus
@@ -19,11 +19,11 @@ internal class StatusModel : ViewModel() {
const val TAG = "StatusModel"
val DEFAULTS = Pair(null, ArrayList<Status>().also {
it += RTKStatus("", -1)
it += IpcStatus(CallerAutoPilotManager.isConnected())
it += NetStatus(false)
// it += NetStatus(false)
it += CanStatus(false)
it += TracingStatus(UNKNOWN)
it += RTKStatus("", -1)
it += GpsStatus(enabled = false, isGranted = false)
})
}

View File

@@ -2,14 +2,8 @@ package com.zhjt.mogo_core_function_devatools.status.ui
import android.annotation.*
import android.content.*
import android.graphics.*
import android.graphics.drawable.*
import android.transition.*
import android.util.*
import android.view.*
import androidx.appcompat.widget.*
import androidx.constraintlayout.widget.*
import androidx.core.content.*
import androidx.lifecycle.*
import androidx.recyclerview.widget.*
import com.mogo.eagle.core.utilcode.kotlin.*
@@ -29,29 +23,16 @@ internal class StatusView(private val model: StatusModel, ctx: Context): Constra
const val TAG = "StatusView"
}
private val iv: AppCompatImageView
private val rv: RecyclerView
private val dot: View
private var observer: Observer<Pair<Status?, ArrayList<Status>>>? = null
init {
LayoutInflater.from(context).inflate(R.layout.layout_status_bar, this, true)
iv = findViewById(R.id.iv)
rv = findViewById(R.id.rv)
dot = findViewById(R.id.dot)
init()
}
private fun init() {
dot.background = shape(solid = Color.parseColor("#F33F1D"), shape = GradientDrawable.OVAL, width = 30.PX, height = 30.PX)
iv.also {
it.background = ContextCompat.getDrawable(context, R.drawable.icon_dev_status_un_fold)
it.onClick { v ->
val expand = v.tag as? Boolean ?: false
animate(expand)
v.tag = !expand
}
}
rv.also { itx ->
itx.itemAnimator?.run {
changeDuration = 0
@@ -59,25 +40,16 @@ internal class StatusView(private val model: StatusModel, ctx: Context): Constra
moveDuration = 0
removeDuration = 0
}
itx.layoutManager = GridLayoutManager(context,4, GridLayoutManager.VERTICAL, false)
itx.background = shape(solid = Color.parseColor("#80000000"), radius = 40.PX)
itx.layoutManager = LinearLayoutManager(context,LinearLayoutManager.HORIZONTAL, false)
itx.addItemDecoration(
CommonDividerItemDecoration.Builder()
.horizontalExternalSpace(38.PX)
.verticalExternalSpace(30.PX)
.verticalInnerSpace(20.PX)
.spanCountTBCare(false)
.horizontalInnerSpace(50.PX)
.horizontalInnerSpace(10.PX)
.build()
)
val adapter = model.status.value?.let { data -> StatusAdapter(context, data.second) }?.also { adapter -> itx.adapter = adapter }
adapter?.let { _ ->
model.status.observeForever(Observer<Pair<Status?, ArrayList<Status>>> { data ->
if (data.first != null) {
dot.visibility = View.VISIBLE
} else {
dot.visibility = View.INVISIBLE
}
val old = adapter.data
val result = DiffUtil.calculateDiff(StatusDiffCallback(old, data.second))
adapter.data = data.second
@@ -101,10 +73,4 @@ internal class StatusView(private val model: StatusModel, ctx: Context): Constra
}
}
}
private fun animate(expand: Boolean) {
TransitionManager.beginDelayedTransition(this, AutoTransition().setDuration(200))
rv.visibility = if (expand) View.VISIBLE else View.INVISIBLE
}
}

View File

@@ -39,9 +39,9 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
}
fun bind(status: Status) {
itemView.onClick {
ToastUtils.showShort(getText(status))
}
// itemView.onClick {
// ToastUtils.showShort(getText(status))
// }
when(status) {
is IpcStatus -> {
if (status.enabled) {
@@ -57,13 +57,13 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_can_disable)
}
}
is NetStatus -> {
if (status.enabled) {
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_net_enable)
} else {
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_net_disable)
}
}
// is NetStatus -> {
// if (status.enabled) {
// iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_net_enable)
// } else {
// iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_net_disable)
// }
// }
is GpsStatus -> {
if (status.enabled && status.isGranted) {
iv.background = ContextCompat.getDrawable(itemView.context, drawable.icon_dev_status_gps_enable)
@@ -106,7 +106,7 @@ internal class StatusAdapter(val ctx: Context, var data: ArrayList<Status>): Rec
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 NetStatus -> "WIFI:${ if (status.enabled) "${status.name}" else "非正常连接" }"
is RTKStatus -> when(status.desc) {
"RTK" ->
when(status.state) {

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.4 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.0 KiB

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@@ -8,33 +8,11 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rv"
android:layout_width="611dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toStartOf="@+id/iv"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginEnd="42dp"
android:overScrollMode="never"
app:layout_constraintBottom_toBottomOf="parent"/>
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/iv"
android:layout_width="107dp"
android:layout_height="107dp"
android:layout_marginBottom="20dp"
app:layout_constraintTop_toTopOf="parent"
android:layout_marginTop="12dp"
app:layout_constraintStart_toEndOf="@+id/rv"
app:layout_constraintEnd_toEndOf="parent"
android:background="@drawable/icon_dev_status_un_fold"/>
<View
android:id="@+id/dot"
android:layout_width="20dp"
android:layout_height="20dp"
android:layout_marginEnd="5dp"
android:layout_marginTop="5dp"
app:layout_constraintEnd_toEndOf="@+id/iv"
app:layout_constraintTop_toTopOf="@+id/iv"
android:visibility="invisible"/>
app:layout_constraintBottom_toBottomOf="parent"
android:overScrollMode="never" />
</merge>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/iv"
android:layout_width="96dp"
android:layout_height="96dp" />
android:layout_width="@dimen/dp_115"
android:layout_height="@dimen/dp_46" />