map和直播页面改版
@@ -30,7 +30,7 @@ android {
|
||||
targetSdkVersion 35
|
||||
versionCode 2101
|
||||
// versionName "2.1.1"
|
||||
versionName "2.1.1-Beta2"
|
||||
versionName "2.1.1-Beta4"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
|
||||
@@ -391,6 +391,10 @@
|
||||
android:name=".ui.activity.map.LiveActivityV2"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".ui.activity.map.LiveActivityV3"
|
||||
android:exported="false"
|
||||
android:screenOrientation="portrait" />
|
||||
<activity
|
||||
android:name=".ui.activity.data.MoreSleepActivity"
|
||||
android:exported="false"
|
||||
|
||||
@@ -34,7 +34,10 @@ data class MapDeviceBean(
|
||||
var fences: MutableList<FencesBean>?,
|
||||
var wifiZones: MutableList<WiFiZoneBean>?,
|
||||
var startTime: String,
|
||||
var endTime: String
|
||||
var endTime: String,
|
||||
var canShowBattery: Boolean,
|
||||
var isCloseBattery: Boolean,
|
||||
var isCloseMsg: Boolean
|
||||
) : Parcelable {
|
||||
constructor() : this(
|
||||
"",
|
||||
@@ -65,6 +68,9 @@ data class MapDeviceBean(
|
||||
null,
|
||||
null,
|
||||
"",
|
||||
""
|
||||
"",
|
||||
false,
|
||||
false,
|
||||
false
|
||||
)
|
||||
}
|
||||
|
||||
@@ -102,6 +102,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
||||
private val mBleReportManage: BleReportManage by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||
mSocketUtilManage = SocketUtilManage()
|
||||
mSocketUtilManage?.initEasySocket(mContext)
|
||||
LogUtil.e("创建Socket连接")
|
||||
BleReportManage(mSocketSendMessageViewModel, mSocketUtilManage!!)
|
||||
}
|
||||
|
||||
@@ -222,8 +223,13 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
||||
XEventBus.observe(this, EventName.ConnectDeviceState) { ble: BleTrackDeviceBean ->
|
||||
getPet(false)?.apply {
|
||||
//蓝牙连接断开上传日志
|
||||
if (ble.mac == macID && ble.conState == ConState.DISCONNECTED) {
|
||||
mLogBleReportViewModel.uploadLog(mContext, macID)
|
||||
if (ble.mac == macID) {
|
||||
if (ble.conState == ConState.CONNECTED) {
|
||||
//蓝牙连接就去连接socket
|
||||
mBleReportManage.dealBleReportData(macID, null)
|
||||
} else {
|
||||
mLogBleReportViewModel.uploadLog(mContext, macID)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -338,7 +344,6 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
||||
getPet(false)?.apply {
|
||||
mLogBleReportViewModel.uploadLog(mContext, macID)
|
||||
}
|
||||
(mFragments[2] as MapV3Fragment).showPetNameAndHead(mSelectPetPosition)
|
||||
} else {
|
||||
onChangeClick(mSelectPetPosition)
|
||||
when (mViewBinding.homeV2ViewPager2.currentItem) {
|
||||
@@ -364,6 +369,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
||||
}
|
||||
}
|
||||
}
|
||||
(mFragments[2] as MapV3Fragment).showPetNameAndHead(mSelectPetPosition)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,7 +412,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
||||
* 选择宠物弹窗
|
||||
*/
|
||||
fun selectPetDialog() {
|
||||
if (isRequestPetData && mPetList.size == 0) {
|
||||
if (mPetList.size == 0) {
|
||||
showToast(R.string.no_bind_pet)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
package com.abbidot.tracker.ui.common.map
|
||||
|
||||
import android.content.Context
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import com.abbidot.baselibrary.constant.MMKVKey
|
||||
import com.abbidot.baselibrary.util.AppUtils
|
||||
import com.abbidot.baselibrary.util.MMKVUtil
|
||||
import com.abbidot.tracker.base.BaseMapCommon
|
||||
import com.abbidot.tracker.bean.HistoryDataBean
|
||||
import com.abbidot.tracker.bean.MapDeviceBean
|
||||
import com.abbidot.tracker.constant.ConstantInt
|
||||
import com.abbidot.tracker.databinding.LayoutPetLocationInfoBinding
|
||||
import com.abbidot.tracker.ui.fragment.map.baidumap.HomeMapBaiduMapFragment
|
||||
import com.abbidot.tracker.ui.fragment.map.googlemap.HomeMapGoogleMapFragmentV3
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
*Created by .yzq on 2022/7/5/005.
|
||||
* @link
|
||||
* @description:
|
||||
*/
|
||||
class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() {
|
||||
|
||||
private var mHomeMapGoogleMapFragment: HomeMapGoogleMapFragmentV3? = null
|
||||
private var mHomeMapBaiduMapFragment: HomeMapBaiduMapFragment? = null
|
||||
|
||||
fun getMapFragment(
|
||||
context: Context,
|
||||
locationLayoutViewBinding: LayoutPetLocationInfoBinding,
|
||||
deviceBatteryLayout: ViewGroup,
|
||||
petAddressTimeFormat: String,
|
||||
mapLoadOk: () -> Unit
|
||||
): Fragment {
|
||||
return if (AppUtils.isChina(AppUtils.SWITCH_MAP_TYPE)) {
|
||||
mHomeMapBaiduMapFragment = HomeMapBaiduMapFragment.newInstance(context, mapLoadOk)
|
||||
mHomeMapBaiduMapFragment!!
|
||||
} else {
|
||||
mHomeMapGoogleMapFragment = HomeMapGoogleMapFragmentV3.newInstance(
|
||||
context,
|
||||
locationLayoutViewBinding,
|
||||
deviceBatteryLayout,
|
||||
petAddressTimeFormat,
|
||||
mapLoadOk
|
||||
)
|
||||
mHomeMapGoogleMapFragment!!
|
||||
}
|
||||
}
|
||||
|
||||
fun setMapDeviceBean(mapDeviceBean: MapDeviceBean?) {
|
||||
if (null != mHomeMapBaiduMapFragment) {
|
||||
mHomeMapBaiduMapFragment!!.setMapDeviceBean(mapDeviceBean)
|
||||
} else if (null != mHomeMapGoogleMapFragment) {
|
||||
mHomeMapGoogleMapFragment!!.setMapDeviceBean(mapDeviceBean)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始每隔几秒刷新用户位置
|
||||
*/
|
||||
fun startRefreshUserLocation() {
|
||||
if (isMapLoadOk()) startRefreshUserLocation(
|
||||
mHomeMapBaiduMapFragment, mHomeMapGoogleMapFragment
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取宠物反编译好的位置信息
|
||||
*/
|
||||
fun getDecPetAddressData(): HistoryDataBean? {
|
||||
if (null != mHomeMapBaiduMapFragment) {
|
||||
return mHomeMapBaiduMapFragment!!.mDecPetAddressData
|
||||
} else if (null != mHomeMapGoogleMapFragment) {
|
||||
return mHomeMapGoogleMapFragment!!.mDecPetAddressData
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun clearMarker() {
|
||||
if (null != mHomeMapBaiduMapFragment) {
|
||||
mHomeMapBaiduMapFragment!!.mBaiduMap?.clear()
|
||||
} else if (null != mHomeMapGoogleMapFragment) {
|
||||
mHomeMapGoogleMapFragment!!.clearAllMarker()
|
||||
}
|
||||
}
|
||||
|
||||
fun refreshPetCurrentLocation(latitude: Double, longitude: Double, isMoveCamera: Boolean) {
|
||||
if (null != mHomeMapBaiduMapFragment) {
|
||||
mHomeMapBaiduMapFragment?.apply {
|
||||
refreshPetCurrentLocation(
|
||||
latitude, longitude, isMoveCamera
|
||||
)
|
||||
}
|
||||
} else if (null != mHomeMapGoogleMapFragment) {
|
||||
MMKVUtil.putDouble(MMKVKey.MapShowDefaultLat, latitude)
|
||||
MMKVUtil.putDouble(MMKVKey.MapShowDefaultLon, longitude)
|
||||
mHomeMapGoogleMapFragment?.apply {
|
||||
refreshPetCurrentLocation(
|
||||
LatLng(latitude, longitude), needMoveCamera = isMoveCamera
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 重新设置宠物头像
|
||||
*/
|
||||
fun setPetHeadIcon(imageUrl: String, petType: Int) {
|
||||
if (null != mHomeMapBaiduMapFragment) {
|
||||
mHomeMapBaiduMapFragment!!.setPetHeadIconUrl(imageUrl)
|
||||
} else if (null != mHomeMapGoogleMapFragment) {
|
||||
mHomeMapGoogleMapFragment!!.setPetHeadIconUrl(imageUrl, petType)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 地图是否加载好了,准备好了
|
||||
*/
|
||||
fun isMapLoadOk() = isMapLoadOk(mHomeMapBaiduMapFragment, mHomeMapGoogleMapFragment)
|
||||
|
||||
/**
|
||||
* 切换地图类型
|
||||
*/
|
||||
fun switchSatelliteAndNormalMapType() {
|
||||
switchSatelliteAndNormalMapType(mHomeMapBaiduMapFragment, mHomeMapGoogleMapFragment)
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换用户和宠物的位置居中显示
|
||||
*/
|
||||
fun switchShowLocation(@ConstantInt type: Int) {
|
||||
switchShowLocationType(type, mHomeMapBaiduMapFragment, mHomeMapGoogleMapFragment)
|
||||
}
|
||||
|
||||
/**
|
||||
* 画轨迹线
|
||||
*/
|
||||
fun addTrackLine(latitude: Double, longitude: Double) {
|
||||
if (null != mHomeMapBaiduMapFragment) {
|
||||
mHomeMapBaiduMapFragment!!.addLine(latitude, longitude)
|
||||
} else if (null != mHomeMapGoogleMapFragment) {
|
||||
mHomeMapGoogleMapFragment!!.addLine(LatLng(latitude, longitude))
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 画轨迹线
|
||||
*/
|
||||
fun addTrackLines(trackList: MutableList<HistoryDataBean>) {
|
||||
if (null != mHomeMapBaiduMapFragment) {
|
||||
} else if (null != mHomeMapGoogleMapFragment) {
|
||||
mHomeMapGoogleMapFragment!!.addLines(trackList)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算用户和宠物的距离
|
||||
*/
|
||||
fun getUserAndPetDistance(): Double {
|
||||
var distance = 0.0
|
||||
if (null != mHomeMapBaiduMapFragment) {
|
||||
distance = mHomeMapBaiduMapFragment!!.getUserAndPetDistance()
|
||||
} else if (null != mHomeMapGoogleMapFragment) {
|
||||
distance = mHomeMapGoogleMapFragment!!.getUserAndPetDistance()
|
||||
}
|
||||
return distance
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始水波纹动画
|
||||
*/
|
||||
fun startRippleCircleAnim() {
|
||||
if (null != mHomeMapBaiduMapFragment) {
|
||||
} else if (null != mHomeMapGoogleMapFragment) {
|
||||
mHomeMapGoogleMapFragment!!.startRippleCircleAnim()
|
||||
}
|
||||
}
|
||||
|
||||
fun greenRippleCircleAnim() {
|
||||
mHomeMapGoogleMapFragment?.greenRippleCircleAnim()
|
||||
}
|
||||
|
||||
fun setMarkerInfoViewOffset() {
|
||||
if (null != mHomeMapBaiduMapFragment) {
|
||||
} else if (null != mHomeMapGoogleMapFragment) {
|
||||
mHomeMapGoogleMapFragment!!.setMarkerInfoViewOffset()
|
||||
}
|
||||
}
|
||||
|
||||
// fun getAddressShowMarkerInfoWindow(historyDataBean: HistoryDataBean) {
|
||||
// if (null != mHomeMapBaiduMapFragment) {
|
||||
// mHomeMapBaiduMapFragment!!.showMarkerInfoWindow(historyDataBean)
|
||||
// } else if (null != mHomeMapGoogleMapFragment) {
|
||||
// mHomeMapGoogleMapFragment!!.showMarkerInfoWindow(historyDataBean)
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -18,8 +18,8 @@ import com.abbidot.baselibrary.list.BaseRecyclerAdapter
|
||||
import com.abbidot.baselibrary.util.AppUtils
|
||||
import com.abbidot.baselibrary.util.LogUtil
|
||||
import com.abbidot.baselibrary.util.MMKVUtil
|
||||
import com.abbidot.baselibrary.util.Utils
|
||||
import com.abbidot.tracker.R
|
||||
import com.abbidot.tracker.adapter.HomeMapDeviceMsgAdapter
|
||||
import com.abbidot.tracker.adapter.HomeMapDeviceStateAdapter
|
||||
import com.abbidot.tracker.base.BaseDialog
|
||||
import com.abbidot.tracker.base.BaseFragment
|
||||
@@ -37,15 +37,14 @@ import com.abbidot.tracker.dialog.CommonDialog1
|
||||
import com.abbidot.tracker.dialog.SelectMapTypeDialog
|
||||
import com.abbidot.tracker.ui.activity.HomeV2Activity
|
||||
import com.abbidot.tracker.ui.activity.device.MyTrackerV2Activity
|
||||
import com.abbidot.tracker.ui.activity.map.LiveActivityV2
|
||||
import com.abbidot.tracker.ui.common.map.HomeMapCommon
|
||||
import com.abbidot.tracker.ui.activity.map.LiveActivityV3
|
||||
import com.abbidot.tracker.ui.common.map.HomeMapCommonV3
|
||||
import com.abbidot.tracker.util.Util
|
||||
import com.abbidot.tracker.util.ViewUtil
|
||||
import com.abbidot.tracker.util.bluetooth.SRBleUtil
|
||||
import com.abbidot.tracker.vm.FamilyViewModel
|
||||
import com.abbidot.tracker.vm.FencesMapViewModel
|
||||
import com.abbidot.tracker.vm.MapViewModel
|
||||
import com.abbidot.tracker.widget.MapDeviceNetView
|
||||
import com.clj.fastble.BleManager
|
||||
import com.hjq.permissions.XXPermissions
|
||||
import com.hjq.permissions.permission.PermissionLists
|
||||
@@ -74,14 +73,14 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
private var mCurrentShowPetPos = -1
|
||||
|
||||
@Inject
|
||||
lateinit var mHomeMapCommon: HomeMapCommon
|
||||
lateinit var mHomeMapCommon: HomeMapCommonV3
|
||||
private lateinit var mFragment: Fragment
|
||||
private var mMapDeviceBean: MapDeviceBean? = null
|
||||
|
||||
private lateinit var mDeviceStateList: MutableList<DataBean>
|
||||
private lateinit var mDeviceStateAdapter: HomeMapDeviceStateAdapter
|
||||
private lateinit var mDeviceMsgList: MutableList<DataBean>
|
||||
private lateinit var mDeviceMsgAdapter: HomeMapDeviceMsgAdapter
|
||||
// private lateinit var mDeviceMsgList: MutableList<DataBean>
|
||||
// private lateinit var mDeviceMsgAdapter: HomeMapDeviceMsgAdapter
|
||||
|
||||
//启动移动地图摄像机
|
||||
private var isMoveCamera = true
|
||||
@@ -113,7 +112,10 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
rlHomeMapTopLayout, WindowInsetsCompat.Type.statusBars()
|
||||
)
|
||||
mFragment = mHomeMapCommon.getMapFragment(
|
||||
mContext!!, miHomeMapAddressView, MapDeviceNetView(mContext!!)
|
||||
mContext!!,
|
||||
ilHomeMapPetLocation,
|
||||
llHomeMapDeviceBatteryLayout,
|
||||
Utils.DATE_FORMAT_PATTERN_EN11
|
||||
) { mapLoadOk() }
|
||||
|
||||
llHomeMapTopPet.ivTopPetBtnSmall.setImageResource(R.drawable.icon_map_type)
|
||||
@@ -123,17 +125,16 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
)
|
||||
|
||||
mDeviceStateList = mutableListOf()
|
||||
mDeviceMsgList = mutableListOf()
|
||||
mMapViewModel.addDeviceDefaultStateData(mContext!!, mDeviceStateList)
|
||||
mDeviceStateAdapter = HomeMapDeviceStateAdapter(mContext!!, mDeviceStateList)
|
||||
ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
|
||||
mContext!!, rvHomeMapDeviceState, mDeviceStateAdapter, bottom = 10
|
||||
)
|
||||
|
||||
mDeviceMsgAdapter = HomeMapDeviceMsgAdapter(mContext!!, mDeviceMsgList)
|
||||
ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
|
||||
mContext!!, rvHomeMapDeviceMsg, mDeviceMsgAdapter, bottom = 10
|
||||
)
|
||||
// mDeviceMsgAdapter = HomeMapDeviceMsgAdapter(mContext!!, mDeviceMsgList)
|
||||
// ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
|
||||
// mContext!!, rvHomeMapDeviceMsg, mDeviceMsgAdapter, bottom = 10
|
||||
// )
|
||||
|
||||
setOnClickListenerViews(
|
||||
homeMapRefreshBtn,
|
||||
@@ -141,7 +142,9 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
homeMapLiveBtn,
|
||||
llHomeMapTopPet.ivTopPetBtnSmall,
|
||||
llHomeMapTopPet.homeDataPetNameSmall,
|
||||
llHomeMapTopPet.homeDataPetHeadSmall.root
|
||||
llHomeMapTopPet.homeDataPetHeadSmall.root,
|
||||
ilHomeMapDeviceBatteryLayout.ivDeviceCloseBtn,
|
||||
ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn
|
||||
)
|
||||
|
||||
if (AppUtils.isDebug()) {
|
||||
@@ -230,17 +233,22 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
override fun onResult(any: Any) {
|
||||
val data = it.getOrNull()
|
||||
data?.apply {
|
||||
mMapDeviceBean?.let { m ->
|
||||
data.isCloseMsg = m.isCloseMsg
|
||||
data.isCloseBattery = m.isCloseBattery
|
||||
data.canShowBattery = m.canShowBattery
|
||||
}
|
||||
mMapDeviceBean = data
|
||||
setMapData(data)
|
||||
mMapViewModel.setDeviceStateAndWarningData(
|
||||
mContext!!,
|
||||
getHomeV2Activity()?.getPet(),
|
||||
data,
|
||||
mViewBinding.ilHomeMapDeviceMsg.root,
|
||||
mViewBinding.ilHomeMapDeviceMsg.tvDeviceMsgContent,
|
||||
mViewBinding.ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn,
|
||||
mDeviceStateList,
|
||||
mDeviceStateAdapter,
|
||||
mDeviceMsgList,
|
||||
mDeviceMsgAdapter,
|
||||
mViewBinding.rvHomeMapDeviceMsg
|
||||
mDeviceStateAdapter
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -288,11 +296,26 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
//接收蓝牙连接状态
|
||||
XEventBus.observe(this, EventName.ConnectDeviceState) { trackBle: BleTrackDeviceBean ->
|
||||
getHomeV2Activity()?.getPet(false)?.apply {
|
||||
//蓝牙断开就重新获取服务器数据,蓝牙数据上报断开
|
||||
if (trackBle.mac == macID && trackBle.conState != ConState.CONNECTED) {
|
||||
//隐藏蓝牙nearby
|
||||
mViewBinding.rvHomeMapDeviceMsg.visibility = View.GONE
|
||||
updateMapDeviceStatus()
|
||||
if (trackBle.mac == macID) {
|
||||
if (trackBle.conState == ConState.CONNECTED) {
|
||||
mMapDeviceBean?.let {
|
||||
mMapViewModel.setDeviceStateAndWarningData(
|
||||
mContext!!,
|
||||
getHomeV2Activity()?.getPet(),
|
||||
it,
|
||||
mViewBinding.ilHomeMapDeviceMsg.root,
|
||||
mViewBinding.ilHomeMapDeviceMsg.tvDeviceMsgContent,
|
||||
mViewBinding.ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn,
|
||||
mDeviceStateList,
|
||||
mDeviceStateAdapter
|
||||
)
|
||||
}
|
||||
} else {
|
||||
//隐藏蓝牙nearby
|
||||
mViewBinding.ilHomeMapDeviceMsg.root.visibility = View.GONE
|
||||
//蓝牙断开就重新获取服务器数据,蓝牙数据上报断开
|
||||
updateMapDeviceStatus()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -314,26 +337,24 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
it.longitude = location.longitude
|
||||
it.latitude = location.latitude
|
||||
}
|
||||
mHomeMapCommon.setMapDeviceBean(mMapDeviceBean)
|
||||
setMapDeviceBean(it)
|
||||
mHomeMapCommon.refreshPetCurrentLocation(
|
||||
it.latitude, it.longitude, isMoveCamera
|
||||
)
|
||||
mHomeMapCommon.startRefreshUserLocation()
|
||||
}
|
||||
ViewUtil.instance.viewShow(mViewBinding.homeMapLiveBtn)
|
||||
mMapViewModel.setDeviceStateAndWarningData(
|
||||
mContext!!,
|
||||
getHomeV2Activity()?.getPet(),
|
||||
it,
|
||||
mViewBinding.ilHomeMapDeviceMsg.root,
|
||||
mViewBinding.ilHomeMapDeviceMsg.tvDeviceMsgContent,
|
||||
mViewBinding.ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn,
|
||||
mDeviceStateList,
|
||||
mDeviceStateAdapter
|
||||
)
|
||||
}
|
||||
|
||||
mViewBinding.homeMapLiveBtn.visibility = View.VISIBLE
|
||||
|
||||
mMapViewModel.setDeviceStateAndWarningData(
|
||||
mContext!!,
|
||||
getHomeV2Activity()?.getPet(),
|
||||
mMapDeviceBean!!,
|
||||
mDeviceStateList,
|
||||
mDeviceStateAdapter,
|
||||
mDeviceMsgList,
|
||||
mDeviceMsgAdapter,
|
||||
mViewBinding.rvHomeMapDeviceMsg
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -438,10 +459,6 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
private fun updateMapDeviceStatus(
|
||||
isNeedCountDown: Boolean = true, useBleLocation: Boolean = false
|
||||
) {
|
||||
// mShowCenterLocationType = ConstantInt.PetLocationType
|
||||
// ViewUtil.instance.setMapSwitchLocationButtonImage(
|
||||
// mViewBinding.homeMapRefreshBtn, mShowCenterLocationType
|
||||
// )
|
||||
getHomeV2Activity()?.apply {
|
||||
if (mPetList.size <= mCurrentShowPetPos) return
|
||||
getPet()?.apply {
|
||||
@@ -531,8 +548,12 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
if (mHomeMapCommon.isMapLoadOk()) {
|
||||
isMoveCamera = true
|
||||
mHomeMapCommon.clearMarker()
|
||||
mViewBinding.miHomeMapAddressView.visibility = View.GONE
|
||||
mViewBinding.rvHomeMapDeviceMsg.visibility = View.GONE
|
||||
mMapDeviceBean?.let {
|
||||
it.isCloseMsg = false
|
||||
it.isCloseBattery = false
|
||||
it.canShowBattery = false
|
||||
}
|
||||
mViewBinding.ilHomeMapDeviceMsg.root.visibility = View.GONE
|
||||
showLoading(true)
|
||||
val pet = mPetList[position]
|
||||
//重新设置地图宠物头像
|
||||
@@ -555,7 +576,7 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
if (Util.isTimeoutReport(updateTime) || powerSwitch == ConstantInt.Type0 || powerSwitch == ConstantInt.Type2 || inWifiZone == ConstantInt.Type1) View.GONE
|
||||
else View.VISIBLE
|
||||
|
||||
mHomeMapCommon.setMapDeviceBean(this)
|
||||
setMapDeviceBean(this)
|
||||
//设置循环查询时间间隔 30秒
|
||||
mMapViewModel.updateMillisInFuture(0.5f)
|
||||
|
||||
@@ -565,10 +586,6 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
}
|
||||
}
|
||||
|
||||
// mShowCenterLocationType = ConstantInt.PetLocationType
|
||||
// ViewUtil.instance.setMapSwitchLocationButtonImage(
|
||||
// mViewBinding.homeMapRefreshBtn, mShowCenterLocationType
|
||||
// )
|
||||
mHomeMapCommon.refreshPetCurrentLocation(latitude, longitude, isMoveCamera)
|
||||
mHomeMapCommon.startRefreshUserLocation()
|
||||
|
||||
@@ -576,6 +593,22 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
}
|
||||
}
|
||||
|
||||
private fun setMapDeviceBean(mapDeviceBean: MapDeviceBean) {
|
||||
mapDeviceBean.apply {
|
||||
mViewBinding.ilHomeMapDeviceBatteryLayout.let {
|
||||
mMapViewModel.setMapDeviceBattery(
|
||||
mContext!!, mapDeviceBean, it.root, it.tvDeviceBatteryInfo, it.ivDeviceCloseBtn
|
||||
)
|
||||
}
|
||||
mViewBinding.ilHomeMapPetLocation.let {
|
||||
mMapViewModel.setPetLocationReverseGeocode(
|
||||
mContext!!, mapDeviceBean, it.root, it.tvPetLocationReverseGeocode
|
||||
)
|
||||
}
|
||||
mHomeMapCommon.setMapDeviceBean(this)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查获取定位,蓝牙权限
|
||||
*/
|
||||
@@ -591,7 +624,7 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
} else {
|
||||
getPet()?.apply {
|
||||
mViewBinding.homeMapLiveBtn.isEnabled = false
|
||||
val intent = Intent(mContext, LiveActivityV2::class.java)
|
||||
val intent = Intent(mContext, LiveActivityV3::class.java)
|
||||
intent.putExtra(ConstantString.JumpActivity, true)
|
||||
intent.putExtra(ConstantString.Pet, this)
|
||||
startActivity(intent)
|
||||
@@ -605,7 +638,7 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
} else {
|
||||
getPet()?.apply {
|
||||
mViewBinding.homeMapBluetoothBtn.isEnabled = false
|
||||
val intent = Intent(mContext, LiveActivityV2::class.java)
|
||||
val intent = Intent(mContext, LiveActivityV3::class.java)
|
||||
intent.putExtra(ConstantString.JumpActivity, false)
|
||||
intent.putExtra(ConstantString.Pet, this)
|
||||
startActivity(intent)
|
||||
@@ -644,7 +677,7 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
getHomeV2Activity()?.let {
|
||||
it.getPet()?.apply {
|
||||
mViewBinding.homeMapLiveBtn.isEnabled = false
|
||||
val intent = Intent(mContext, LiveActivityV2::class.java)
|
||||
val intent = Intent(mContext, LiveActivityV3::class.java)
|
||||
intent.putExtra(ConstantString.JumpActivity, true)
|
||||
intent.putExtra(ConstantString.Pet, this)
|
||||
startActivity(intent)
|
||||
@@ -655,6 +688,15 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
||||
llHomeMapTopPet.ivTopPetBtnSmall -> showMapTypeDialog()
|
||||
homeMapBluetoothBtn -> checkPermissions(1)
|
||||
llHomeMapTopPet.homeDataPetNameSmall, llHomeMapTopPet.homeDataPetHeadSmall.root -> getHomeV2Activity()?.selectPetDialog()
|
||||
ilHomeMapDeviceBatteryLayout.ivDeviceCloseBtn -> {
|
||||
mMapDeviceBean?.isCloseBattery = true
|
||||
llHomeMapDeviceBatteryLayout.visibility = View.INVISIBLE
|
||||
}
|
||||
|
||||
ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn -> {
|
||||
mMapDeviceBean?.isCloseMsg = true
|
||||
ilHomeMapDeviceMsg.root.visibility = View.GONE
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.abbidot.tracker.R
|
||||
import com.abbidot.tracker.base.BaseFragment
|
||||
import com.abbidot.tracker.bean.FencesBean
|
||||
import com.abbidot.tracker.bean.HistoryDataBean
|
||||
import com.abbidot.tracker.bean.MapDeviceBean
|
||||
import com.abbidot.tracker.constant.ConstantInt
|
||||
import com.abbidot.tracker.databinding.FragmentGoogleMapBinding
|
||||
import com.abbidot.tracker.util.ImageUtil
|
||||
@@ -392,13 +393,16 @@ abstract class BaseGoogleMapFragment :
|
||||
}
|
||||
|
||||
//刷新当前位置ok,延时等待移动地图摄像头动画
|
||||
if (isAnimMoveCamera) {
|
||||
mGoogleMapView.postDelayed({
|
||||
onRefreshPetCurrentLocationOk(mGoogleMap!!)
|
||||
}, 1000)
|
||||
} else {
|
||||
// if (isAnimMoveCamera) {
|
||||
// mGoogleMapView.postDelayed({
|
||||
// onRefreshPetCurrentLocationOk(mGoogleMap!!)
|
||||
// }, 1000)
|
||||
// } else {
|
||||
// onRefreshPetCurrentLocationOk(mGoogleMap!!)
|
||||
// }
|
||||
mGoogleMapView.postDelayed({
|
||||
onRefreshPetCurrentLocationOk(mGoogleMap!!)
|
||||
}
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1066,6 +1070,21 @@ abstract class BaseGoogleMapFragment :
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置Marker弹窗设备电量的位置
|
||||
*/
|
||||
fun setMapDeviceBatteryOffset(
|
||||
viewGroup: ViewGroup, latLng: LatLng, mapDeviceBean: MapDeviceBean
|
||||
) {
|
||||
mGoogleMap?.projection?.toScreenLocation(latLng)?.let {
|
||||
viewGroup.x = it.x.toFloat() - viewGroup.width / 2 + AppUtils.dpToPx(5)
|
||||
viewGroup.y = it.y.toFloat() - AppUtils.dpToPx(56) - viewGroup.height
|
||||
if (mapDeviceBean.canShowBattery && !mapDeviceBean.isCloseBattery) ViewUtil.instance.viewShow(
|
||||
viewGroup
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置地图网络类型显示位置
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,320 @@
|
||||
package com.abbidot.tracker.ui.fragment.map.googlemap
|
||||
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.view.animation.LinearInterpolator
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isGone
|
||||
import androidx.fragment.app.viewModels
|
||||
import com.abbidot.baselibrary.util.AppUtils
|
||||
import com.abbidot.baselibrary.util.Utils
|
||||
import com.abbidot.tracker.R
|
||||
import com.abbidot.tracker.bean.HistoryDataBean
|
||||
import com.abbidot.tracker.bean.MapDeviceBean
|
||||
import com.abbidot.tracker.databinding.LayoutPetLocationInfoBinding
|
||||
import com.abbidot.tracker.util.Util
|
||||
import com.abbidot.tracker.util.ViewUtil
|
||||
import com.abbidot.tracker.vm.GeoCoderViewModel
|
||||
import com.google.android.gms.maps.GoogleMap
|
||||
import com.google.android.gms.maps.model.Circle
|
||||
import com.google.android.gms.maps.model.CircleOptions
|
||||
import com.google.android.gms.maps.model.LatLng
|
||||
import com.google.android.gms.maps.model.Marker
|
||||
import com.google.android.gms.maps.model.Polyline
|
||||
import com.google.android.gms.maps.model.PolylineOptions
|
||||
import kotlin.math.pow
|
||||
|
||||
/**
|
||||
*Created by .yzq on 2022/1/13/013.
|
||||
* @link
|
||||
* @description:首页map谷歌地图
|
||||
*/
|
||||
class HomeMapGoogleMapFragmentV3 : BaseGoogleMapFragment() {
|
||||
|
||||
private val mGeoCoderViewModel: GeoCoderViewModel by viewModels()
|
||||
|
||||
private lateinit var mPetLocationLayoutBinding: LayoutPetLocationInfoBinding
|
||||
private lateinit var mDeviceBatteryLayout: ViewGroup
|
||||
|
||||
//宠物当前反地理位置信息
|
||||
var mDecPetAddressData: HistoryDataBean? = null
|
||||
private var mMapDeviceBean: MapDeviceBean? = null
|
||||
private lateinit var mMapLoadOk: () -> Unit
|
||||
|
||||
//启动动画移动地图摄像机
|
||||
private var isMoveCamera = true
|
||||
private var mPolyline: Polyline? = null
|
||||
private var mRippleCircle: Circle? = null
|
||||
private var mValueAnimator: ValueAnimator? = null
|
||||
|
||||
private var mRippleCirclePercent = 0.0
|
||||
private var mRippleCircleRadius = 200
|
||||
private var isMapCameraMove = false
|
||||
private var mPetAddressTimeFormat = Utils.DATE_FORMAT_PATTERN_EN11
|
||||
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun newInstance(
|
||||
context: Context,
|
||||
locationLayoutViewBinding: LayoutPetLocationInfoBinding,
|
||||
deviceBatteryLayout: ViewGroup,
|
||||
petAddressTimeFormat: String,
|
||||
mapLoadOk: () -> Unit
|
||||
) = HomeMapGoogleMapFragmentV3().apply {
|
||||
mContext = context
|
||||
mDeviceBatteryLayout = deviceBatteryLayout
|
||||
mPetLocationLayoutBinding = locationLayoutViewBinding
|
||||
mPetAddressTimeFormat = petAddressTimeFormat
|
||||
mMapLoadOk = mapLoadOk
|
||||
}
|
||||
}
|
||||
|
||||
fun setMapDeviceBean(mapDeviceBean: MapDeviceBean?) {
|
||||
mMapDeviceBean = mapDeviceBean
|
||||
}
|
||||
|
||||
override fun liveDataObserve() {
|
||||
//反地理编码成功返回
|
||||
mGeoCoderViewModel.mLatLonAddressLiveData.observe(viewLifecycleOwner) {
|
||||
//保存地理信息,方便传参给导航页面
|
||||
if (null == mDecPetAddressData) mDecPetAddressData = HistoryDataBean()
|
||||
|
||||
mMapDeviceBean?.apply {
|
||||
val timeString = Utils.formatTime(latLonUpdateTime * 1000, mPetAddressTimeFormat)
|
||||
mDecPetAddressData?.let { history ->
|
||||
//更新位置时间
|
||||
history.dayTime = timeString
|
||||
//详细位置
|
||||
history.address = it
|
||||
//传递位置信息给InfoWindowAdapter窗口
|
||||
// mMarker?.tag = history
|
||||
|
||||
// showMarkerInfoWindow(history)
|
||||
val address = String.format(mContext!!.getString(R.string.txt_near), it)
|
||||
ViewUtil.instance.viewShow(mPetLocationLayoutBinding.root)
|
||||
mPetLocationLayoutBinding.let { layout ->
|
||||
layout.tvPetLocationReverseGeocode.text = address
|
||||
layout.tvPetLocationUpdateTime.text = timeString
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMapLoadOk(googleMap: GoogleMap) {
|
||||
//设置自定义头部地点布局
|
||||
mGoogleMap?.apply {
|
||||
setOnCameraIdleListener {
|
||||
if (isMapCameraMove) {
|
||||
isMapCameraMove = false
|
||||
} else {
|
||||
setMarkerInfoViewOffset()
|
||||
}
|
||||
}
|
||||
setOnCameraMoveListener {
|
||||
isMapCameraMove = true
|
||||
setMarkerInfoViewOffset()
|
||||
}
|
||||
|
||||
setOnMarkerClickListener(object : GoogleMap.OnMarkerClickListener {
|
||||
override fun onMarkerClick(marker: Marker): Boolean {
|
||||
if (marker == mMarker) {
|
||||
mMapDeviceBean?.let {
|
||||
if (it.canShowBattery) {
|
||||
mDeviceBatteryLayout.visibility = if (mDeviceBatteryLayout.isGone) {
|
||||
it.isCloseBattery = false
|
||||
View.VISIBLE
|
||||
} else {
|
||||
it.isCloseBattery = true
|
||||
View.GONE
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
})
|
||||
getLastLocation()
|
||||
}
|
||||
|
||||
//变量是否初始化
|
||||
if (::mMapLoadOk.isInitialized) mMapLoadOk()
|
||||
}
|
||||
|
||||
override fun onRefreshPetCurrentLocationOk(googleMap: GoogleMap) {
|
||||
if (null == mMarker) return
|
||||
else startReverseGeocode()
|
||||
}
|
||||
|
||||
/**
|
||||
* 刚开始的反编译地理位置
|
||||
*/
|
||||
private fun startReverseGeocode() {
|
||||
mMapDeviceBean?.apply {
|
||||
mGeoCoderViewModel.getLatLonAddress(latitude, longitude, false)
|
||||
setMarkerInfoViewOffset()
|
||||
}
|
||||
}
|
||||
|
||||
fun setMarkerInfoViewOffset() {
|
||||
mPetLatLng?.apply {
|
||||
mMapDeviceBean?.let {
|
||||
setMapDeviceBatteryOffset(
|
||||
mDeviceBatteryLayout, LatLng(latitude, longitude), it
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算用户和宠物的距离
|
||||
*/
|
||||
fun getUserAndPetDistance(): Double {
|
||||
var distance = 0.0
|
||||
mUserLatLng?.apply {
|
||||
mPetLatLng?.let {
|
||||
distance =
|
||||
Util.measureLatLonDistance(latitude, longitude, it.latitude, it.longitude)
|
||||
}
|
||||
}
|
||||
return distance
|
||||
}
|
||||
|
||||
/**
|
||||
* 画用户和宠物之间的虚线
|
||||
*/
|
||||
private fun addUserAndPetLine(petLatLng: LatLng) {
|
||||
mUserLatLng?.apply {
|
||||
mGoogleMap?.let {
|
||||
if (null == mPolyline) {
|
||||
val polylineOptions =
|
||||
PolylineOptions().clickable(false).width(AppUtils.dpToPx(1.5f))
|
||||
.color(ContextCompat.getColor(mContext!!, R.color.blue_color9))
|
||||
.geodesic(false)
|
||||
mPolyline = it.addPolyline(polylineOptions)
|
||||
mPolyline?.pattern = getDashedPatternStyle(18f)
|
||||
}
|
||||
mPolyline?.let { pLine ->
|
||||
val latList = mutableListOf<LatLng>()
|
||||
latList.add(petLatLng)
|
||||
latList.add(this)
|
||||
pLine.points = latList
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化并添加水波纹圆
|
||||
*/
|
||||
private fun addRippleCircle() {
|
||||
mPetLatLng?.apply {
|
||||
mGoogleMap?.let {
|
||||
if (null == mRippleCircle) {
|
||||
mRippleCircle = it.addCircle(
|
||||
CircleOptions().center(this)
|
||||
.radius(mRippleCircleRadius * mRippleCirclePercent)
|
||||
.strokeWidth(AppUtils.dpToPx(2).toFloat())
|
||||
.fillColor(ContextCompat.getColor(mContext!!, R.color.black10))
|
||||
.strokeColor(ContextCompat.getColor(mContext!!, R.color.black10))
|
||||
)
|
||||
|
||||
setRippleCircleAnim()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置水波纹动画
|
||||
*/
|
||||
private fun setRippleCircleAnim() {
|
||||
if (null == mValueAnimator) {
|
||||
mValueAnimator = ViewUtil.instance.setValueAnimator(
|
||||
0.0, 100.0, 1500, LinearInterpolator()
|
||||
) {
|
||||
mRippleCirclePercent = it.animatedValue as Float / 100.0
|
||||
mRippleCircle?.apply {
|
||||
mPetLatLng?.let { petLatLng ->
|
||||
center = petLatLng
|
||||
radius = mRippleCircleRadius * mRippleCirclePercent
|
||||
}
|
||||
}
|
||||
}?.apply {
|
||||
repeatMode = ValueAnimator.RESTART
|
||||
repeatCount = ValueAnimator.INFINITE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 画线
|
||||
*/
|
||||
fun addLine(latLng: LatLng) {
|
||||
// addPolyline(mGoogleMap!!, latLng)
|
||||
// addUserAndPetLine(latLng)
|
||||
refreshPetCurrentLocation(latLng, needMoveCamera = isMoveCamera)
|
||||
|
||||
// mRippleCircle?.apply {
|
||||
// //一像素对应几米
|
||||
// val pxDis = 2.0.pow(15.5 - getGoogleMapZoom())
|
||||
// mRippleCircleRadius = (pxDis * 150).toInt()
|
||||
// fillColor = (ContextCompat.getColor(mContext!!, R.color.select_color5))
|
||||
// strokeColor = (ContextCompat.getColor(mContext!!, R.color.select_color5))
|
||||
// mValueAnimator?.duration = 2000
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 画多条线
|
||||
*/
|
||||
fun addLines(trackList: MutableList<HistoryDataBean>) {
|
||||
val latLngList = mutableListOf<LatLng>()
|
||||
for (i in 0 until trackList.size) {
|
||||
trackList[i].apply {
|
||||
val latLng = LatLng(latitude, longitude)
|
||||
latLngList.add(latLng)
|
||||
if (i == trackList.size - 1) {
|
||||
// addUserAndPetLine(latLng)
|
||||
refreshPetCurrentLocation(latLng, needMoveCamera = isMoveCamera)
|
||||
}
|
||||
}
|
||||
}
|
||||
// addPolyLines(mGoogleMap!!, latLngList)
|
||||
}
|
||||
|
||||
/**
|
||||
* 开始水波纹动画
|
||||
*/
|
||||
fun startRippleCircleAnim() {
|
||||
mPetLatLng?.apply {
|
||||
//一像素对应几米
|
||||
val pxDis = 2.0.pow(15.5 - getGoogleMapZoom())
|
||||
mRippleCircleRadius = (pxDis * 150).toInt()
|
||||
// addUserAndPetLine(this)
|
||||
addRippleCircle()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 直播开始之后,改变绿色波纹动画
|
||||
*/
|
||||
fun greenRippleCircleAnim() {
|
||||
mRippleCircle?.apply {
|
||||
//一像素对应几米
|
||||
val pxDis = 2.0.pow(15.5 - getGoogleMapZoom())
|
||||
mRippleCircleRadius = (pxDis * 150).toInt()
|
||||
fillColor = (ContextCompat.getColor(mContext!!, R.color.select_color5))
|
||||
strokeColor = (ContextCompat.getColor(mContext!!, R.color.select_color5))
|
||||
mValueAnimator?.duration = 2000
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDetach() {
|
||||
super.onDetach()
|
||||
mValueAnimator?.cancel()
|
||||
}
|
||||
}
|
||||
@@ -36,6 +36,7 @@ import android.widget.TextView
|
||||
import androidx.annotation.DrawableRes
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.core.view.isGone
|
||||
import androidx.core.view.isInvisible
|
||||
import androidx.core.view.setPadding
|
||||
import androidx.core.widget.addTextChangedListener
|
||||
import androidx.fragment.app.FragmentActivity
|
||||
@@ -1116,6 +1117,6 @@ class ViewUtil private constructor() {
|
||||
}
|
||||
|
||||
fun viewShow(view: View) {
|
||||
if (view.isGone) view.visibility = View.VISIBLE
|
||||
if (view.isGone || view.isInvisible) view.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,10 @@ package com.abbidot.tracker.vm
|
||||
|
||||
import android.content.Context
|
||||
import android.os.CountDownTimer
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.widget.AppCompatImageView
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
@@ -17,6 +21,8 @@ import com.abbidot.tracker.retrofit2.NetworkApi
|
||||
import com.abbidot.tracker.util.Util
|
||||
import com.abbidot.tracker.util.ViewUtil
|
||||
import com.abbidot.tracker.util.bluetooth.SRBleUtil
|
||||
import com.abbidot.tracker.widget.TypefaceButton
|
||||
import com.abbidot.tracker.widget.TypefaceTextView
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
class MapViewModel : ViewModel() {
|
||||
@@ -28,8 +34,7 @@ class MapViewModel : ViewModel() {
|
||||
private var mRefreshDataMin = 0.5f
|
||||
private var mDeviceId = ""
|
||||
|
||||
//警告动画是否结束
|
||||
private var isWarningAnimEnd = true
|
||||
private var mDeviceMsgType = ConstantInt.SpecialType
|
||||
|
||||
fun getMapDeviceStatus(deviceId: String, isNeedCountDown: Boolean = true) {
|
||||
viewModelScope.launch {
|
||||
@@ -199,6 +204,63 @@ class MapViewModel : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置设备状态和告警信息显示
|
||||
*/
|
||||
fun setDeviceStateAndWarningData(
|
||||
context: Context,
|
||||
petBean: PetBean?,
|
||||
mapDeviceBean: MapDeviceBean,
|
||||
rootView: ViewGroup,
|
||||
tvDeviceMsgView: TypefaceButton,
|
||||
deviceMsgCloseBtn: AppCompatImageView,
|
||||
deviceStateList: MutableList<DataBean>,
|
||||
deviceStateAdapter: BaseRecyclerAdapter<DataBean>,
|
||||
) {
|
||||
mapDeviceBean.apply {
|
||||
tvDeviceMsgView.setBackgroundResource(R.color.device_msg_color1)
|
||||
if (null != petBean && null != SRBleUtil.instance.getConnectMacDevice(petBean.macID)) {
|
||||
if (isCloseMsg && mDeviceMsgType == ConstantInt.Type0) {
|
||||
|
||||
} else {
|
||||
val nearby =
|
||||
String.format(context.getString(R.string.txt_is_nearby), petBean.petName)
|
||||
tvDeviceMsgView.text = nearby
|
||||
isCloseMsg = false
|
||||
tvDeviceMsgView.setBackgroundResource(R.color.green_color10)
|
||||
ViewUtil.instance.viewShow(rootView)
|
||||
deviceMsgCloseBtn.visibility = View.GONE
|
||||
}
|
||||
} else if (inNoGoZone == ConstantInt.BadZone) {
|
||||
if (isCloseMsg && mDeviceMsgType == ConstantInt.Type1) {
|
||||
|
||||
} else {
|
||||
tvDeviceMsgView.text = context.getString(R.string.txt_in_no_go_zone)
|
||||
ViewUtil.instance.viewShow(deviceMsgCloseBtn)
|
||||
ViewUtil.instance.viewShow(rootView)
|
||||
isCloseMsg = false
|
||||
mDeviceMsgType = ConstantInt.Type1
|
||||
}
|
||||
} else if (inSafeZone == ConstantInt.BadZone) {
|
||||
if (isCloseMsg && mDeviceMsgType == ConstantInt.Type2) {
|
||||
|
||||
} else {
|
||||
tvDeviceMsgView.text = context.getString(R.string.txt_out_save_zone)
|
||||
ViewUtil.instance.viewShow(rootView)
|
||||
ViewUtil.instance.viewShow(deviceMsgCloseBtn)
|
||||
isCloseMsg = false
|
||||
mDeviceMsgType = ConstantInt.Type2
|
||||
}
|
||||
} else {
|
||||
mDeviceMsgType = ConstantInt.Type3
|
||||
rootView.visibility = View.GONE
|
||||
}
|
||||
setDeviceState(context, mapDeviceBean, deviceStateList)
|
||||
|
||||
deviceStateAdapter.notifyItemRangeChanged(0, deviceStateList.size)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置没有的状态
|
||||
*/
|
||||
@@ -363,6 +425,71 @@ class MapViewModel : ViewModel() {
|
||||
}
|
||||
}
|
||||
|
||||
fun setMapDeviceBattery(
|
||||
context: Context,
|
||||
mapDeviceBean: MapDeviceBean,
|
||||
rootView: ViewGroup,
|
||||
batteryText: TypefaceTextView,
|
||||
closeBtn: AppCompatImageView
|
||||
) {
|
||||
mapDeviceBean.apply {
|
||||
if (isCloseBattery) return@apply
|
||||
batteryText.let {
|
||||
canShowBattery = true
|
||||
rootView.visibility = View.VISIBLE
|
||||
if (powerSwitch == ConstantInt.Type0) {
|
||||
it.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
|
||||
it.text = context.getString(R.string.txt_powered_off)
|
||||
ViewUtil.instance.viewShow(closeBtn)
|
||||
} else if (powerSwitch == ConstantInt.Type3) {
|
||||
it.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.icon_charge_image, 0, 0, 0
|
||||
)
|
||||
it.text = context.getString(R.string.txt_charging)
|
||||
ViewUtil.instance.viewShow(closeBtn)
|
||||
} else if (batteryLevel <= ConstantInt.LowBattery30) {
|
||||
val lowBattery =
|
||||
if (batteryLevel <= ConstantInt.LowBattery10) ConstantInt.LowBattery10
|
||||
else if (batteryLevel <= ConstantInt.LowBattery20) ConstantInt.LowBattery20
|
||||
else ConstantInt.LowBattery30
|
||||
it.setCompoundDrawablesWithIntrinsicBounds(
|
||||
R.drawable.icon_low_battery_image, 0, 0, 0
|
||||
)
|
||||
it.text = String.format(
|
||||
context.getString(R.string.txt_battery_less_than), "$lowBattery"
|
||||
)
|
||||
} else {
|
||||
rootView.visibility = View.INVISIBLE
|
||||
canShowBattery = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun setPetLocationReverseGeocode(
|
||||
context: Context,
|
||||
mapDeviceBean: MapDeviceBean,
|
||||
rootView: ViewGroup,
|
||||
locationText: TypefaceTextView,
|
||||
) {
|
||||
mapDeviceBean.apply {
|
||||
val imageResId = if (inWifiZone == ConstantInt.Type1) {
|
||||
rootView.background =
|
||||
ContextCompat.getDrawable(context, R.drawable.shape16_light_green_color_bg)
|
||||
R.drawable.icon_wifi_image
|
||||
} else {
|
||||
rootView.background =
|
||||
ContextCompat.getDrawable(context, R.drawable.shape16_white_color_bg)
|
||||
R.drawable.icon_wifi_image
|
||||
0
|
||||
}
|
||||
locationText.setCompoundDrawablesWithIntrinsicBounds(
|
||||
imageResId, 0, 0, 0
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 停止获取数据
|
||||
*/
|
||||
|
||||
@@ -1,133 +0,0 @@
|
||||
package com.abbidot.tracker.widget
|
||||
|
||||
import android.content.Context
|
||||
import android.graphics.Canvas
|
||||
import android.graphics.Paint
|
||||
import android.graphics.Path
|
||||
import android.text.TextUtils
|
||||
import android.util.AttributeSet
|
||||
import android.view.View
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.abbidot.baselibrary.util.AppUtils
|
||||
import com.abbidot.tracker.R
|
||||
import com.qmuiteam.qmui.util.QMUIDisplayHelper
|
||||
|
||||
/**
|
||||
*Created by .yzq on 2024/8/26/026.
|
||||
* @link
|
||||
* @description:
|
||||
*/
|
||||
class MapBatteryView : View {
|
||||
|
||||
private lateinit var mContext: Context
|
||||
private var mOffsetX = 0
|
||||
private var mOffsetY = 0
|
||||
|
||||
//文字和边界的距离。三角形的直线长
|
||||
private var mPadding = 0
|
||||
|
||||
private lateinit var mTextPaint: Paint
|
||||
private lateinit var mPaint: Paint
|
||||
|
||||
//小三角形的path
|
||||
private lateinit var mTrianglePath: Path
|
||||
|
||||
private var mTimeText = ""
|
||||
private var mAddressText = ""
|
||||
|
||||
constructor(context: Context) : super(context) {
|
||||
init(context)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||
context, attrs, defStyleAttr
|
||||
) {
|
||||
init(context)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
|
||||
init(context)
|
||||
}
|
||||
|
||||
private fun init(context: Context) {
|
||||
//禁用硬件加速,防止返回到界面多次执行onDraw
|
||||
setLayerType(LAYER_TYPE_SOFTWARE, null)
|
||||
mContext = context
|
||||
mPaint = Paint().apply {
|
||||
color = ContextCompat.getColor(mContext, R.color.white)
|
||||
}
|
||||
//开启抗锯齿
|
||||
mTextPaint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
||||
color = ContextCompat.getColor(mContext, R.color.black)
|
||||
textSize = QMUIDisplayHelper.sp2px(mContext, 12).toFloat()
|
||||
}
|
||||
mPadding = AppUtils.dpToPx(6)
|
||||
|
||||
mTrianglePath = Path()
|
||||
}
|
||||
|
||||
override fun onDraw(canvas: Canvas) {
|
||||
super.onDraw(canvas)
|
||||
canvas.apply {
|
||||
startDraw(this)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startDraw(canvas: Canvas) {
|
||||
if (TextUtils.isEmpty(mAddressText) && TextUtils.isEmpty(mTimeText)) return
|
||||
mTrianglePath.apply {
|
||||
reset()
|
||||
moveTo((mOffsetX - mPadding).toFloat(), (mOffsetY - mPadding).toFloat())
|
||||
lineTo(mOffsetX.toFloat(), mOffsetY.toFloat())
|
||||
lineTo((mOffsetX + mPadding).toFloat(), (mOffsetY - mPadding).toFloat())
|
||||
close()
|
||||
}
|
||||
canvas.apply {
|
||||
|
||||
drawPath(mTrianglePath, mPaint)
|
||||
|
||||
val fontMetrics = mTextPaint.fontMetrics
|
||||
//文字高度
|
||||
val textHeight = fontMetrics.bottom - fontMetrics.top
|
||||
//时间文字宽度
|
||||
val timeTextWith = mTextPaint.measureText(mTimeText)
|
||||
//地址文字宽度
|
||||
val addressTextWith = mTextPaint.measureText(mAddressText)
|
||||
val maxTextWith = maxOf(timeTextWith, addressTextWith)
|
||||
|
||||
drawRoundRect(
|
||||
mOffsetX - maxTextWith / 2 - mPadding,
|
||||
mOffsetY - textHeight * 2 - mPadding * 2,
|
||||
mOffsetX + maxTextWith / 2 + mPadding,
|
||||
mOffsetY.toFloat() - mPadding,
|
||||
AppUtils.dpToPx(6f),
|
||||
AppUtils.dpToPx(6f),
|
||||
mPaint
|
||||
)
|
||||
drawText(
|
||||
mTimeText,
|
||||
mOffsetX - timeTextWith / 2,
|
||||
mOffsetY - textHeight / 2 - mPadding,
|
||||
mTextPaint
|
||||
)
|
||||
drawText(
|
||||
mAddressText,
|
||||
mOffsetX - addressTextWith / 2,
|
||||
mOffsetY - textHeight / 2 - textHeight - mPadding,
|
||||
mTextPaint
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fun setShowText(time: String, address: String) {
|
||||
mTimeText = time
|
||||
mAddressText = address
|
||||
invalidate()
|
||||
}
|
||||
|
||||
fun setOffsetXY(x: Int, y: Int) {
|
||||
mOffsetX = x
|
||||
mOffsetY = y
|
||||
invalidate()
|
||||
}
|
||||
}
|
||||
BIN
app/src/main/res/drawable-xhdpi/icon_charge_image.png
Normal file
|
After Width: | Height: | Size: 301 B |
BIN
app/src/main/res/drawable-xhdpi/icon_low_battery_image.png
Normal file
|
After Width: | Height: | Size: 309 B |
BIN
app/src/main/res/drawable-xxhdpi/icon_charge_image.png
Normal file
|
After Width: | Height: | Size: 331 B |
BIN
app/src/main/res/drawable-xxhdpi/icon_low_battery_image.png
Normal file
|
After Width: | Height: | Size: 302 B |
BIN
app/src/main/res/drawable-xxxhdpi/icon_charge_image.png
Normal file
|
After Width: | Height: | Size: 420 B |
BIN
app/src/main/res/drawable-xxxhdpi/icon_low_battery_image.png
Normal file
|
After Width: | Height: | Size: 468 B |
BIN
app/src/main/res/drawable-xxxhdpi/icon_white_trigon.png
Normal file
|
After Width: | Height: | Size: 305 B |
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/green_color10" />
|
||||
<corners android:radius="@dimen/dp_16" />
|
||||
</shape>
|
||||
|
||||
145
app/src/main/res/layout/activity_live_v3.xml
Normal file
@@ -0,0 +1,145 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical"
|
||||
tools:context=".ui.activity.map.LiveActivityV2">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1">
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/fc_live_v2_map_fragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/ll_live_v3_map_device_battery_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible">
|
||||
|
||||
<include
|
||||
android:id="@+id/il_live_v3_map_device_battery_layout"
|
||||
layout="@layout/layout_map_device_battery" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<include
|
||||
android:id="@+id/ll_live_v2_map_top_pet"
|
||||
layout="@layout/layout_top_pet_data_small"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginHorizontal="@dimen/dp_8"
|
||||
android:layout_marginTop="@dimen/dp_40" />
|
||||
|
||||
<com.qmuiteam.qmui.widget.roundwidget.QMUIRoundLinearLayout
|
||||
android:id="@+id/ll_live_v2_state_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="@dimen/dp_34"
|
||||
android:layout_below="@id/ll_live_v2_map_top_pet"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginTop="@dimen/dp_8"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="@dimen/dp_12"
|
||||
android:visibility="gone"
|
||||
app:qmui_backgroundColor="@color/select_color2"
|
||||
app:qmui_radius="@dimen/dp_28">
|
||||
|
||||
<com.airbnb.lottie.LottieAnimationView
|
||||
android:id="@+id/lav_live_v2_state_anim"
|
||||
android:layout_width="@dimen/dp_40"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:lottie_loop="true" />
|
||||
|
||||
<com.abbidot.tracker.widget.TypefaceTextView
|
||||
android:id="@+id/tv_live_v2_state_content"
|
||||
style="@style/my_TextView_style_v2"
|
||||
android:text="@string/txt_starting_live"
|
||||
android:textColor="@color/select_color"
|
||||
android:textSize="@dimen/textSize12"
|
||||
app:typeface="@string/roboto_regular_font" />
|
||||
|
||||
</com.qmuiteam.qmui.widget.roundwidget.QMUIRoundLinearLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/il_live_v3_map_device_msg"
|
||||
layout="@layout/item_home_map_device_msg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/ll_live_v2_state_layout"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginTop="@dimen/dp_6"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.abbidot.tracker.widget.NonSwipeRecyclerView
|
||||
android:id="@+id/rv_map_live_v2_device_state"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/ll_live_v2_map_top_pet"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginTop="@dimen/dp_18"
|
||||
android:layout_marginEnd="@dimen/dp_12"
|
||||
android:layoutDirection="rtl" />
|
||||
|
||||
<include
|
||||
android:id="@+id/il_live_v2_bluetooth_find_device"
|
||||
layout="@layout/layout_bluetooth_find_device"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
|
||||
<include
|
||||
android:id="@+id/il_live_v3_map_pet_location"
|
||||
layout="@layout/layout_pet_location_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginHorizontal="@dimen/dp_8"
|
||||
android:layout_marginBottom="@dimen/dp_4"
|
||||
android:visibility="invisible" />
|
||||
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iv_map_live_v2_refresh_btn"
|
||||
style="@style/map_image_yellow_btn_style"
|
||||
android:layout_above="@id/il_live_v3_map_pet_location"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_marginEnd="@dimen/dp_12"
|
||||
android:layout_marginBottom="@dimen/dp_16" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iv_map_live_v2_bluetooth_btn"
|
||||
style="@style/map_image_white_btn_style"
|
||||
android:layout_alignTop="@id/iv_map_live_v2_refresh_btn"
|
||||
android:layout_alignBottom="@id/iv_map_live_v2_refresh_btn"
|
||||
android:layout_marginStart="@dimen/dp_12"
|
||||
android:padding="@dimen/dp_8"
|
||||
android:src="@drawable/icon_map_bluetooth" />
|
||||
|
||||
|
||||
<include
|
||||
android:id="@+id/il_map_live_v2_issue_layout"
|
||||
layout="@layout/layout_live_issue"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:visibility="gone" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<include
|
||||
android:id="@+id/il_live_v2_operate_layout"
|
||||
layout="@layout/layout_live_v2_data_info"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/white" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
@@ -10,10 +10,17 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<com.abbidot.tracker.widget.MapMarkerInfoView
|
||||
android:id="@+id/mi_home_map_address_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:id="@+id/ll_home_map_device_battery_layout"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="invisible">
|
||||
|
||||
<include
|
||||
android:id="@+id/il_home_map_device_battery_layout"
|
||||
layout="@layout/layout_map_device_battery" />
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
|
||||
<RelativeLayout
|
||||
@@ -29,13 +36,15 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_8" />
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/rv_home_map_device_msg"
|
||||
<include
|
||||
android:id="@+id/il_home_map_device_msg"
|
||||
layout="@layout/item_home_map_device_msg"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/ll_home_map_top_pet"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_marginTop="@dimen/dp_8" />
|
||||
android:layout_marginTop="@dimen/dp_6"
|
||||
android:visibility="gone" />
|
||||
|
||||
<com.abbidot.tracker.widget.NonSwipeRecyclerView
|
||||
android:id="@+id/rv_home_map_device_state"
|
||||
@@ -53,7 +62,8 @@
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_marginBottom="@dimen/dp_40" />
|
||||
android:layout_marginBottom="@dimen/dp_38"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/home_map_bluetooth_btn"
|
||||
@@ -80,7 +90,7 @@
|
||||
android:orientation="vertical"
|
||||
android:paddingHorizontal="@dimen/dp_14"
|
||||
android:paddingVertical="@dimen/dp_16"
|
||||
android:visibility="visible">
|
||||
android:visibility="invisible">
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="@dimen/dp_255"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center">
|
||||
@@ -9,11 +9,22 @@
|
||||
<com.abbidot.tracker.widget.TypefaceButton
|
||||
android:id="@+id/tv_device_msg_content"
|
||||
style="@style/my_TextView_style_v2"
|
||||
android:background="@color/orange_color3"
|
||||
android:layout_marginTop="@dimen/dp_4"
|
||||
android:layout_marginEnd="@dimen/dp_4"
|
||||
android:background="@color/device_msg_color1"
|
||||
android:paddingHorizontal="@dimen/dp_18"
|
||||
android:paddingVertical="@dimen/dp_12"
|
||||
android:textColor="@color/data_black_color"
|
||||
android:textSize="@dimen/textSize12"
|
||||
app:qmui_radius="@dimen/dp_28" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iv_device_msg_close_btn"
|
||||
android:layout_width="@dimen/dp_16"
|
||||
android:layout_height="@dimen/dp_16"
|
||||
android:layout_gravity="end"
|
||||
android:src="@drawable/ic_delete_easyy_photos"
|
||||
android:tint="@color/gray_color3" />
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
42
app/src/main/res/layout/layout_map_device_battery.xml
Normal file
@@ -0,0 +1,42 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout 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">
|
||||
|
||||
<androidx.appcompat.widget.LinearLayoutCompat
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="@dimen/dp_6"
|
||||
android:layout_marginEnd="@dimen/dp_8"
|
||||
android:gravity="center"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.abbidot.tracker.widget.TypefaceTextView
|
||||
android:id="@+id/tv_device_battery_info"
|
||||
style="@style/my_TextView_style_v2"
|
||||
android:background="@drawable/shape8_white_bg"
|
||||
android:drawableStart="@drawable/icon_low_battery_image"
|
||||
android:drawablePadding="@dimen/dp_4"
|
||||
android:padding="@dimen/dp_10"
|
||||
android:text="@string/txt_powered_off"
|
||||
android:textSize="@dimen/textSize12"
|
||||
app:typeface="@string/roboto_regular_font" />
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:src="@drawable/icon_white_trigon" />
|
||||
|
||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||
|
||||
|
||||
<androidx.appcompat.widget.AppCompatImageView
|
||||
android:id="@+id/iv_device_close_btn"
|
||||
android:layout_width="@dimen/dp_16"
|
||||
android:layout_height="@dimen/dp_16"
|
||||
android:layout_gravity="end"
|
||||
android:src="@drawable/ic_delete_easyy_photos"
|
||||
android:tint="@color/gray_color3" />
|
||||
|
||||
</FrameLayout>
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
|
||||
<com.abbidot.tracker.widget.TypefaceTextView
|
||||
android:id="@+id/tv_pet_location_update_time"
|
||||
style="@style/my_TextView_style_v2"
|
||||
android:layout_below="@id/tv_pet_location_reverse_geocode"
|
||||
android:layout_alignParentEnd="true"
|
||||
|
||||
@@ -796,7 +796,7 @@
|
||||
<string name="txt_hours">hours</string>
|
||||
<string name="txt_search_device">Searching…</string>
|
||||
<string name="txt_no_search_device">Keep tracker on and nearby to scan.</string>
|
||||
<string name="txt_battery_less_than">Battery less than %s%%</string>
|
||||
<string name="txt_battery_less_than">Less than %s%%</string>
|
||||
<string name="txt_outside">Outside</string>
|
||||
<string name="txt_inside">Inside</string>
|
||||
<string name="txt_7days_avg">7 Days Avg.</string>
|
||||
@@ -1050,5 +1050,8 @@
|
||||
<string name="txt_show_crash">The program has an exception and is about to exit</string>
|
||||
|
||||
<string name="txt_activate_subscribe">Activate Subscription</string>
|
||||
<string name="txt_powered_off">Powered off</string>
|
||||
<string name="txt_near">Near %s</string>
|
||||
<string name="txt_charging">Charging</string>
|
||||
|
||||
</resources>
|
||||
@@ -42,6 +42,8 @@ class Utils {
|
||||
const val DATE_FORMAT_PATTERN_EN8 = "hh:mm a"
|
||||
const val DATE_FORMAT_PATTERN_EN9 = "MMM d, yyyy hh:mm a"
|
||||
const val DATE_FORMAT_PATTERN_EN10 = "dd/MM/yyyy HH:mm:ss"
|
||||
const val DATE_FORMAT_PATTERN_EN11 = "dd/MM HH:mm"
|
||||
const val DATE_FORMAT_PATTERN_EN12 = "dd/MM HH:mm:ss"
|
||||
|
||||
//返回星期几 简写
|
||||
const val WEEK_FORMAT_PATTERN = "E"
|
||||
|
||||