map和直播页面改版
@@ -30,7 +30,7 @@ android {
|
|||||||
targetSdkVersion 35
|
targetSdkVersion 35
|
||||||
versionCode 2101
|
versionCode 2101
|
||||||
// versionName "2.1.1"
|
// versionName "2.1.1"
|
||||||
versionName "2.1.1-Beta2"
|
versionName "2.1.1-Beta4"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|
||||||
|
|||||||
@@ -391,6 +391,10 @@
|
|||||||
android:name=".ui.activity.map.LiveActivityV2"
|
android:name=".ui.activity.map.LiveActivityV2"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
android:screenOrientation="portrait" />
|
android:screenOrientation="portrait" />
|
||||||
|
<activity
|
||||||
|
android:name=".ui.activity.map.LiveActivityV3"
|
||||||
|
android:exported="false"
|
||||||
|
android:screenOrientation="portrait" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.activity.data.MoreSleepActivity"
|
android:name=".ui.activity.data.MoreSleepActivity"
|
||||||
android:exported="false"
|
android:exported="false"
|
||||||
|
|||||||
@@ -34,7 +34,10 @@ data class MapDeviceBean(
|
|||||||
var fences: MutableList<FencesBean>?,
|
var fences: MutableList<FencesBean>?,
|
||||||
var wifiZones: MutableList<WiFiZoneBean>?,
|
var wifiZones: MutableList<WiFiZoneBean>?,
|
||||||
var startTime: String,
|
var startTime: String,
|
||||||
var endTime: String
|
var endTime: String,
|
||||||
|
var canShowBattery: Boolean,
|
||||||
|
var isCloseBattery: Boolean,
|
||||||
|
var isCloseMsg: Boolean
|
||||||
) : Parcelable {
|
) : Parcelable {
|
||||||
constructor() : this(
|
constructor() : this(
|
||||||
"",
|
"",
|
||||||
@@ -65,6 +68,9 @@ data class MapDeviceBean(
|
|||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
"",
|
"",
|
||||||
""
|
"",
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
|||||||
private val mBleReportManage: BleReportManage by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
|
private val mBleReportManage: BleReportManage by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
|
||||||
mSocketUtilManage = SocketUtilManage()
|
mSocketUtilManage = SocketUtilManage()
|
||||||
mSocketUtilManage?.initEasySocket(mContext)
|
mSocketUtilManage?.initEasySocket(mContext)
|
||||||
|
LogUtil.e("创建Socket连接")
|
||||||
BleReportManage(mSocketSendMessageViewModel, mSocketUtilManage!!)
|
BleReportManage(mSocketSendMessageViewModel, mSocketUtilManage!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -222,11 +223,16 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
|||||||
XEventBus.observe(this, EventName.ConnectDeviceState) { ble: BleTrackDeviceBean ->
|
XEventBus.observe(this, EventName.ConnectDeviceState) { ble: BleTrackDeviceBean ->
|
||||||
getPet(false)?.apply {
|
getPet(false)?.apply {
|
||||||
//蓝牙连接断开上传日志
|
//蓝牙连接断开上传日志
|
||||||
if (ble.mac == macID && ble.conState == ConState.DISCONNECTED) {
|
if (ble.mac == macID) {
|
||||||
|
if (ble.conState == ConState.CONNECTED) {
|
||||||
|
//蓝牙连接就去连接socket
|
||||||
|
mBleReportManage.dealBleReportData(macID, null)
|
||||||
|
} else {
|
||||||
mLogBleReportViewModel.uploadLog(mContext, macID)
|
mLogBleReportViewModel.uploadLog(mContext, macID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
//更新套餐数据
|
//更新套餐数据
|
||||||
XEventBus.observe(this, EventName.RefreshPackage) {
|
XEventBus.observe(this, EventName.RefreshPackage) {
|
||||||
mDataViewModel.getHomeBindPetList(this)
|
mDataViewModel.getHomeBindPetList(this)
|
||||||
@@ -338,7 +344,6 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
|||||||
getPet(false)?.apply {
|
getPet(false)?.apply {
|
||||||
mLogBleReportViewModel.uploadLog(mContext, macID)
|
mLogBleReportViewModel.uploadLog(mContext, macID)
|
||||||
}
|
}
|
||||||
(mFragments[2] as MapV3Fragment).showPetNameAndHead(mSelectPetPosition)
|
|
||||||
} else {
|
} else {
|
||||||
onChangeClick(mSelectPetPosition)
|
onChangeClick(mSelectPetPosition)
|
||||||
when (mViewBinding.homeV2ViewPager2.currentItem) {
|
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() {
|
fun selectPetDialog() {
|
||||||
if (isRequestPetData && mPetList.size == 0) {
|
if (mPetList.size == 0) {
|
||||||
showToast(R.string.no_bind_pet)
|
showToast(R.string.no_bind_pet)
|
||||||
return
|
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.AppUtils
|
||||||
import com.abbidot.baselibrary.util.LogUtil
|
import com.abbidot.baselibrary.util.LogUtil
|
||||||
import com.abbidot.baselibrary.util.MMKVUtil
|
import com.abbidot.baselibrary.util.MMKVUtil
|
||||||
|
import com.abbidot.baselibrary.util.Utils
|
||||||
import com.abbidot.tracker.R
|
import com.abbidot.tracker.R
|
||||||
import com.abbidot.tracker.adapter.HomeMapDeviceMsgAdapter
|
|
||||||
import com.abbidot.tracker.adapter.HomeMapDeviceStateAdapter
|
import com.abbidot.tracker.adapter.HomeMapDeviceStateAdapter
|
||||||
import com.abbidot.tracker.base.BaseDialog
|
import com.abbidot.tracker.base.BaseDialog
|
||||||
import com.abbidot.tracker.base.BaseFragment
|
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.dialog.SelectMapTypeDialog
|
||||||
import com.abbidot.tracker.ui.activity.HomeV2Activity
|
import com.abbidot.tracker.ui.activity.HomeV2Activity
|
||||||
import com.abbidot.tracker.ui.activity.device.MyTrackerV2Activity
|
import com.abbidot.tracker.ui.activity.device.MyTrackerV2Activity
|
||||||
import com.abbidot.tracker.ui.activity.map.LiveActivityV2
|
import com.abbidot.tracker.ui.activity.map.LiveActivityV3
|
||||||
import com.abbidot.tracker.ui.common.map.HomeMapCommon
|
import com.abbidot.tracker.ui.common.map.HomeMapCommonV3
|
||||||
import com.abbidot.tracker.util.Util
|
import com.abbidot.tracker.util.Util
|
||||||
import com.abbidot.tracker.util.ViewUtil
|
import com.abbidot.tracker.util.ViewUtil
|
||||||
import com.abbidot.tracker.util.bluetooth.SRBleUtil
|
import com.abbidot.tracker.util.bluetooth.SRBleUtil
|
||||||
import com.abbidot.tracker.vm.FamilyViewModel
|
import com.abbidot.tracker.vm.FamilyViewModel
|
||||||
import com.abbidot.tracker.vm.FencesMapViewModel
|
import com.abbidot.tracker.vm.FencesMapViewModel
|
||||||
import com.abbidot.tracker.vm.MapViewModel
|
import com.abbidot.tracker.vm.MapViewModel
|
||||||
import com.abbidot.tracker.widget.MapDeviceNetView
|
|
||||||
import com.clj.fastble.BleManager
|
import com.clj.fastble.BleManager
|
||||||
import com.hjq.permissions.XXPermissions
|
import com.hjq.permissions.XXPermissions
|
||||||
import com.hjq.permissions.permission.PermissionLists
|
import com.hjq.permissions.permission.PermissionLists
|
||||||
@@ -74,14 +73,14 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
private var mCurrentShowPetPos = -1
|
private var mCurrentShowPetPos = -1
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var mHomeMapCommon: HomeMapCommon
|
lateinit var mHomeMapCommon: HomeMapCommonV3
|
||||||
private lateinit var mFragment: Fragment
|
private lateinit var mFragment: Fragment
|
||||||
private var mMapDeviceBean: MapDeviceBean? = null
|
private var mMapDeviceBean: MapDeviceBean? = null
|
||||||
|
|
||||||
private lateinit var mDeviceStateList: MutableList<DataBean>
|
private lateinit var mDeviceStateList: MutableList<DataBean>
|
||||||
private lateinit var mDeviceStateAdapter: HomeMapDeviceStateAdapter
|
private lateinit var mDeviceStateAdapter: HomeMapDeviceStateAdapter
|
||||||
private lateinit var mDeviceMsgList: MutableList<DataBean>
|
// private lateinit var mDeviceMsgList: MutableList<DataBean>
|
||||||
private lateinit var mDeviceMsgAdapter: HomeMapDeviceMsgAdapter
|
// private lateinit var mDeviceMsgAdapter: HomeMapDeviceMsgAdapter
|
||||||
|
|
||||||
//启动移动地图摄像机
|
//启动移动地图摄像机
|
||||||
private var isMoveCamera = true
|
private var isMoveCamera = true
|
||||||
@@ -113,7 +112,10 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
rlHomeMapTopLayout, WindowInsetsCompat.Type.statusBars()
|
rlHomeMapTopLayout, WindowInsetsCompat.Type.statusBars()
|
||||||
)
|
)
|
||||||
mFragment = mHomeMapCommon.getMapFragment(
|
mFragment = mHomeMapCommon.getMapFragment(
|
||||||
mContext!!, miHomeMapAddressView, MapDeviceNetView(mContext!!)
|
mContext!!,
|
||||||
|
ilHomeMapPetLocation,
|
||||||
|
llHomeMapDeviceBatteryLayout,
|
||||||
|
Utils.DATE_FORMAT_PATTERN_EN11
|
||||||
) { mapLoadOk() }
|
) { mapLoadOk() }
|
||||||
|
|
||||||
llHomeMapTopPet.ivTopPetBtnSmall.setImageResource(R.drawable.icon_map_type)
|
llHomeMapTopPet.ivTopPetBtnSmall.setImageResource(R.drawable.icon_map_type)
|
||||||
@@ -123,17 +125,16 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
)
|
)
|
||||||
|
|
||||||
mDeviceStateList = mutableListOf()
|
mDeviceStateList = mutableListOf()
|
||||||
mDeviceMsgList = mutableListOf()
|
|
||||||
mMapViewModel.addDeviceDefaultStateData(mContext!!, mDeviceStateList)
|
mMapViewModel.addDeviceDefaultStateData(mContext!!, mDeviceStateList)
|
||||||
mDeviceStateAdapter = HomeMapDeviceStateAdapter(mContext!!, mDeviceStateList)
|
mDeviceStateAdapter = HomeMapDeviceStateAdapter(mContext!!, mDeviceStateList)
|
||||||
ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
|
ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
|
||||||
mContext!!, rvHomeMapDeviceState, mDeviceStateAdapter, bottom = 10
|
mContext!!, rvHomeMapDeviceState, mDeviceStateAdapter, bottom = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
mDeviceMsgAdapter = HomeMapDeviceMsgAdapter(mContext!!, mDeviceMsgList)
|
// mDeviceMsgAdapter = HomeMapDeviceMsgAdapter(mContext!!, mDeviceMsgList)
|
||||||
ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
|
// ViewUtil.instance.setRecyclerViewVerticalLinearLayout(
|
||||||
mContext!!, rvHomeMapDeviceMsg, mDeviceMsgAdapter, bottom = 10
|
// mContext!!, rvHomeMapDeviceMsg, mDeviceMsgAdapter, bottom = 10
|
||||||
)
|
// )
|
||||||
|
|
||||||
setOnClickListenerViews(
|
setOnClickListenerViews(
|
||||||
homeMapRefreshBtn,
|
homeMapRefreshBtn,
|
||||||
@@ -141,7 +142,9 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
homeMapLiveBtn,
|
homeMapLiveBtn,
|
||||||
llHomeMapTopPet.ivTopPetBtnSmall,
|
llHomeMapTopPet.ivTopPetBtnSmall,
|
||||||
llHomeMapTopPet.homeDataPetNameSmall,
|
llHomeMapTopPet.homeDataPetNameSmall,
|
||||||
llHomeMapTopPet.homeDataPetHeadSmall.root
|
llHomeMapTopPet.homeDataPetHeadSmall.root,
|
||||||
|
ilHomeMapDeviceBatteryLayout.ivDeviceCloseBtn,
|
||||||
|
ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn
|
||||||
)
|
)
|
||||||
|
|
||||||
if (AppUtils.isDebug()) {
|
if (AppUtils.isDebug()) {
|
||||||
@@ -230,17 +233,22 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
override fun onResult(any: Any) {
|
override fun onResult(any: Any) {
|
||||||
val data = it.getOrNull()
|
val data = it.getOrNull()
|
||||||
data?.apply {
|
data?.apply {
|
||||||
|
mMapDeviceBean?.let { m ->
|
||||||
|
data.isCloseMsg = m.isCloseMsg
|
||||||
|
data.isCloseBattery = m.isCloseBattery
|
||||||
|
data.canShowBattery = m.canShowBattery
|
||||||
|
}
|
||||||
mMapDeviceBean = data
|
mMapDeviceBean = data
|
||||||
setMapData(data)
|
setMapData(data)
|
||||||
mMapViewModel.setDeviceStateAndWarningData(
|
mMapViewModel.setDeviceStateAndWarningData(
|
||||||
mContext!!,
|
mContext!!,
|
||||||
getHomeV2Activity()?.getPet(),
|
getHomeV2Activity()?.getPet(),
|
||||||
data,
|
data,
|
||||||
|
mViewBinding.ilHomeMapDeviceMsg.root,
|
||||||
|
mViewBinding.ilHomeMapDeviceMsg.tvDeviceMsgContent,
|
||||||
|
mViewBinding.ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn,
|
||||||
mDeviceStateList,
|
mDeviceStateList,
|
||||||
mDeviceStateAdapter,
|
mDeviceStateAdapter
|
||||||
mDeviceMsgList,
|
|
||||||
mDeviceMsgAdapter,
|
|
||||||
mViewBinding.rvHomeMapDeviceMsg
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -288,15 +296,30 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
//接收蓝牙连接状态
|
//接收蓝牙连接状态
|
||||||
XEventBus.observe(this, EventName.ConnectDeviceState) { trackBle: BleTrackDeviceBean ->
|
XEventBus.observe(this, EventName.ConnectDeviceState) { trackBle: BleTrackDeviceBean ->
|
||||||
getHomeV2Activity()?.getPet(false)?.apply {
|
getHomeV2Activity()?.getPet(false)?.apply {
|
||||||
//蓝牙断开就重新获取服务器数据,蓝牙数据上报断开
|
if (trackBle.mac == macID) {
|
||||||
if (trackBle.mac == macID && trackBle.conState != ConState.CONNECTED) {
|
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
|
//隐藏蓝牙nearby
|
||||||
mViewBinding.rvHomeMapDeviceMsg.visibility = View.GONE
|
mViewBinding.ilHomeMapDeviceMsg.root.visibility = View.GONE
|
||||||
|
//蓝牙断开就重新获取服务器数据,蓝牙数据上报断开
|
||||||
updateMapDeviceStatus()
|
updateMapDeviceStatus()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新蓝牙上报的数据
|
* 更新蓝牙上报的数据
|
||||||
@@ -314,29 +337,27 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
it.longitude = location.longitude
|
it.longitude = location.longitude
|
||||||
it.latitude = location.latitude
|
it.latitude = location.latitude
|
||||||
}
|
}
|
||||||
mHomeMapCommon.setMapDeviceBean(mMapDeviceBean)
|
setMapDeviceBean(it)
|
||||||
mHomeMapCommon.refreshPetCurrentLocation(
|
mHomeMapCommon.refreshPetCurrentLocation(
|
||||||
it.latitude, it.longitude, isMoveCamera
|
it.latitude, it.longitude, isMoveCamera
|
||||||
)
|
)
|
||||||
mHomeMapCommon.startRefreshUserLocation()
|
mHomeMapCommon.startRefreshUserLocation()
|
||||||
}
|
}
|
||||||
}
|
ViewUtil.instance.viewShow(mViewBinding.homeMapLiveBtn)
|
||||||
|
|
||||||
mViewBinding.homeMapLiveBtn.visibility = View.VISIBLE
|
|
||||||
|
|
||||||
mMapViewModel.setDeviceStateAndWarningData(
|
mMapViewModel.setDeviceStateAndWarningData(
|
||||||
mContext!!,
|
mContext!!,
|
||||||
getHomeV2Activity()?.getPet(),
|
getHomeV2Activity()?.getPet(),
|
||||||
mMapDeviceBean!!,
|
it,
|
||||||
|
mViewBinding.ilHomeMapDeviceMsg.root,
|
||||||
|
mViewBinding.ilHomeMapDeviceMsg.tvDeviceMsgContent,
|
||||||
|
mViewBinding.ilHomeMapDeviceMsg.ivDeviceMsgCloseBtn,
|
||||||
mDeviceStateList,
|
mDeviceStateList,
|
||||||
mDeviceStateAdapter,
|
mDeviceStateAdapter
|
||||||
mDeviceMsgList,
|
|
||||||
mDeviceMsgAdapter,
|
|
||||||
mViewBinding.rvHomeMapDeviceMsg
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示被删除邀请的弹窗
|
* 显示被删除邀请的弹窗
|
||||||
@@ -438,10 +459,6 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
private fun updateMapDeviceStatus(
|
private fun updateMapDeviceStatus(
|
||||||
isNeedCountDown: Boolean = true, useBleLocation: Boolean = false
|
isNeedCountDown: Boolean = true, useBleLocation: Boolean = false
|
||||||
) {
|
) {
|
||||||
// mShowCenterLocationType = ConstantInt.PetLocationType
|
|
||||||
// ViewUtil.instance.setMapSwitchLocationButtonImage(
|
|
||||||
// mViewBinding.homeMapRefreshBtn, mShowCenterLocationType
|
|
||||||
// )
|
|
||||||
getHomeV2Activity()?.apply {
|
getHomeV2Activity()?.apply {
|
||||||
if (mPetList.size <= mCurrentShowPetPos) return
|
if (mPetList.size <= mCurrentShowPetPos) return
|
||||||
getPet()?.apply {
|
getPet()?.apply {
|
||||||
@@ -531,8 +548,12 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
if (mHomeMapCommon.isMapLoadOk()) {
|
if (mHomeMapCommon.isMapLoadOk()) {
|
||||||
isMoveCamera = true
|
isMoveCamera = true
|
||||||
mHomeMapCommon.clearMarker()
|
mHomeMapCommon.clearMarker()
|
||||||
mViewBinding.miHomeMapAddressView.visibility = View.GONE
|
mMapDeviceBean?.let {
|
||||||
mViewBinding.rvHomeMapDeviceMsg.visibility = View.GONE
|
it.isCloseMsg = false
|
||||||
|
it.isCloseBattery = false
|
||||||
|
it.canShowBattery = false
|
||||||
|
}
|
||||||
|
mViewBinding.ilHomeMapDeviceMsg.root.visibility = View.GONE
|
||||||
showLoading(true)
|
showLoading(true)
|
||||||
val pet = mPetList[position]
|
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
|
if (Util.isTimeoutReport(updateTime) || powerSwitch == ConstantInt.Type0 || powerSwitch == ConstantInt.Type2 || inWifiZone == ConstantInt.Type1) View.GONE
|
||||||
else View.VISIBLE
|
else View.VISIBLE
|
||||||
|
|
||||||
mHomeMapCommon.setMapDeviceBean(this)
|
setMapDeviceBean(this)
|
||||||
//设置循环查询时间间隔 30秒
|
//设置循环查询时间间隔 30秒
|
||||||
mMapViewModel.updateMillisInFuture(0.5f)
|
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.refreshPetCurrentLocation(latitude, longitude, isMoveCamera)
|
||||||
mHomeMapCommon.startRefreshUserLocation()
|
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 {
|
} else {
|
||||||
getPet()?.apply {
|
getPet()?.apply {
|
||||||
mViewBinding.homeMapLiveBtn.isEnabled = false
|
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.JumpActivity, true)
|
||||||
intent.putExtra(ConstantString.Pet, this)
|
intent.putExtra(ConstantString.Pet, this)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
@@ -605,7 +638,7 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
} else {
|
} else {
|
||||||
getPet()?.apply {
|
getPet()?.apply {
|
||||||
mViewBinding.homeMapBluetoothBtn.isEnabled = false
|
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.JumpActivity, false)
|
||||||
intent.putExtra(ConstantString.Pet, this)
|
intent.putExtra(ConstantString.Pet, this)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
@@ -644,7 +677,7 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
getHomeV2Activity()?.let {
|
getHomeV2Activity()?.let {
|
||||||
it.getPet()?.apply {
|
it.getPet()?.apply {
|
||||||
mViewBinding.homeMapLiveBtn.isEnabled = false
|
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.JumpActivity, true)
|
||||||
intent.putExtra(ConstantString.Pet, this)
|
intent.putExtra(ConstantString.Pet, this)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
@@ -655,6 +688,15 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
llHomeMapTopPet.ivTopPetBtnSmall -> showMapTypeDialog()
|
llHomeMapTopPet.ivTopPetBtnSmall -> showMapTypeDialog()
|
||||||
homeMapBluetoothBtn -> checkPermissions(1)
|
homeMapBluetoothBtn -> checkPermissions(1)
|
||||||
llHomeMapTopPet.homeDataPetNameSmall, llHomeMapTopPet.homeDataPetHeadSmall.root -> getHomeV2Activity()?.selectPetDialog()
|
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.base.BaseFragment
|
||||||
import com.abbidot.tracker.bean.FencesBean
|
import com.abbidot.tracker.bean.FencesBean
|
||||||
import com.abbidot.tracker.bean.HistoryDataBean
|
import com.abbidot.tracker.bean.HistoryDataBean
|
||||||
|
import com.abbidot.tracker.bean.MapDeviceBean
|
||||||
import com.abbidot.tracker.constant.ConstantInt
|
import com.abbidot.tracker.constant.ConstantInt
|
||||||
import com.abbidot.tracker.databinding.FragmentGoogleMapBinding
|
import com.abbidot.tracker.databinding.FragmentGoogleMapBinding
|
||||||
import com.abbidot.tracker.util.ImageUtil
|
import com.abbidot.tracker.util.ImageUtil
|
||||||
@@ -392,13 +393,16 @@ abstract class BaseGoogleMapFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
//刷新当前位置ok,延时等待移动地图摄像头动画
|
//刷新当前位置ok,延时等待移动地图摄像头动画
|
||||||
if (isAnimMoveCamera) {
|
// if (isAnimMoveCamera) {
|
||||||
|
// mGoogleMapView.postDelayed({
|
||||||
|
// onRefreshPetCurrentLocationOk(mGoogleMap!!)
|
||||||
|
// }, 1000)
|
||||||
|
// } else {
|
||||||
|
// onRefreshPetCurrentLocationOk(mGoogleMap!!)
|
||||||
|
// }
|
||||||
mGoogleMapView.postDelayed({
|
mGoogleMapView.postDelayed({
|
||||||
onRefreshPetCurrentLocationOk(mGoogleMap!!)
|
onRefreshPetCurrentLocationOk(mGoogleMap!!)
|
||||||
}, 1000)
|
}, 500)
|
||||||
} else {
|
|
||||||
onRefreshPetCurrentLocationOk(mGoogleMap!!)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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.annotation.DrawableRes
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.isGone
|
import androidx.core.view.isGone
|
||||||
|
import androidx.core.view.isInvisible
|
||||||
import androidx.core.view.setPadding
|
import androidx.core.view.setPadding
|
||||||
import androidx.core.widget.addTextChangedListener
|
import androidx.core.widget.addTextChangedListener
|
||||||
import androidx.fragment.app.FragmentActivity
|
import androidx.fragment.app.FragmentActivity
|
||||||
@@ -1116,6 +1117,6 @@ class ViewUtil private constructor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun viewShow(view: View) {
|
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.content.Context
|
||||||
import android.os.CountDownTimer
|
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.MutableLiveData
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
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.Util
|
||||||
import com.abbidot.tracker.util.ViewUtil
|
import com.abbidot.tracker.util.ViewUtil
|
||||||
import com.abbidot.tracker.util.bluetooth.SRBleUtil
|
import com.abbidot.tracker.util.bluetooth.SRBleUtil
|
||||||
|
import com.abbidot.tracker.widget.TypefaceButton
|
||||||
|
import com.abbidot.tracker.widget.TypefaceTextView
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
class MapViewModel : ViewModel() {
|
class MapViewModel : ViewModel() {
|
||||||
@@ -28,8 +34,7 @@ class MapViewModel : ViewModel() {
|
|||||||
private var mRefreshDataMin = 0.5f
|
private var mRefreshDataMin = 0.5f
|
||||||
private var mDeviceId = ""
|
private var mDeviceId = ""
|
||||||
|
|
||||||
//警告动画是否结束
|
private var mDeviceMsgType = ConstantInt.SpecialType
|
||||||
private var isWarningAnimEnd = true
|
|
||||||
|
|
||||||
fun getMapDeviceStatus(deviceId: String, isNeedCountDown: Boolean = true) {
|
fun getMapDeviceStatus(deviceId: String, isNeedCountDown: Boolean = true) {
|
||||||
viewModelScope.launch {
|
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_width="match_parent"
|
||||||
android:layout_height="match_parent" />
|
android:layout_height="match_parent" />
|
||||||
|
|
||||||
<com.abbidot.tracker.widget.MapMarkerInfoView
|
|
||||||
android:id="@+id/mi_home_map_address_view"
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
android:layout_width="match_parent"
|
android:id="@+id/ll_home_map_device_battery_layout"
|
||||||
android:layout_height="match_parent" />
|
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
|
<RelativeLayout
|
||||||
@@ -29,13 +36,15 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="@dimen/dp_8" />
|
android:layout_marginTop="@dimen/dp_8" />
|
||||||
|
|
||||||
<androidx.recyclerview.widget.RecyclerView
|
<include
|
||||||
android:id="@+id/rv_home_map_device_msg"
|
android:id="@+id/il_home_map_device_msg"
|
||||||
|
layout="@layout/item_home_map_device_msg"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_below="@id/ll_home_map_top_pet"
|
android:layout_below="@id/ll_home_map_top_pet"
|
||||||
android:layout_centerInParent="true"
|
android:layout_centerInParent="true"
|
||||||
android:layout_marginTop="@dimen/dp_8" />
|
android:layout_marginTop="@dimen/dp_6"
|
||||||
|
android:visibility="gone" />
|
||||||
|
|
||||||
<com.abbidot.tracker.widget.NonSwipeRecyclerView
|
<com.abbidot.tracker.widget.NonSwipeRecyclerView
|
||||||
android:id="@+id/rv_home_map_device_state"
|
android:id="@+id/rv_home_map_device_state"
|
||||||
@@ -53,7 +62,8 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
android:layout_marginBottom="@dimen/dp_40" />
|
android:layout_marginBottom="@dimen/dp_38"
|
||||||
|
android:visibility="invisible" />
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:id="@+id/home_map_bluetooth_btn"
|
android:id="@+id/home_map_bluetooth_btn"
|
||||||
@@ -80,7 +90,7 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:paddingHorizontal="@dimen/dp_14"
|
android:paddingHorizontal="@dimen/dp_14"
|
||||||
android:paddingVertical="@dimen/dp_16"
|
android:paddingVertical="@dimen/dp_16"
|
||||||
android:visibility="visible">
|
android:visibility="invisible">
|
||||||
|
|
||||||
<androidx.appcompat.widget.AppCompatImageView
|
<androidx.appcompat.widget.AppCompatImageView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?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"
|
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_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
android:gravity="center">
|
android:gravity="center">
|
||||||
@@ -9,11 +9,22 @@
|
|||||||
<com.abbidot.tracker.widget.TypefaceButton
|
<com.abbidot.tracker.widget.TypefaceButton
|
||||||
android:id="@+id/tv_device_msg_content"
|
android:id="@+id/tv_device_msg_content"
|
||||||
style="@style/my_TextView_style_v2"
|
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:paddingHorizontal="@dimen/dp_18"
|
||||||
android:paddingVertical="@dimen/dp_12"
|
android:paddingVertical="@dimen/dp_12"
|
||||||
android:textColor="@color/data_black_color"
|
android:textColor="@color/data_black_color"
|
||||||
android:textSize="@dimen/textSize12"
|
android:textSize="@dimen/textSize12"
|
||||||
app:qmui_radius="@dimen/dp_28" />
|
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
|
<com.abbidot.tracker.widget.TypefaceTextView
|
||||||
|
android:id="@+id/tv_pet_location_update_time"
|
||||||
style="@style/my_TextView_style_v2"
|
style="@style/my_TextView_style_v2"
|
||||||
android:layout_below="@id/tv_pet_location_reverse_geocode"
|
android:layout_below="@id/tv_pet_location_reverse_geocode"
|
||||||
android:layout_alignParentEnd="true"
|
android:layout_alignParentEnd="true"
|
||||||
|
|||||||
@@ -796,7 +796,7 @@
|
|||||||
<string name="txt_hours">hours</string>
|
<string name="txt_hours">hours</string>
|
||||||
<string name="txt_search_device">Searching…</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_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_outside">Outside</string>
|
||||||
<string name="txt_inside">Inside</string>
|
<string name="txt_inside">Inside</string>
|
||||||
<string name="txt_7days_avg">7 Days Avg.</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_show_crash">The program has an exception and is about to exit</string>
|
||||||
|
|
||||||
<string name="txt_activate_subscribe">Activate Subscription</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>
|
</resources>
|
||||||
@@ -42,6 +42,8 @@ class Utils {
|
|||||||
const val DATE_FORMAT_PATTERN_EN8 = "hh:mm a"
|
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_EN9 = "MMM d, yyyy hh:mm a"
|
||||||
const val DATE_FORMAT_PATTERN_EN10 = "dd/MM/yyyy HH:mm:ss"
|
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"
|
const val WEEK_FORMAT_PATTERN = "E"
|
||||||
|
|||||||