1.处理轨迹经纬度飘和圆滑度
2.增加围栏缩放最小值提示 3.增加map和直播显示多宠物设置
This commit is contained in:
@@ -57,6 +57,11 @@ abstract class BaseDialog<T : ViewBinding>
|
|||||||
initView()
|
initView()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onStart() {
|
||||||
|
super.onStart()
|
||||||
|
// ✅ 每次显示都会执行(刷新数据、更新UI等)
|
||||||
|
}
|
||||||
|
|
||||||
abstract fun initView()
|
abstract fun initView()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -36,12 +36,14 @@ data class PetBean(
|
|||||||
var showDFUDialog: Boolean,//是否显示了固件升级弹窗
|
var showDFUDialog: Boolean,//是否显示了固件升级弹窗
|
||||||
var showNoWifiDialog: Boolean,//是否显示了没有设置wifi弹窗
|
var showNoWifiDialog: Boolean,//是否显示了没有设置wifi弹窗
|
||||||
var availableOrder: Int,//判断套餐是否可用或过期,1是可用 0不可用
|
var availableOrder: Int,//判断套餐是否可用或过期,1是可用 0不可用
|
||||||
|
var latitude: Double,
|
||||||
|
var longitude: Double,
|
||||||
var deviceId: String
|
var deviceId: String
|
||||||
) : Parcelable, BaseDiffBean() {
|
) : Parcelable, BaseDiffBean() {
|
||||||
constructor() : this(
|
constructor() : this(
|
||||||
"", "", "", "", 0, 1, MMKVUtil.getString(MMKVKey.UserId), "", 0, Utils.formatTime(
|
"", "", "", "", 0, 1, MMKVUtil.getString(MMKVKey.UserId), "", 0, Utils.formatTime(
|
||||||
System.currentTimeMillis(), Utils.DATE_FORMAT_PATTERN_CN
|
System.currentTimeMillis(), Utils.DATE_FORMAT_PATTERN_CN
|
||||||
), "", 0f, 0f, "", "", "", 1, 1, "", false, false, 1, ""
|
), "", 0f, 0f, "", "", "", 1, 1, "", false, false, 1, 0.0, 0.0, ""
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun isSameObject(other: Any): Boolean {
|
override fun isSameObject(other: Any): Boolean {
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import androidx.annotation.StringDef
|
|||||||
ConstantString.Upgrade,
|
ConstantString.Upgrade,
|
||||||
ConstantString.Password,
|
ConstantString.Password,
|
||||||
ConstantString.PackageUnitDay,
|
ConstantString.PackageUnitDay,
|
||||||
|
ConstantString.Lists,
|
||||||
ConstantString.PackageUnitMonth,
|
ConstantString.PackageUnitMonth,
|
||||||
ConstantString.PackageUnitYear,
|
ConstantString.PackageUnitYear,
|
||||||
ConstantString.SetMealIndex
|
ConstantString.SetMealIndex
|
||||||
@@ -95,6 +96,7 @@ annotation class ConstantString {
|
|||||||
const val Latitude = "latitude"
|
const val Latitude = "latitude"
|
||||||
const val Longitude = "longitude"
|
const val Longitude = "longitude"
|
||||||
const val isFirstBind = "isFirstBind"
|
const val isFirstBind = "isFirstBind"
|
||||||
|
const val Lists = "list"
|
||||||
|
|
||||||
const val isCheck = "isCheck"
|
const val isCheck = "isCheck"
|
||||||
const val Amount = "amount"
|
const val Amount = "amount"
|
||||||
|
|||||||
@@ -490,6 +490,10 @@ class FencesAddActivity : BaseActivity<ActivityFencesAddBinding>(ActivityFencesA
|
|||||||
override fun rectStartDragClick() {
|
override fun rectStartDragClick() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun rectMinSizeClick() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
override fun rectEndDragClick() {
|
override fun rectEndDragClick() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -504,6 +508,9 @@ class FencesAddActivity : BaseActivity<ActivityFencesAddBinding>(ActivityFencesA
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun circleMinSizeClick() {
|
||||||
|
}
|
||||||
|
|
||||||
override fun circleEndDragClick() {
|
override fun circleEndDragClick() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.abbidot.tracker.dialog
|
package com.abbidot.tracker.dialog
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.view.View
|
||||||
import android.widget.CompoundButton
|
import android.widget.CompoundButton
|
||||||
import com.abbidot.baselibrary.constant.MMKVKey
|
import com.abbidot.baselibrary.constant.MMKVKey
|
||||||
import com.abbidot.baselibrary.list.BaseRecyclerAdapter
|
import com.abbidot.baselibrary.list.BaseRecyclerAdapter
|
||||||
@@ -20,14 +21,16 @@ import com.abbidot.tracker.util.ViewUtil
|
|||||||
class SelectMapTypeDialog(
|
class SelectMapTypeDialog(
|
||||||
context: Context,
|
context: Context,
|
||||||
adapter: BaseRecyclerAdapter<*>,
|
adapter: BaseRecyclerAdapter<*>,
|
||||||
fenceCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null,
|
fenceCheckedListener: CompoundButton.OnCheckedChangeListener? = null,
|
||||||
dashedCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null
|
dashedCheckedListener: CompoundButton.OnCheckedChangeListener? = null,
|
||||||
|
showAllPetCheckedListener: CompoundButton.OnCheckedChangeListener? = null
|
||||||
) : BaseDialog<DialogSelectMapTypeLayoutBinding>(
|
) : BaseDialog<DialogSelectMapTypeLayoutBinding>(
|
||||||
DialogSelectMapTypeLayoutBinding::inflate, context
|
DialogSelectMapTypeLayoutBinding::inflate, context
|
||||||
) {
|
) {
|
||||||
private var mAdapter = adapter
|
private var mAdapter = adapter
|
||||||
private val mFenceCheckedChangeListener = fenceCheckedChangeListener
|
private val mFenceCheckedListener = fenceCheckedListener
|
||||||
private val mDashedCheckedChangeListener = dashedCheckedChangeListener
|
private val mDashedCheckedListener = dashedCheckedListener
|
||||||
|
private val mShowAllPetCheckedListener = showAllPetCheckedListener
|
||||||
|
|
||||||
override fun initView() {
|
override fun initView() {
|
||||||
mViewBinding.apply {
|
mViewBinding.apply {
|
||||||
@@ -35,13 +38,15 @@ class SelectMapTypeDialog(
|
|||||||
context, rvShowMapTypeList, mAdapter, right = AppUtils.dpToPx(58)
|
context, rvShowMapTypeList, mAdapter, right = AppUtils.dpToPx(58)
|
||||||
)
|
)
|
||||||
cbDialogMapFencesSwitch.isChecked = Util.getShowFenceSp()
|
cbDialogMapFencesSwitch.isChecked = Util.getShowFenceSp()
|
||||||
cbDialogMapDashedLineSwitch.isChecked =
|
cbDialogMapDashedLineSwitch.isChecked = MMKVUtil.getBoolean(MMKVKey.ShowDashedLine)
|
||||||
MMKVUtil.getBoolean(MMKVKey.ShowDashedLine, false)
|
cbDialogMapAllPetSwitch.isChecked = MMKVUtil.getBoolean(MMKVKey.ShowAllPet)
|
||||||
cbDialogMapFencesSwitch.setOnCheckedChangeListener(mFenceCheckedChangeListener)
|
cbDialogMapFencesSwitch.setOnCheckedChangeListener(mFenceCheckedListener)
|
||||||
cbDialogMapDashedLineSwitch.setOnCheckedChangeListener(mDashedCheckedChangeListener)
|
cbDialogMapDashedLineSwitch.setOnCheckedChangeListener(mDashedCheckedListener)
|
||||||
|
cbDialogMapAllPetSwitch.setOnCheckedChangeListener(mShowAllPetCheckedListener)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 检测地图类型有没有改变
|
* 检测地图类型有没有改变
|
||||||
*/
|
*/
|
||||||
@@ -69,4 +74,12 @@ class SelectMapTypeDialog(
|
|||||||
fun setDashedSwitch(checked: Boolean) {
|
fun setDashedSwitch(checked: Boolean) {
|
||||||
mViewBinding.cbDialogMapDashedLineSwitch.isChecked = checked
|
mViewBinding.cbDialogMapDashedLineSwitch.isChecked = checked
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setShowAllPetSwitch(checked: Boolean) {
|
||||||
|
mViewBinding.cbDialogMapAllPetSwitch.isChecked = checked
|
||||||
|
}
|
||||||
|
|
||||||
|
fun showAllPetSwitch(isShow: Boolean) {
|
||||||
|
mViewBinding.llMapTypeShowAllPetSwitch.visibility = if (isShow) View.VISIBLE else View.GONE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -8,6 +8,7 @@ import android.net.Network
|
|||||||
import android.net.NetworkCapabilities
|
import android.net.NetworkCapabilities
|
||||||
import android.net.NetworkRequest
|
import android.net.NetworkRequest
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
|
import android.view.Gravity
|
||||||
import android.view.MenuItem
|
import android.view.MenuItem
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
@@ -92,7 +93,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
|||||||
var mSelectPetPosition = 0
|
var mSelectPetPosition = 0
|
||||||
|
|
||||||
//宠物数据
|
//宠物数据
|
||||||
lateinit var mPetList: MutableList<PetBean>
|
val mPetList = mutableListOf<PetBean>()
|
||||||
private var isFirst = true
|
private var isFirst = true
|
||||||
|
|
||||||
//是否请求过宠物数据
|
//是否请求过宠物数据
|
||||||
@@ -163,7 +164,6 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
|||||||
it.itemIconTintList = null
|
it.itemIconTintList = null
|
||||||
it.setOnItemSelectedListener(this)
|
it.setOnItemSelectedListener(this)
|
||||||
}
|
}
|
||||||
mPetList = mutableListOf()
|
|
||||||
mChangePetListDialogAdapter = ChangePetListDialogAdapter(mContext, mPetList).apply {
|
mChangePetListDialogAdapter = ChangePetListDialogAdapter(mContext, mPetList).apply {
|
||||||
setOnChangeClickListener(this@HomeV2Activity)
|
setOnChangeClickListener(this@HomeV2Activity)
|
||||||
}
|
}
|
||||||
@@ -175,7 +175,7 @@ class HomeV2Activity : BaseActivity<ActivityHomeV2Binding>(ActivityHomeV2Binding
|
|||||||
val isCrash = MMKVUtil.getBoolean(MMKVKey.isCrash, false)
|
val isCrash = MMKVUtil.getBoolean(MMKVKey.isCrash, false)
|
||||||
if (isCrash) {
|
if (isCrash) {
|
||||||
MMKVUtil.putBoolean(MMKVKey.isCrash, false)
|
MMKVUtil.putBoolean(MMKVKey.isCrash, false)
|
||||||
showToast(R.string.txt_show_crash)
|
showToast(R.string.txt_show_crash, gravity = Gravity.CENTER)
|
||||||
mCountdownType = ConstantInt.Type0
|
mCountdownType = ConstantInt.Type0
|
||||||
mCountDownTimerViewModel.startCountDown(4)
|
mCountDownTimerViewModel.startCountDown(4)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -838,6 +838,11 @@ open class AddAndEditFencesZoneBaseActivity :
|
|||||||
mFencesBean.startDrag = true
|
mFencesBean.startDrag = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun rectMinSizeClick() {
|
||||||
|
if (isLimitClick()) return
|
||||||
|
showToast(R.string.txt_already_min_size, gravity = Gravity.CENTER)
|
||||||
|
}
|
||||||
|
|
||||||
override fun rectEndDragClick() {
|
override fun rectEndDragClick() {
|
||||||
mFencesBean.startDrag = false
|
mFencesBean.startDrag = false
|
||||||
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
|
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
|
||||||
@@ -855,6 +860,11 @@ open class AddAndEditFencesZoneBaseActivity :
|
|||||||
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
|
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun circleMinSizeClick() {
|
||||||
|
if (isLimitClick()) return
|
||||||
|
showToast(R.string.txt_already_min_size, gravity = Gravity.CENTER)
|
||||||
|
}
|
||||||
|
|
||||||
override fun circleEndDragClick() {
|
override fun circleEndDragClick() {
|
||||||
mFencesBean.startDrag = false
|
mFencesBean.startDrag = false
|
||||||
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
|
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
|
||||||
@@ -868,6 +878,11 @@ open class AddAndEditFencesZoneBaseActivity :
|
|||||||
mFencesBean.startDrag = true
|
mFencesBean.startDrag = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun polygonMinSizeClick() {
|
||||||
|
if (isLimitClick()) return
|
||||||
|
showToast(R.string.txt_already_min_size, gravity = Gravity.CENTER)
|
||||||
|
}
|
||||||
|
|
||||||
override fun polygonEndDragClick() {
|
override fun polygonEndDragClick() {
|
||||||
mFencesBean.startDrag = false
|
mFencesBean.startDrag = false
|
||||||
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
|
mFencesMapCommon.calculateDistanceAndGetPointLatLng(delayMillis = 0)
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ class LiveActivityV3 : BaseActivity<ActivityLiveV3Binding>(ActivityLiveV3Binding
|
|||||||
//是否显示虚线
|
//是否显示虚线
|
||||||
private var isShowDashed = true
|
private var isShowDashed = true
|
||||||
|
|
||||||
|
//是否显示所有宠物
|
||||||
|
private var isShowAllPet = false
|
||||||
|
|
||||||
//地图类型,标准和卫星地图
|
//地图类型,标准和卫星地图
|
||||||
private var mMapType = ConstantInt.Type0
|
private var mMapType = ConstantInt.Type0
|
||||||
private var mShowCenterLocation = ConstantInt.PetLocationType
|
private var mShowCenterLocation = ConstantInt.PetLocationType
|
||||||
@@ -102,6 +105,7 @@ class LiveActivityV3 : BaseActivity<ActivityLiveV3Binding>(ActivityLiveV3Binding
|
|||||||
private var isLiveJump = true
|
private var isLiveJump = true
|
||||||
private var mLiveStatus = 1
|
private var mLiveStatus = 1
|
||||||
private var mPetBean: PetBean? = null
|
private var mPetBean: PetBean? = null
|
||||||
|
private var mPetList: MutableList<PetBean>? = null
|
||||||
private var mTrackBleDevice: BleTrackDeviceBean? = null
|
private var mTrackBleDevice: BleTrackDeviceBean? = null
|
||||||
|
|
||||||
//直播是否开始
|
//直播是否开始
|
||||||
@@ -138,10 +142,14 @@ class LiveActivityV3 : BaseActivity<ActivityLiveV3Binding>(ActivityLiveV3Binding
|
|||||||
isCloseMsg = getBoolean(ConstantString.PetAuthorized)
|
isCloseMsg = getBoolean(ConstantString.PetAuthorized)
|
||||||
mMapViewModel.mDeviceMsgType = getInt(ConstantString.Type, ConstantInt.SpecialType)
|
mMapViewModel.mDeviceMsgType = getInt(ConstantString.Type, ConstantInt.SpecialType)
|
||||||
mPetBean = Util.getParcelableAdaptive(intent, ConstantString.Pet, PetBean::class.java)
|
mPetBean = Util.getParcelableAdaptive(intent, ConstantString.Pet, PetBean::class.java)
|
||||||
|
mPetList = Util.getParcelableArrayListAdaptive(
|
||||||
|
intent, ConstantString.Lists, PetBean::class.java
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
isShowFence = Util.getShowFenceSp()
|
isShowFence = Util.getShowFenceSp()
|
||||||
isShowDashed = MMKVUtil.getBoolean(MMKVKey.ShowDashedLine, false)
|
isShowDashed = MMKVUtil.getBoolean(MMKVKey.ShowDashedLine)
|
||||||
|
isShowAllPet = MMKVUtil.getBoolean(MMKVKey.ShowAllPet)
|
||||||
|
|
||||||
mViewBinding.apply {
|
mViewBinding.apply {
|
||||||
ViewUtil.instance.viewRotationAnimator(
|
ViewUtil.instance.viewRotationAnimator(
|
||||||
@@ -314,6 +322,10 @@ class LiveActivityV3 : BaseActivity<ActivityLiveV3Binding>(ActivityLiveV3Binding
|
|||||||
mDeviceStateList,
|
mDeviceStateList,
|
||||||
mDeviceStateAdapter
|
mDeviceStateAdapter
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if (MMKVUtil.getBoolean(MMKVKey.ShowAllPet)) {
|
||||||
|
setAllPetShow(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -808,13 +820,43 @@ class LiveActivityV3 : BaseActivity<ActivityLiveV3Binding>(ActivityLiveV3Binding
|
|||||||
} else {
|
} else {
|
||||||
mHomeMapCommon.removeUserAndPetLine()
|
mHomeMapCommon.removeUserAndPetLine()
|
||||||
}
|
}
|
||||||
})
|
},
|
||||||
|
{ _, isChecked ->
|
||||||
|
setAllPetShow(isChecked)
|
||||||
|
}).apply {
|
||||||
|
setOnShowListener {
|
||||||
|
mPetList?.let {
|
||||||
|
if (it.size > 1) mSelectMapTypeDialog?.showAllPetSwitch(true)
|
||||||
|
else mSelectMapTypeDialog?.showAllPetSwitch(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
mSelectMapTypeDialog!!.mapTypeSpToUpdate()
|
mSelectMapTypeDialog!!.mapTypeSpToUpdate()
|
||||||
}
|
}
|
||||||
mSelectMapTypeDialog?.show()
|
mSelectMapTypeDialog?.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置多宠物显示
|
||||||
|
*/
|
||||||
|
private fun setAllPetShow(isShow: Boolean) {
|
||||||
|
isShowAllPet = isShow
|
||||||
|
MMKVUtil.putBoolean(MMKVKey.ShowAllPet, isShow)
|
||||||
|
if (isShow) {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
mPetList?.apply {
|
||||||
|
mPetBean?.let { p ->
|
||||||
|
//删除当前选中宠物
|
||||||
|
mHomeMapCommon.showOtherPetHeadMarker(filter { it != p }.toMutableList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mHomeMapCommon.clearOtherPetHeadMarker()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置地图相关数据
|
* 设置地图相关数据
|
||||||
*/
|
*/
|
||||||
@@ -928,7 +970,7 @@ class LiveActivityV3 : BaseActivity<ActivityLiveV3Binding>(ActivityLiveV3Binding
|
|||||||
it.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
|
it.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0)
|
||||||
}
|
}
|
||||||
mViewBinding.llLiveV2MapTopPet.homeDataPetHeadSmall.appHeadImage.let {
|
mViewBinding.llLiveV2MapTopPet.homeDataPetHeadSmall.appHeadImage.let {
|
||||||
ViewUtil.instance.setPetTypeHead(mContext,it, imgurl, petType)
|
ViewUtil.instance.setPetTypeHead(mContext, it, imgurl, petType)
|
||||||
ViewUtil.instance.viewAlphaAndRotationObjectAnimator(it)
|
ViewUtil.instance.viewAlphaAndRotationObjectAnimator(it)
|
||||||
}
|
}
|
||||||
//重新设置地图宠物头像
|
//重新设置地图宠物头像
|
||||||
|
|||||||
@@ -6,9 +6,11 @@ import androidx.fragment.app.Fragment
|
|||||||
import com.abbidot.baselibrary.constant.MMKVKey
|
import com.abbidot.baselibrary.constant.MMKVKey
|
||||||
import com.abbidot.baselibrary.util.AppUtils
|
import com.abbidot.baselibrary.util.AppUtils
|
||||||
import com.abbidot.baselibrary.util.MMKVUtil
|
import com.abbidot.baselibrary.util.MMKVUtil
|
||||||
|
import com.abbidot.tracker.R
|
||||||
import com.abbidot.tracker.base.BaseMapCommon
|
import com.abbidot.tracker.base.BaseMapCommon
|
||||||
import com.abbidot.tracker.bean.HistoryDataBean
|
import com.abbidot.tracker.bean.HistoryDataBean
|
||||||
import com.abbidot.tracker.bean.MapDeviceBean
|
import com.abbidot.tracker.bean.MapDeviceBean
|
||||||
|
import com.abbidot.tracker.bean.PetBean
|
||||||
import com.abbidot.tracker.constant.ConstantInt
|
import com.abbidot.tracker.constant.ConstantInt
|
||||||
import com.abbidot.tracker.databinding.LayoutPetLocationInfoBinding
|
import com.abbidot.tracker.databinding.LayoutPetLocationInfoBinding
|
||||||
import com.abbidot.tracker.ui.fragment.map.baidumap.HomeMapBaiduMapFragment
|
import com.abbidot.tracker.ui.fragment.map.baidumap.HomeMapBaiduMapFragment
|
||||||
@@ -206,6 +208,18 @@ class HomeMapCommonV3 @Inject constructor() : BaseMapCommon() {
|
|||||||
mHomeMapGoogleMapFragment?.removeUserAndPetLine()
|
mHomeMapGoogleMapFragment?.removeUserAndPetLine()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun showOtherPetHeadMarker(
|
||||||
|
petList: MutableList<PetBean>, headBgResId: Int = R.drawable.pic_map_gps_avatar
|
||||||
|
) {
|
||||||
|
if (petList.size > 0) {
|
||||||
|
mHomeMapGoogleMapFragment?.showOtherPetHeadMarker(petList, headBgResId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun clearOtherPetHeadMarker() {
|
||||||
|
mHomeMapGoogleMapFragment?.clearOtherPetHeadMarker()
|
||||||
|
}
|
||||||
|
|
||||||
// fun getAddressShowMarkerInfoWindow(historyDataBean: HistoryDataBean) {
|
// fun getAddressShowMarkerInfoWindow(historyDataBean: HistoryDataBean) {
|
||||||
// if (null != mHomeMapBaiduMapFragment) {
|
// if (null != mHomeMapBaiduMapFragment) {
|
||||||
// mHomeMapBaiduMapFragment!!.showMarkerInfoWindow(historyDataBean)
|
// mHomeMapBaiduMapFragment!!.showMarkerInfoWindow(historyDataBean)
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import androidx.core.view.WindowInsetsCompat
|
|||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.commit
|
import androidx.fragment.app.commit
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.abbidot.baselibrary.constant.ConState
|
import com.abbidot.baselibrary.constant.ConState
|
||||||
import com.abbidot.baselibrary.constant.EventName
|
import com.abbidot.baselibrary.constant.EventName
|
||||||
import com.abbidot.baselibrary.constant.MMKVKey
|
import com.abbidot.baselibrary.constant.MMKVKey
|
||||||
@@ -61,6 +62,7 @@ import com.google.android.gms.maps.model.LatLng
|
|||||||
import com.hjq.permissions.XXPermissions
|
import com.hjq.permissions.XXPermissions
|
||||||
import com.hjq.permissions.permission.PermissionLists
|
import com.hjq.permissions.permission.PermissionLists
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
|
||||||
@@ -91,8 +93,6 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
|
|
||||||
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 mDeviceMsgAdapter: HomeMapDeviceMsgAdapter
|
|
||||||
|
|
||||||
//启动移动地图摄像机
|
//启动移动地图摄像机
|
||||||
private var isMoveCamera = true
|
private var isMoveCamera = true
|
||||||
@@ -102,7 +102,10 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
private var isShowFence = true
|
private var isShowFence = true
|
||||||
|
|
||||||
//是否显示虚线
|
//是否显示虚线
|
||||||
private var isShowDashed = true
|
private var isShowDashed = false
|
||||||
|
|
||||||
|
//是否显示所有宠物
|
||||||
|
private var isShowAllPet = false
|
||||||
|
|
||||||
//地图类型,标准和卫星地图
|
//地图类型,标准和卫星地图
|
||||||
private var mMapType = ConstantInt.Type0
|
private var mMapType = ConstantInt.Type0
|
||||||
@@ -112,6 +115,8 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
|
|
||||||
//是否需要gps坐标转火星坐标
|
//是否需要gps坐标转火星坐标
|
||||||
private var needGpsToGCJ02 = true
|
private var needGpsToGCJ02 = true
|
||||||
|
|
||||||
|
//一键定位绿波动画
|
||||||
private var mAnimatorSet: AnimatorSet? = null
|
private var mAnimatorSet: AnimatorSet? = null
|
||||||
|
|
||||||
//一键定位开始的时间戳
|
//一键定位开始的时间戳
|
||||||
@@ -131,7 +136,8 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
}
|
}
|
||||||
|
|
||||||
isShowFence = Util.getShowFenceSp()
|
isShowFence = Util.getShowFenceSp()
|
||||||
isShowDashed = MMKVUtil.getBoolean(MMKVKey.ShowDashedLine, false)
|
isShowDashed = MMKVUtil.getBoolean(MMKVKey.ShowDashedLine)
|
||||||
|
isShowAllPet = MMKVUtil.getBoolean(MMKVKey.ShowAllPet)
|
||||||
|
|
||||||
mViewBinding.apply {
|
mViewBinding.apply {
|
||||||
getHomeV2Activity()?.edgeToEdgeAdapterBars(
|
getHomeV2Activity()?.edgeToEdgeAdapterBars(
|
||||||
@@ -220,7 +226,8 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
}
|
}
|
||||||
|
|
||||||
val showFence = Util.getShowFenceSp()
|
val showFence = Util.getShowFenceSp()
|
||||||
val showDashed = MMKVUtil.getBoolean(MMKVKey.ShowDashedLine, false)
|
val showDashed = MMKVUtil.getBoolean(MMKVKey.ShowDashedLine)
|
||||||
|
val showAllPet = MMKVUtil.getBoolean(MMKVKey.ShowAllPet)
|
||||||
//检测直播页面有没有修改围栏显示
|
//检测直播页面有没有修改围栏显示
|
||||||
if (isShowFence != showFence) {
|
if (isShowFence != showFence) {
|
||||||
if (null == mSelectMapTypeDialog) {
|
if (null == mSelectMapTypeDialog) {
|
||||||
@@ -236,6 +243,13 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
mSelectMapTypeDialog?.setDashedSwitch(showDashed)
|
mSelectMapTypeDialog?.setDashedSwitch(showDashed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isShowAllPet != showAllPet) {
|
||||||
|
if (null == mSelectMapTypeDialog) {
|
||||||
|
setAllPetShow(showAllPet)
|
||||||
|
} else {
|
||||||
|
mSelectMapTypeDialog?.setShowAllPetSwitch(showDashed)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getHomeV2Activity(): HomeV2Activity? {
|
private fun getHomeV2Activity(): HomeV2Activity? {
|
||||||
@@ -600,20 +614,29 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
* 显示地图类型选择弹窗
|
* 显示地图类型选择弹窗
|
||||||
*/
|
*/
|
||||||
private fun showMapTypeDialog() {
|
private fun showMapTypeDialog() {
|
||||||
if (null == mSelectMapTypeDialog) mSelectMapTypeDialog = ViewUtil.instance.getMapTypeDialog(
|
if (null == mSelectMapTypeDialog) {
|
||||||
mContext!!, object : BaseRecyclerAdapter.OnItemClickListener {
|
mSelectMapTypeDialog = ViewUtil.instance.getMapTypeDialog(
|
||||||
override fun onItemClick(itemView: View?, pos: Int) {
|
mContext!!, object : BaseRecyclerAdapter.OnItemClickListener {
|
||||||
mMapType = Util.getMapTypeSp()
|
override fun onItemClick(itemView: View?, pos: Int) {
|
||||||
if (pos == mMapType) {
|
mMapType = Util.getMapTypeSp()
|
||||||
return
|
if (pos == mMapType) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mHomeMapCommon.switchSatelliteAndNormalMapType()
|
||||||
|
}
|
||||||
|
}, this, this, this
|
||||||
|
).apply {
|
||||||
|
setOnShowListener {
|
||||||
|
getHomeV2Activity()?.apply {
|
||||||
|
if (mPetList.size > 1) mSelectMapTypeDialog?.showAllPetSwitch(true)
|
||||||
|
else mSelectMapTypeDialog?.showAllPetSwitch(false)
|
||||||
}
|
}
|
||||||
mHomeMapCommon.switchSatelliteAndNormalMapType()
|
|
||||||
}
|
}
|
||||||
}, this, this
|
}
|
||||||
)
|
} else {
|
||||||
else {
|
|
||||||
mSelectMapTypeDialog!!.mapTypeSpToUpdate()
|
mSelectMapTypeDialog!!.mapTypeSpToUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
mSelectMapTypeDialog?.show()
|
mSelectMapTypeDialog?.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -645,6 +668,27 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置多宠物显示
|
||||||
|
*/
|
||||||
|
private fun setAllPetShow(isShow: Boolean) {
|
||||||
|
isShowAllPet = isShow
|
||||||
|
MMKVUtil.putBoolean(MMKVKey.ShowAllPet, isShow)
|
||||||
|
if (isShow) {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
getHomeV2Activity()?.apply {
|
||||||
|
getPet(false)?.let { p ->
|
||||||
|
//删除当前选中宠物
|
||||||
|
mHomeMapCommon.showOtherPetHeadMarker(mPetList.filter { it != p }
|
||||||
|
.toMutableList())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mHomeMapCommon.clearOtherPetHeadMarker()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置需要更新的标识
|
* 设置需要更新的标识
|
||||||
*/
|
*/
|
||||||
@@ -755,6 +799,9 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
if (isShowDashed) {
|
if (isShowDashed) {
|
||||||
mHomeMapCommon.addUserAndPetLine()
|
mHomeMapCommon.addUserAndPetLine()
|
||||||
}
|
}
|
||||||
|
if (isShowAllPet) {
|
||||||
|
setAllPetShow(true)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -951,6 +998,9 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
getPet()?.apply {
|
getPet()?.apply {
|
||||||
val intent = Intent(mContext, LiveActivityV3::class.java)
|
val intent = Intent(mContext, LiveActivityV3::class.java)
|
||||||
intent.putExtra(ConstantString.JumpActivity, isLiveJump)
|
intent.putExtra(ConstantString.JumpActivity, isLiveJump)
|
||||||
|
intent.putParcelableArrayListExtra(
|
||||||
|
ConstantString.Lists, mPetList.toCollection(ArrayList())
|
||||||
|
)
|
||||||
intent.putExtra(ConstantString.Pet, this)
|
intent.putExtra(ConstantString.Pet, this)
|
||||||
mMapDeviceBean?.let {
|
mMapDeviceBean?.let {
|
||||||
intent.putExtra(ConstantString.DeviceAuthorized, it.isCloseBattery)
|
intent.putExtra(ConstantString.DeviceAuthorized, it.isCloseBattery)
|
||||||
@@ -1056,6 +1106,7 @@ class MapV3Fragment : BaseFragment<FragmentMapV3Binding>(FragmentMapV3Binding::i
|
|||||||
when (v.id) {
|
when (v.id) {
|
||||||
R.id.cb_dialog_map_fences_switch -> setFencesShow(isChecked)
|
R.id.cb_dialog_map_fences_switch -> setFencesShow(isChecked)
|
||||||
R.id.cb_dialog_map_dashed_line_switch -> setDashedShow(isChecked)
|
R.id.cb_dialog_map_dashed_line_switch -> setDashedShow(isChecked)
|
||||||
|
R.id.cb_dialog_map_all_pet_switch -> setAllPetShow(isChecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.abbidot.tracker.databinding.FragmentBaseBaiduMapBinding
|
|||||||
import com.abbidot.tracker.ui.fragment.map.googlemap.GoogleBitmapHelper
|
import com.abbidot.tracker.ui.fragment.map.googlemap.GoogleBitmapHelper
|
||||||
import com.abbidot.tracker.util.ImageUtil
|
import com.abbidot.tracker.util.ImageUtil
|
||||||
import com.abbidot.tracker.util.LonAndLatUtil
|
import com.abbidot.tracker.util.LonAndLatUtil
|
||||||
|
import com.abbidot.tracker.util.Util.Companion.safeRecycle
|
||||||
import com.abbidot.tracker.widget.TypefaceTextView
|
import com.abbidot.tracker.widget.TypefaceTextView
|
||||||
import com.baidu.location.BDAbstractLocationListener
|
import com.baidu.location.BDAbstractLocationListener
|
||||||
import com.baidu.location.BDLocation
|
import com.baidu.location.BDLocation
|
||||||
@@ -218,7 +219,7 @@ abstract class BaseBaiduMapFragment :
|
|||||||
*/
|
*/
|
||||||
fun setPetHeadIconUrl(petHeadUrl: String) {
|
fun setPetHeadIconUrl(petHeadUrl: String) {
|
||||||
mPetHeadUrl = petHeadUrl
|
mPetHeadUrl = petHeadUrl
|
||||||
mPetHeadIconBitmap?.recycle()
|
mPetHeadIconBitmap.safeRecycle()
|
||||||
mPetHeadIconBitmap = null
|
mPetHeadIconBitmap = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,20 +248,21 @@ abstract class BaseBaiduMapFragment :
|
|||||||
headBgResId: Int = R.drawable.pic_map_gps_avatar
|
headBgResId: Int = R.drawable.pic_map_gps_avatar
|
||||||
) {
|
) {
|
||||||
|
|
||||||
val mapKey = if (TextUtils.isEmpty(mPetHeadUrl)) "pet_default_head"
|
// val mapKey = if (TextUtils.isEmpty(mPetHeadUrl)) "pet_default_head"
|
||||||
else mPetHeadUrl.substring(mPetHeadUrl.lastIndexOf("/") + 1, mPetHeadUrl.length)
|
// else mPetHeadUrl.substring(mPetHeadUrl.lastIndexOf("/") + 1, mPetHeadUrl.length)
|
||||||
var bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
|
// var bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
|
||||||
if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
|
// if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
|
||||||
if (null == mPetHeadIconBitmap) {
|
// if (null == mPetHeadIconBitmap) {
|
||||||
//设置头像
|
// //设置头像
|
||||||
mPetHeadIconBitmap =
|
// mPetHeadIconBitmap =
|
||||||
GoogleBitmapHelper.headToBitmap(mContext!!, headBgResId, mPetHeadUrl, mPetType)
|
// GoogleBitmapHelper.headToBitmap(mContext!!, headBgResId, mPetHeadUrl, mPetType)
|
||||||
}
|
// }
|
||||||
bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(mPetHeadIconBitmap!!)
|
// bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(mPetHeadIconBitmap!!)
|
||||||
//保存在内存中,提高显示速度
|
// //保存在内存中,提高显示速度
|
||||||
MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor
|
// MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor
|
||||||
}
|
// }
|
||||||
|
val bitmapDescriptor =
|
||||||
|
getMarkerBitmapDescriptor(mContext!!, mPetHeadUrl, mPetType, headBgResId)
|
||||||
mMarker?.remove()
|
mMarker?.remove()
|
||||||
val latLng = getBaiduMapLatLng(lat, lon, needConvertGCJ02)
|
val latLng = getBaiduMapLatLng(lat, lon, needConvertGCJ02)
|
||||||
mPetLatLng = latLng
|
mPetLatLng = latLng
|
||||||
@@ -272,6 +274,42 @@ abstract class BaseBaiduMapFragment :
|
|||||||
mMarker = mBaiduMap!!.addOverlay(option)
|
mMarker = mBaiduMap!!.addOverlay(option)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private suspend fun getMarkerBitmapDescriptor(
|
||||||
|
context: Context,
|
||||||
|
headUrl: String,
|
||||||
|
petType: Int,
|
||||||
|
headBgResId: Int = R.drawable.pic_map_gps_avatar
|
||||||
|
): BitmapDescriptor? {
|
||||||
|
var bitmap: Bitmap? = null
|
||||||
|
var bitmapDescriptor: Any?
|
||||||
|
try {
|
||||||
|
val mapKey = if (TextUtils.isEmpty(headUrl)) {
|
||||||
|
"pet_default_head"
|
||||||
|
} else {
|
||||||
|
val idx = headUrl.lastIndexOf("/")
|
||||||
|
if (idx != -1) {
|
||||||
|
headUrl.substring(idx + 1)
|
||||||
|
} else {
|
||||||
|
headUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LogUtil.e("mapKey=$mapKey")
|
||||||
|
bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
|
||||||
|
if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
|
||||||
|
bitmap = GoogleBitmapHelper.headToBitmap(context, headBgResId, headUrl, petType)
|
||||||
|
bitmap?.let {
|
||||||
|
bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(it)
|
||||||
|
//保存在内存中,提高显示速度
|
||||||
|
MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor as BitmapDescriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
bitmap.safeRecycle()
|
||||||
|
}
|
||||||
|
// 把 return 写在 finally 外面
|
||||||
|
return bitmapDescriptor as? BitmapDescriptor
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 地图添加图片
|
* 地图添加图片
|
||||||
*/
|
*/
|
||||||
@@ -853,7 +891,8 @@ abstract class BaseBaiduMapFragment :
|
|||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
mSensorManager?.unregisterListener(mSensorEventListener)
|
mSensorManager?.unregisterListener(mSensorEventListener)
|
||||||
mPetHeadIconBitmap?.recycle()
|
mPetHeadIconBitmap.safeRecycle()
|
||||||
|
mPetHeadIconBitmap = null
|
||||||
stopLocation()
|
stopLocation()
|
||||||
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
|
//在activity执行onDestroy时执行mMapView.onDestroy(),实现地图生命周期管理
|
||||||
mMapView.onDestroy()
|
mMapView.onDestroy()
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import android.graphics.Bitmap
|
|||||||
import android.graphics.Point
|
import android.graphics.Point
|
||||||
import android.location.Location
|
import android.location.Location
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.TextUtils
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
@@ -19,7 +18,6 @@ import com.abbidot.baselibrary.constant.MMKVKey
|
|||||||
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.tracker.MyApplication
|
|
||||||
import com.abbidot.tracker.R
|
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
|
||||||
@@ -30,6 +28,7 @@ import com.abbidot.tracker.databinding.FragmentGoogleMapBinding
|
|||||||
import com.abbidot.tracker.util.ImageUtil
|
import com.abbidot.tracker.util.ImageUtil
|
||||||
import com.abbidot.tracker.util.LonAndLatUtil
|
import com.abbidot.tracker.util.LonAndLatUtil
|
||||||
import com.abbidot.tracker.util.Util
|
import com.abbidot.tracker.util.Util
|
||||||
|
import com.abbidot.tracker.util.Util.Companion.safeRecycle
|
||||||
import com.abbidot.tracker.util.ViewUtil
|
import com.abbidot.tracker.util.ViewUtil
|
||||||
import com.abbidot.tracker.widget.MapDeviceNetView
|
import com.abbidot.tracker.widget.MapDeviceNetView
|
||||||
import com.abbidot.tracker.widget.MapMarkerInfoView
|
import com.abbidot.tracker.widget.MapMarkerInfoView
|
||||||
@@ -42,7 +41,6 @@ import com.google.android.gms.maps.GoogleMap
|
|||||||
import com.google.android.gms.maps.GoogleMapOptions
|
import com.google.android.gms.maps.GoogleMapOptions
|
||||||
import com.google.android.gms.maps.MapView
|
import com.google.android.gms.maps.MapView
|
||||||
import com.google.android.gms.maps.OnMapReadyCallback
|
import com.google.android.gms.maps.OnMapReadyCallback
|
||||||
import com.google.android.gms.maps.model.BitmapDescriptor
|
|
||||||
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
||||||
import com.google.android.gms.maps.model.CameraPosition
|
import com.google.android.gms.maps.model.CameraPosition
|
||||||
import com.google.android.gms.maps.model.Circle
|
import com.google.android.gms.maps.model.Circle
|
||||||
@@ -65,6 +63,12 @@ import com.google.android.gms.tasks.CancellationTokenSource
|
|||||||
import com.google.android.gms.tasks.Task
|
import com.google.android.gms.tasks.Task
|
||||||
import com.qmuiteam.qmui.util.QMUIDisplayHelper
|
import com.qmuiteam.qmui.util.QMUIDisplayHelper
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlin.math.PI
|
||||||
|
import kotlin.math.atan2
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.pow
|
||||||
|
import kotlin.math.sin
|
||||||
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -97,7 +101,7 @@ abstract class BaseGoogleMapFragment :
|
|||||||
var mMarker: Marker? = null
|
var mMarker: Marker? = null
|
||||||
|
|
||||||
//自定显示用户地点信息图层
|
//自定显示用户地点信息图层
|
||||||
var mUserMarker: Marker? = null
|
private var mUserMarker: Marker? = null
|
||||||
|
|
||||||
//宠物大头针设置自定义头像
|
//宠物大头针设置自定义头像
|
||||||
private var mPetHeadIconBitmap: Bitmap? = null
|
private var mPetHeadIconBitmap: Bitmap? = null
|
||||||
@@ -318,9 +322,13 @@ abstract class BaseGoogleMapFragment :
|
|||||||
}
|
}
|
||||||
|
|
||||||
ConstantInt.UserLocationType -> {
|
ConstantInt.UserLocationType -> {
|
||||||
mPetLatLng?.let {
|
if (null == mPetLatLng) {
|
||||||
mUserLatLng?.apply {
|
mUserLatLng?.apply {
|
||||||
setLatLngZoom(mContext!!, 250, it, this)
|
moveCameraLocation(this)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mUserLatLng?.apply {
|
||||||
|
setLatLngZoom(mContext!!, 250, mPetLatLng!!, this)
|
||||||
cameraUpdateMove()
|
cameraUpdateMove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,7 +376,7 @@ abstract class BaseGoogleMapFragment :
|
|||||||
fun setPetHeadIconUrl(petHeadUrl: String, petType: Int) {
|
fun setPetHeadIconUrl(petHeadUrl: String, petType: Int) {
|
||||||
mPetHeadUrl = petHeadUrl
|
mPetHeadUrl = petHeadUrl
|
||||||
mPetType = petType
|
mPetType = petType
|
||||||
mPetHeadIconBitmap?.recycle()
|
mPetHeadIconBitmap.safeRecycle()
|
||||||
mPetHeadIconBitmap = null
|
mPetHeadIconBitmap = null
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,21 +398,26 @@ abstract class BaseGoogleMapFragment :
|
|||||||
private suspend fun setPetHeadMarker(
|
private suspend fun setPetHeadMarker(
|
||||||
latLng: LatLng, headBgResId: Int = R.drawable.pic_map_gps_avatar
|
latLng: LatLng, headBgResId: Int = R.drawable.pic_map_gps_avatar
|
||||||
) {
|
) {
|
||||||
val mapKey = if (TextUtils.isEmpty(mPetHeadUrl)) "pet_default_head"
|
// val mapKey = if (TextUtils.isEmpty(mPetHeadUrl)) "pet_default_head"
|
||||||
else mPetHeadUrl.substring(mPetHeadUrl.lastIndexOf("/") + 1, mPetHeadUrl.length)
|
// else mPetHeadUrl.substring(mPetHeadUrl.lastIndexOf("/") + 1, mPetHeadUrl.length)
|
||||||
var bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
|
// var bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
|
||||||
if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
|
// if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
|
||||||
if (null == mPetHeadIconBitmap) {
|
// if (null == mPetHeadIconBitmap) {
|
||||||
//设置头像
|
// //设置头像
|
||||||
mPetHeadIconBitmap =
|
// mPetHeadIconBitmap =
|
||||||
GoogleBitmapHelper.headToBitmap(mContext!!, headBgResId, mPetHeadUrl, mPetType)
|
// GoogleBitmapHelper.headToBitmap(mContext!!, headBgResId, mPetHeadUrl, mPetType)
|
||||||
}
|
// }
|
||||||
bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(mPetHeadIconBitmap!!)
|
// bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(mPetHeadIconBitmap!!)
|
||||||
//保存在内存中,提高显示速度
|
// //保存在内存中,提高显示速度
|
||||||
MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor
|
// MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor
|
||||||
}
|
// }
|
||||||
|
|
||||||
|
val bitmapDescriptor = GoogleBitmapHelper.getMarkerBitmapDescriptor(
|
||||||
|
mContext!!, mPetHeadUrl, mPetType, headBgResId
|
||||||
|
)
|
||||||
val newLatLng = toGCJ02LatLon(latLng)
|
val newLatLng = toGCJ02LatLon(latLng)
|
||||||
val markerOptions = MarkerOptions().position(newLatLng)
|
//显示最上面,层级最高,默认值 0f
|
||||||
|
val markerOptions = MarkerOptions().position(newLatLng).zIndex(99f)
|
||||||
markerOptions.icon(bitmapDescriptor)
|
markerOptions.icon(bitmapDescriptor)
|
||||||
mMarker?.remove()
|
mMarker?.remove()
|
||||||
mGoogleMap?.apply {
|
mGoogleMap?.apply {
|
||||||
@@ -805,7 +818,7 @@ abstract class BaseGoogleMapFragment :
|
|||||||
*/
|
*/
|
||||||
fun getPolylineOptions(widthDp: Float, lineColorRes: Int): PolylineOptions {
|
fun getPolylineOptions(widthDp: Float, lineColorRes: Int): PolylineOptions {
|
||||||
return PolylineOptions().clickable(false).width(AppUtils.dpToPx(widthDp))
|
return PolylineOptions().clickable(false).width(AppUtils.dpToPx(widthDp))
|
||||||
.color(ContextCompat.getColor(mContext!!, lineColorRes)).geodesic(false)
|
.color(ContextCompat.getColor(mContext!!, lineColorRes))
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -824,8 +837,21 @@ abstract class BaseGoogleMapFragment :
|
|||||||
} else {
|
} else {
|
||||||
latLngList
|
latLngList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*慢速步行:epsilon=0.5,插值 2 个
|
||||||
|
日常骑行:epsilon=1.0,插值 2 个
|
||||||
|
机动车行驶:epsilon=1.5~2.0,插值 3 个
|
||||||
|
**/
|
||||||
|
// 1. 降噪
|
||||||
|
val filterPoints = filterNoisePoint(newLatLngList)
|
||||||
|
// 2. RDP平滑抽稀
|
||||||
|
val smoothPoints = rdpSmooth(filterPoints, epsilon = 1.0)
|
||||||
|
// 3. 插值加密线条
|
||||||
|
val finalPoints = latLngInterpolate(smoothPoints, step = 2)
|
||||||
|
|
||||||
//先黄黑线
|
//先黄黑线
|
||||||
getPolylineOptions(8f, R.color.line_stroke_color).let {
|
getPolylineOptions(8f, R.color.line_stroke_color).let {
|
||||||
|
it.geodesic(true)
|
||||||
it.addAll(newLatLngList)
|
it.addAll(newLatLngList)
|
||||||
googleMap.addPolyline(it).apply {
|
googleMap.addPolyline(it).apply {
|
||||||
startCap = RoundCap()
|
startCap = RoundCap()
|
||||||
@@ -841,7 +867,8 @@ abstract class BaseGoogleMapFragment :
|
|||||||
|
|
||||||
//再画黄线
|
//再画黄线
|
||||||
getPolylineOptions(5f, R.color.rote_line_color).let {
|
getPolylineOptions(5f, R.color.rote_line_color).let {
|
||||||
it.addAll(newLatLngList)
|
it.geodesic(true)
|
||||||
|
it.addAll(finalPoints)
|
||||||
googleMap.addPolyline(it).apply {
|
googleMap.addPolyline(it).apply {
|
||||||
startCap = RoundCap()
|
startCap = RoundCap()
|
||||||
endCap = RoundCap()
|
endCap = RoundCap()
|
||||||
@@ -1267,8 +1294,118 @@ abstract class BaseGoogleMapFragment :
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
mPetHeadIconBitmap?.recycle()
|
mPetHeadIconBitmap.safeRecycle()
|
||||||
|
mPetHeadIconBitmap = null
|
||||||
mGoogleMapView?.onDestroy()
|
mGoogleMapView?.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 两点间距离 单位米
|
||||||
|
*/
|
||||||
|
private fun distanceBetween(p1: LatLng, p2: LatLng): Double {
|
||||||
|
val r = 6371000.0
|
||||||
|
val lat1 = p1.latitude * PI / 180
|
||||||
|
val lng1 = p1.longitude * PI / 180
|
||||||
|
val lat2 = p2.latitude * PI / 180
|
||||||
|
val lng2 = p2.longitude * PI / 180
|
||||||
|
|
||||||
|
val dLat = lat2 - lat1
|
||||||
|
val dLng = lng2 - lng1
|
||||||
|
val a = sin(dLat / 2).pow(2) + cos(lat1) * cos(lat2) * sin(dLng / 2).pow(2)
|
||||||
|
val c = 2 * atan2(sqrt(a), sqrt(1 - a))
|
||||||
|
return r * c
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ramer-Douglas-Peucker 轨迹抽稀平滑
|
||||||
|
* @param epsilon 阈值 建议0.5~2.0
|
||||||
|
*/
|
||||||
|
private fun rdpSmooth(points: List<LatLng>, epsilon: Double = 1.0): List<LatLng> {
|
||||||
|
if (points.size < 3) return points
|
||||||
|
var maxDist = 0.0
|
||||||
|
var index = 0
|
||||||
|
val start = points.first()
|
||||||
|
val end = points.last()
|
||||||
|
|
||||||
|
for (i in 1 until points.lastIndex) {
|
||||||
|
val dist = pointToLineDist(points[i], start, end)
|
||||||
|
if (dist > maxDist) {
|
||||||
|
maxDist = dist
|
||||||
|
index = i
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return if (maxDist > epsilon) {
|
||||||
|
val left = rdpSmooth(points.subList(0, index + 1), epsilon)
|
||||||
|
val right = rdpSmooth(points.subList(index, points.size), epsilon)
|
||||||
|
left.dropLast(1) + right
|
||||||
|
} else {
|
||||||
|
listOf(start, end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 点到线段距离
|
||||||
|
*/
|
||||||
|
private fun pointToLineDist(p: LatLng, a: LatLng, b: LatLng): Double {
|
||||||
|
val ax = a.longitude
|
||||||
|
val ay = a.latitude
|
||||||
|
val bx = b.longitude
|
||||||
|
val by = b.latitude
|
||||||
|
val px = p.longitude
|
||||||
|
val py = p.latitude
|
||||||
|
|
||||||
|
val cross = (px - ax) * (bx - ax) + (py - ay) * (by - ay)
|
||||||
|
if (cross <= 0.0) return distanceBetween(p, a)
|
||||||
|
|
||||||
|
val len2 = (bx - ax).pow(2) + (by - ay).pow(2)
|
||||||
|
if (cross >= len2) return distanceBetween(p, b)
|
||||||
|
|
||||||
|
val t = cross / len2
|
||||||
|
val nearX = ax + t * (bx - ax)
|
||||||
|
val nearY = ay + t * (by - ay)
|
||||||
|
return distanceBetween(p, LatLng(nearY, nearX))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 相邻两点插值补点,让线条更顺滑
|
||||||
|
* @param step 插值个数 推荐2~3
|
||||||
|
*/
|
||||||
|
private fun latLngInterpolate(points: List<LatLng>, step: Int = 2): List<LatLng> {
|
||||||
|
if (points.size < 2) return points
|
||||||
|
val result = mutableListOf<LatLng>()
|
||||||
|
for (i in 0 until points.size - 1) {
|
||||||
|
val p0 = points[i]
|
||||||
|
val p1 = points[i + 1]
|
||||||
|
result.add(p0)
|
||||||
|
for (s in 1..step) {
|
||||||
|
val ratio = s.toDouble() / (step + 1)
|
||||||
|
val lat = p0.latitude + (p1.latitude - p0.latitude) * ratio
|
||||||
|
val lng = p0.longitude + (p1.longitude - p0.longitude) * ratio
|
||||||
|
result.add(LatLng(lat, lng))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.add(points.last())
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GPS降噪,过滤跳点漂移
|
||||||
|
*/
|
||||||
|
private fun filterNoisePoint(
|
||||||
|
points: List<LatLng>, minDis: Double = 5.0, maxDis: Double = 60.0
|
||||||
|
): List<LatLng> {
|
||||||
|
if (points.isEmpty()) return emptyList()
|
||||||
|
val res = mutableListOf<LatLng>().apply { add(points.first()) }
|
||||||
|
for (i in 1 until points.size) {
|
||||||
|
val last = res.last()
|
||||||
|
val dis = distanceBetween(last, points[i])
|
||||||
|
if (dis in minDis..maxDis) {
|
||||||
|
res.add(points[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,9 +9,12 @@ import androidx.annotation.DrawableRes
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.graphics.drawable.DrawableCompat
|
import androidx.core.graphics.drawable.DrawableCompat
|
||||||
|
import com.abbidot.baselibrary.util.LogUtil
|
||||||
|
import com.abbidot.tracker.MyApplication
|
||||||
import com.abbidot.tracker.R
|
import com.abbidot.tracker.R
|
||||||
import com.abbidot.tracker.constant.ConstantInt
|
import com.abbidot.tracker.constant.ConstantInt
|
||||||
import com.abbidot.tracker.util.ImageUtil
|
import com.abbidot.tracker.util.ImageUtil
|
||||||
|
import com.abbidot.tracker.util.Util.Companion.safeRecycle
|
||||||
import com.google.android.gms.maps.model.BitmapDescriptor
|
import com.google.android.gms.maps.model.BitmapDescriptor
|
||||||
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
import com.google.android.gms.maps.model.BitmapDescriptorFactory
|
||||||
import com.qmuiteam.qmui.util.QMUIDisplayHelper
|
import com.qmuiteam.qmui.util.QMUIDisplayHelper
|
||||||
@@ -166,4 +169,40 @@ object GoogleBitmapHelper {
|
|||||||
vectorDrawable.draw(canvas)
|
vectorDrawable.draw(canvas)
|
||||||
return BitmapDescriptorFactory.fromBitmap(bitmap)
|
return BitmapDescriptorFactory.fromBitmap(bitmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun getMarkerBitmapDescriptor(
|
||||||
|
context: Context,
|
||||||
|
headUrl: String,
|
||||||
|
petType: Int,
|
||||||
|
headBgResId: Int = R.drawable.pic_map_gps_avatar
|
||||||
|
): BitmapDescriptor? {
|
||||||
|
var bitmap: Bitmap? = null
|
||||||
|
var bitmapDescriptor: Any?
|
||||||
|
try {
|
||||||
|
val mapKey = if (TextUtils.isEmpty(headUrl)) {
|
||||||
|
"pet_default_head"
|
||||||
|
} else {
|
||||||
|
val idx = headUrl.lastIndexOf("/")
|
||||||
|
if (idx != -1) {
|
||||||
|
headUrl.substring(idx + 1)
|
||||||
|
} else {
|
||||||
|
headUrl
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LogUtil.e("mapKey=$mapKey")
|
||||||
|
bitmapDescriptor = MyApplication.mapPetHeadHashMap[mapKey]
|
||||||
|
if (null == bitmapDescriptor || bitmapDescriptor !is BitmapDescriptor) {
|
||||||
|
bitmap = headToBitmap(context, headBgResId, headUrl, petType)
|
||||||
|
bitmap?.let {
|
||||||
|
bitmapDescriptor = BitmapDescriptorFactory.fromBitmap(it)
|
||||||
|
//保存在内存中,提高显示速度
|
||||||
|
MyApplication.mapPetHeadHashMap[mapKey] = bitmapDescriptor as BitmapDescriptor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
bitmap.safeRecycle()
|
||||||
|
}
|
||||||
|
// 把 return 写在 finally 外面
|
||||||
|
return bitmapDescriptor as? BitmapDescriptor
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -302,11 +302,10 @@ class HistoryDataGoogleMapFragment : BaseGoogleMapFragment() {
|
|||||||
if (null != mPetIconDescriptor) {
|
if (null != mPetIconDescriptor) {
|
||||||
mGoogleMap?.apply {
|
mGoogleMap?.apply {
|
||||||
val newLatLng = toGCJ02LatLon(latLng)
|
val newLatLng = toGCJ02LatLon(latLng)
|
||||||
mMarkerOptions.position(newLatLng).icon(mPetIconDescriptor)
|
//显示最上面,层级最高,默认值 0f
|
||||||
|
mMarkerOptions.position(newLatLng).icon(mPetIconDescriptor).zIndex(99f)
|
||||||
mMarker?.remove()
|
mMarker?.remove()
|
||||||
mMarker = addMarker(mMarkerOptions)
|
mMarker = addMarker(mMarkerOptions)
|
||||||
//显示最上面,层级最高
|
|
||||||
mMarker?.zIndex = 1f
|
|
||||||
setUserMarker()
|
setUserMarker()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,14 @@ import android.view.animation.LinearInterpolator
|
|||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.view.isVisible
|
import androidx.core.view.isVisible
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
|
import com.abbidot.baselibrary.constant.MMKVKey
|
||||||
import com.abbidot.baselibrary.util.AppUtils
|
import com.abbidot.baselibrary.util.AppUtils
|
||||||
|
import com.abbidot.baselibrary.util.MMKVUtil
|
||||||
import com.abbidot.baselibrary.util.Utils
|
import com.abbidot.baselibrary.util.Utils
|
||||||
import com.abbidot.tracker.R
|
import com.abbidot.tracker.R
|
||||||
import com.abbidot.tracker.bean.HistoryDataBean
|
import com.abbidot.tracker.bean.HistoryDataBean
|
||||||
import com.abbidot.tracker.bean.MapDeviceBean
|
import com.abbidot.tracker.bean.MapDeviceBean
|
||||||
|
import com.abbidot.tracker.bean.PetBean
|
||||||
import com.abbidot.tracker.constant.ConstantInt
|
import com.abbidot.tracker.constant.ConstantInt
|
||||||
import com.abbidot.tracker.databinding.LayoutPetLocationInfoBinding
|
import com.abbidot.tracker.databinding.LayoutPetLocationInfoBinding
|
||||||
import com.abbidot.tracker.util.Util
|
import com.abbidot.tracker.util.Util
|
||||||
@@ -24,6 +27,7 @@ import com.google.android.gms.maps.model.Circle
|
|||||||
import com.google.android.gms.maps.model.CircleOptions
|
import com.google.android.gms.maps.model.CircleOptions
|
||||||
import com.google.android.gms.maps.model.LatLng
|
import com.google.android.gms.maps.model.LatLng
|
||||||
import com.google.android.gms.maps.model.Marker
|
import com.google.android.gms.maps.model.Marker
|
||||||
|
import com.google.android.gms.maps.model.MarkerOptions
|
||||||
import com.google.android.gms.maps.model.Polyline
|
import com.google.android.gms.maps.model.Polyline
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
@@ -59,6 +63,8 @@ class HomeMapGoogleMapFragmentV3 : BaseGoogleMapFragment() {
|
|||||||
|
|
||||||
//是否需要反编译地理位置
|
//是否需要反编译地理位置
|
||||||
private var isReverseGeocode = false
|
private var isReverseGeocode = false
|
||||||
|
//其他没有选择的宠物
|
||||||
|
private val mOtherPetMarkerList = mutableListOf<Marker?>()
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
@@ -358,6 +364,39 @@ class HomeMapGoogleMapFragmentV3 : BaseGoogleMapFragment() {
|
|||||||
mRippleCircle = null
|
mRippleCircle = null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 显示其他宠物的头像Marker
|
||||||
|
*/
|
||||||
|
suspend fun showOtherPetHeadMarker(
|
||||||
|
petList: MutableList<PetBean>, headBgResId: Int = R.drawable.pic_map_gps_avatar
|
||||||
|
) {
|
||||||
|
clearOtherPetHeadMarker()
|
||||||
|
if (MMKVUtil.getBoolean(MMKVKey.ShowAllPet)) {
|
||||||
|
for (pet in petList) {
|
||||||
|
val bitmapDescriptor = GoogleBitmapHelper.getMarkerBitmapDescriptor(
|
||||||
|
mContext!!, pet.imgurl, pet.petType, headBgResId
|
||||||
|
)
|
||||||
|
val newLatLng = toGCJ02LatLon(LatLng(pet.latitude, pet.longitude))
|
||||||
|
val markerOptions = MarkerOptions().position(newLatLng)
|
||||||
|
markerOptions.icon(bitmapDescriptor)
|
||||||
|
mGoogleMap?.apply {
|
||||||
|
mOtherPetMarkerList.add(addMarker(markerOptions)?.apply {
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清空其他宠物的头像Marker
|
||||||
|
*/
|
||||||
|
fun clearOtherPetHeadMarker() {
|
||||||
|
for (m in mOtherPetMarkerList) {
|
||||||
|
m?.remove()
|
||||||
|
}
|
||||||
|
mOtherPetMarkerList.clear()
|
||||||
|
}
|
||||||
|
|
||||||
override fun onDetach() {
|
override fun onDetach() {
|
||||||
super.onDetach()
|
super.onDetach()
|
||||||
clearRippleCircleAnim()
|
clearRippleCircleAnim()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.content.ClipboardManager
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.graphics.Bitmap
|
||||||
import android.location.LocationManager
|
import android.location.LocationManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
@@ -900,6 +901,12 @@ class Util {
|
|||||||
return this.code in 0x4E00..0x9FA5
|
return this.code in 0x4E00..0x9FA5
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 扩展函数:Bitmap单独安全回收
|
||||||
|
*/
|
||||||
|
fun Bitmap?.safeRecycle() {
|
||||||
|
this?.takeIf { !it.isRecycled }?.recycle()
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -921,8 +921,9 @@ class ViewUtil private constructor() {
|
|||||||
fun getMapTypeDialog(
|
fun getMapTypeDialog(
|
||||||
context: Context,
|
context: Context,
|
||||||
onItemClickListener: BaseRecyclerAdapter.OnItemClickListener? = null,
|
onItemClickListener: BaseRecyclerAdapter.OnItemClickListener? = null,
|
||||||
fenceCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null,
|
fenceCheckedListener: CompoundButton.OnCheckedChangeListener? = null,
|
||||||
dashedCheckedChangeListener: CompoundButton.OnCheckedChangeListener? = null
|
dashedCheckedListener: CompoundButton.OnCheckedChangeListener? = null,
|
||||||
|
showAllPetCheckedListener: CompoundButton.OnCheckedChangeListener? = null
|
||||||
): SelectMapTypeDialog {
|
): SelectMapTypeDialog {
|
||||||
val mapType = Util.getMapTypeSp()
|
val mapType = Util.getMapTypeSp()
|
||||||
val typeList = mutableListOf<DataBean>()
|
val typeList = mutableListOf<DataBean>()
|
||||||
@@ -947,7 +948,7 @@ class ViewUtil private constructor() {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
return SelectMapTypeDialog(
|
return SelectMapTypeDialog(
|
||||||
context, mapTypeAdapter, fenceCheckedChangeListener, dashedCheckedChangeListener
|
context, mapTypeAdapter, fenceCheckedListener, dashedCheckedListener,showAllPetCheckedListener
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ interface OnCircleViewScaleClickListener {
|
|||||||
fun circleScaleEndClick()
|
fun circleScaleEndClick()
|
||||||
fun circleStartDragClick()
|
fun circleStartDragClick()
|
||||||
fun circleScalingClick()
|
fun circleScalingClick()
|
||||||
|
fun circleMinSizeClick()
|
||||||
fun circleEndDragClick()
|
fun circleEndDragClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -17,11 +18,13 @@ interface OnRectViewRotateScaleClickListener {
|
|||||||
fun rectScaleEndClick()
|
fun rectScaleEndClick()
|
||||||
fun rectScalingClick()
|
fun rectScalingClick()
|
||||||
fun rectStartDragClick()
|
fun rectStartDragClick()
|
||||||
|
fun rectMinSizeClick()
|
||||||
fun rectEndDragClick()
|
fun rectEndDragClick()
|
||||||
}
|
}
|
||||||
|
|
||||||
interface OnPolygonViewPointPullClickListener {
|
interface OnPolygonViewPointPullClickListener {
|
||||||
fun polygonPointPullClick()
|
fun polygonPointPullClick()
|
||||||
fun polygonStartDragClick()
|
fun polygonStartDragClick()
|
||||||
|
fun polygonMinSizeClick()
|
||||||
fun polygonEndDragClick()
|
fun polygonEndDragClick()
|
||||||
}
|
}
|
||||||
@@ -380,6 +380,7 @@ class FencesCircleView : View {
|
|||||||
if (mLimitRadius == 0f && circleRadius < mLocationBitmap!!.height / 2f) {
|
if (mLimitRadius == 0f && circleRadius < mLocationBitmap!!.height / 2f) {
|
||||||
return true
|
return true
|
||||||
} else if (circleRadius < mLimitRadius) {
|
} else if (circleRadius < mLimitRadius) {
|
||||||
|
mScaleClickListener?.circleMinSizeClick()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
mMaxCircleRadius = circleRadius
|
mMaxCircleRadius = circleRadius
|
||||||
|
|||||||
@@ -339,6 +339,7 @@ class FencesPolygonView : View {
|
|||||||
}
|
}
|
||||||
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
||||||
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
||||||
|
mPointPullClickListener?.polygonMinSizeClick()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
mOutHideRectWidth = tempRect.width()
|
mOutHideRectWidth = tempRect.width()
|
||||||
@@ -401,6 +402,7 @@ class FencesPolygonView : View {
|
|||||||
}
|
}
|
||||||
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
||||||
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
||||||
|
mPointPullClickListener?.polygonMinSizeClick()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
mOutHideRectWidth = tempRect.width()
|
mOutHideRectWidth = tempRect.width()
|
||||||
@@ -462,6 +464,7 @@ class FencesPolygonView : View {
|
|||||||
}
|
}
|
||||||
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
||||||
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
||||||
|
mPointPullClickListener?.polygonMinSizeClick()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
mOutHideRectWidth = tempRect.width()
|
mOutHideRectWidth = tempRect.width()
|
||||||
@@ -523,6 +526,7 @@ class FencesPolygonView : View {
|
|||||||
}
|
}
|
||||||
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
||||||
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
||||||
|
mPointPullClickListener?.polygonMinSizeClick()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
mOutHideRectWidth = tempRect.width()
|
mOutHideRectWidth = tempRect.width()
|
||||||
@@ -584,6 +588,7 @@ class FencesPolygonView : View {
|
|||||||
}
|
}
|
||||||
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
||||||
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
||||||
|
mPointPullClickListener?.polygonMinSizeClick()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
mOutHideRectWidth = tempRect.width()
|
mOutHideRectWidth = tempRect.width()
|
||||||
@@ -645,6 +650,7 @@ class FencesPolygonView : View {
|
|||||||
}
|
}
|
||||||
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
val tempRect = getTempRect(mTouchPointTag, mTempPoint)
|
||||||
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
if (mLimitSide > 0 && (tempRect.width() < mLimitSide || tempRect.height() < mLimitSide)) {
|
||||||
|
mPointPullClickListener?.polygonMinSizeClick()
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
mOutHideRectWidth = tempRect.width()
|
mOutHideRectWidth = tempRect.width()
|
||||||
|
|||||||
@@ -500,6 +500,7 @@ class FencesRectView : View {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} else if (newRectWidth < mLimitSide || newRectHeight < mLimitSide) {
|
} else if (newRectWidth < mLimitSide || newRectHeight < mLimitSide) {
|
||||||
|
mRotateScaleClickListener?.rectMinSizeClick()
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
mRotateScaleClickListener?.rectScalingClick()
|
mRotateScaleClickListener?.rectScalingClick()
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
package com.abbidot.tracker.widget
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.View
|
||||||
|
|
||||||
|
/**
|
||||||
|
*Created by .yzq on 2026/5/25/周一.
|
||||||
|
* @link
|
||||||
|
* @description:
|
||||||
|
*/
|
||||||
|
class TrackLineView @JvmOverloads constructor(
|
||||||
|
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
|
||||||
|
) : View(context, attrs, defStyleAttr) {
|
||||||
|
|
||||||
|
override fun onDraw(canvas: Canvas) {
|
||||||
|
super.onDraw(canvas)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -66,6 +66,33 @@
|
|||||||
android:id="@+id/cb_dialog_map_dashed_line_switch"
|
android:id="@+id/cb_dialog_map_dashed_line_switch"
|
||||||
style="@style/my_checkbox_switch_style"
|
style="@style/my_checkbox_switch_style"
|
||||||
android:layout_width="@dimen/dp_47"
|
android:layout_width="@dimen/dp_47"
|
||||||
android:checked="true" />
|
android:checked="false" />
|
||||||
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.LinearLayoutCompat
|
||||||
|
android:id="@+id/ll_map_type_show_all_pet_switch"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_below="@id/ll_map_type_show_dashed_line_switch"
|
||||||
|
android:layout_marginTop="@dimen/dp_8"
|
||||||
|
android:background="@drawable/shape8_gray_border_transparent_bg"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:minHeight="@dimen/dp_47"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="@dimen/dp_16">
|
||||||
|
|
||||||
|
<com.abbidot.tracker.widget.TypefaceTextView
|
||||||
|
style="@style/my_TextView_style_v2"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="start"
|
||||||
|
android:text="@string/txt_show_all_pet"
|
||||||
|
android:textSize="@dimen/textSize14"
|
||||||
|
app:typeface="@string/roboto_bold_font" />
|
||||||
|
|
||||||
|
<androidx.appcompat.widget.AppCompatCheckBox
|
||||||
|
android:id="@+id/cb_dialog_map_all_pet_switch"
|
||||||
|
style="@style/my_checkbox_switch_style"
|
||||||
|
android:layout_width="@dimen/dp_47"
|
||||||
|
android:checked="false" />
|
||||||
</androidx.appcompat.widget.LinearLayoutCompat>
|
</androidx.appcompat.widget.LinearLayoutCompat>
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
@@ -1012,5 +1012,7 @@
|
|||||||
<string name="txt_package_permission3">1. VIP-Prioritätssupport\n2. Schneller Austauschservice (1x inbegriffen)\n3. Erweiterter Schutz\n4. Sorgenfreier Haustierschutz</string>
|
<string name="txt_package_permission3">1. VIP-Prioritätssupport\n2. Schneller Austauschservice (1x inbegriffen)\n3. Erweiterter Schutz\n4. Sorgenfreier Haustierschutz</string>
|
||||||
<string name="txt_add_wifi_tips">Fügen Sie eine Wi-Fi-Zone hinzu, um die Betriebszeit zu verlängern.</string>
|
<string name="txt_add_wifi_tips">Fügen Sie eine Wi-Fi-Zone hinzu, um die Betriebszeit zu verlängern.</string>
|
||||||
<string name="txt_add">Hinzufügen</string>
|
<string name="txt_add">Hinzufügen</string>
|
||||||
|
<string name="txt_show_all_pet">Alle Haustiere anzeigen</string>
|
||||||
|
<string name="txt_already_min_size">Bereits auf Minimalgröße</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1056,5 +1056,7 @@
|
|||||||
<string name="txt_package_permission3">1. VIP 优先支持\n2. 快速更换服务(含1次)\n3. 增强型保障\n4. 无忧宠物保护</string>
|
<string name="txt_package_permission3">1. VIP 优先支持\n2. 快速更换服务(含1次)\n3. 增强型保障\n4. 无忧宠物保护</string>
|
||||||
<string name="txt_add_wifi_tips">添加wifi区域可延长使用时长</string>
|
<string name="txt_add_wifi_tips">添加wifi区域可延长使用时长</string>
|
||||||
<string name="txt_add">去添加</string>
|
<string name="txt_add">去添加</string>
|
||||||
|
<string name="txt_show_all_pet">显示所有宠物</string>
|
||||||
|
<string name="txt_already_min_size">已是最小尺寸</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -1114,5 +1114,7 @@
|
|||||||
<string name="txt_package_permission3">1.VIP priority support\n2.Fast replacement service (1 included)\n3.Enhanced protection\n4.Hassle-free pet protection</string>
|
<string name="txt_package_permission3">1.VIP priority support\n2.Fast replacement service (1 included)\n3.Enhanced protection\n4.Hassle-free pet protection</string>
|
||||||
<string name="txt_add_wifi_tips">Add Wi-Fi zone to prolong care time</string>
|
<string name="txt_add_wifi_tips">Add Wi-Fi zone to prolong care time</string>
|
||||||
<string name="txt_add">Add</string>
|
<string name="txt_add">Add</string>
|
||||||
|
<string name="txt_show_all_pet">Display All Pets</string>
|
||||||
|
<string name="txt_already_min_size">Already at minimum size</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -38,6 +38,7 @@ import androidx.annotation.StringDef
|
|||||||
MMKVKey.MapType,
|
MMKVKey.MapType,
|
||||||
MMKVKey.ShowFence,
|
MMKVKey.ShowFence,
|
||||||
MMKVKey.ShowDashedLine,
|
MMKVKey.ShowDashedLine,
|
||||||
|
MMKVKey.ShowAllPet,
|
||||||
MMKVKey.isCrash,
|
MMKVKey.isCrash,
|
||||||
MMKVKey.AvailableOrder,
|
MMKVKey.AvailableOrder,
|
||||||
MMKVKey.isFirstCheckBleOpen,
|
MMKVKey.isFirstCheckBleOpen,
|
||||||
@@ -94,6 +95,7 @@ annotation class MMKVKey {
|
|||||||
//map页是否显示围栏
|
//map页是否显示围栏
|
||||||
const val ShowFence = "isShowFence"
|
const val ShowFence = "isShowFence"
|
||||||
const val ShowDashedLine = "isShowDashedLine"
|
const val ShowDashedLine = "isShowDashedLine"
|
||||||
|
const val ShowAllPet = "isShowAllPet"
|
||||||
|
|
||||||
//是首次打开APP
|
//是首次打开APP
|
||||||
const val FirstOpen = "firstOpen"
|
const val FirstOpen = "firstOpen"
|
||||||
|
|||||||
Reference in New Issue
Block a user