diff --git a/app/build.gradle b/app/build.gradle index 2cef713..9ee2ec9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,6 +100,8 @@ implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //高德地图 implementation 'com.amap.api:3dmap:latest.integration' + //高德地图搜索 + implementation 'com.amap.api:search:8.1.0' //CameraX def camerax_version = '1.2.3' implementation "androidx.camera:camera-core:$camerax_version" diff --git a/app/build.gradle b/app/build.gradle index 2cef713..9ee2ec9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,6 +100,8 @@ implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //高德地图 implementation 'com.amap.api:3dmap:latest.integration' + //高德地图搜索 + implementation 'com.amap.api:search:8.1.0' //CameraX def camerax_version = '1.2.3' implementation "androidx.camera:camera-core:$camerax_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2dbaa56..ee67360 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -73,6 +73,7 @@ + + + (), AMap.OnMapLoadedListener, + AMap.OnCameraChangeListener { + + private lateinit var aMap: AMap + private lateinit var centerMarkerView: CenterMarkerView + + override fun initOnCreate(savedInstanceState: Bundle?) { + binding.mapView.onCreate(savedInstanceState) + + aMap = binding.mapView.map + aMap.mapType = AMap.MAP_TYPE_NORMAL + val locationStyle = MyLocationStyle() + //定位一次,且将视角移动到地图中心点 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) + //设置是否显示定位小蓝点 + locationStyle.showMyLocation(true) + locationStyle.strokeColor(Color.TRANSPARENT) + locationStyle.strokeWidth(0f) + locationStyle.radiusFillColor(Color.TRANSPARENT) + aMap.myLocationStyle = locationStyle + aMap.isMyLocationEnabled = true + val uiSettings = aMap.uiSettings + uiSettings.isCompassEnabled = true + uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER + //不许地图随手势倾斜角度 + uiSettings.isTiltGesturesEnabled = false + //不允许地图旋转 + uiSettings.isRotateGesturesEnabled = false + //设置默认定位按钮是否显示 + uiSettings.isMyLocationButtonEnabled = true + //改变地图的缩放级别 + aMap.moveCamera(CameraUpdateFactory.zoomTo(18f)) + centerMarkerView = CenterMarkerView(this, aMap) + + aMap.setOnMapLoadedListener(this) + aMap.setOnCameraChangeListener(this) + } + + override fun initEvent() { + binding.confirmButton.setOnClickListener { + val intent = Intent() + intent.putExtra("longitude", binding.longitudeView.text) + intent.putExtra("latitude", binding.latitudeView.text) + setResult(RESULT_OK, intent) + finish() + } + } + + override fun initViewBinding(): ActivityDragMapBinding { + return ActivityDragMapBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun onMapLoaded() { + centerMarkerView.addCenterMarker() + } + + override fun onCameraChange(cameraPosition: CameraPosition) { + //隐藏中心点marker的InfoWindow + centerMarkerView.hideCenterMarkerInfoWindow() + } + + override fun onCameraChangeFinish(cameraPosition: CameraPosition) { + val latLng = cameraPosition.target + //显示infoWindow + centerMarkerView.showInfoWindow(latLng) + binding.longitudeView.text = latLng.longitude.toString() + binding.latitudeView.text = latLng.latitude.toString() + } + + override fun onResume() { + super.onResume() + binding.mapView.onResume() + } + + override fun onPause() { + super.onPause() + binding.mapView.onPause() + } + + override fun onDestroy() { + centerMarkerView.destroy() + binding.mapView.onDestroy() + super.onDestroy() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + binding.mapView.onSaveInstanceState(outState) + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).init() + + val insetsController = WindowCompat.getInsetsController(window, binding.rootView) + insetsController.hide(WindowInsetsCompat.Type.statusBars()) + insetsController.hide(WindowInsetsCompat.Type.navigationBars()) + } +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 2cef713..9ee2ec9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,6 +100,8 @@ implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //高德地图 implementation 'com.amap.api:3dmap:latest.integration' + //高德地图搜索 + implementation 'com.amap.api:search:8.1.0' //CameraX def camerax_version = '1.2.3' implementation "androidx.camera:camera-core:$camerax_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2dbaa56..ee67360 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -73,6 +73,7 @@ + (), AMap.OnMapLoadedListener, + AMap.OnCameraChangeListener { + + private lateinit var aMap: AMap + private lateinit var centerMarkerView: CenterMarkerView + + override fun initOnCreate(savedInstanceState: Bundle?) { + binding.mapView.onCreate(savedInstanceState) + + aMap = binding.mapView.map + aMap.mapType = AMap.MAP_TYPE_NORMAL + val locationStyle = MyLocationStyle() + //定位一次,且将视角移动到地图中心点 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) + //设置是否显示定位小蓝点 + locationStyle.showMyLocation(true) + locationStyle.strokeColor(Color.TRANSPARENT) + locationStyle.strokeWidth(0f) + locationStyle.radiusFillColor(Color.TRANSPARENT) + aMap.myLocationStyle = locationStyle + aMap.isMyLocationEnabled = true + val uiSettings = aMap.uiSettings + uiSettings.isCompassEnabled = true + uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER + //不许地图随手势倾斜角度 + uiSettings.isTiltGesturesEnabled = false + //不允许地图旋转 + uiSettings.isRotateGesturesEnabled = false + //设置默认定位按钮是否显示 + uiSettings.isMyLocationButtonEnabled = true + //改变地图的缩放级别 + aMap.moveCamera(CameraUpdateFactory.zoomTo(18f)) + centerMarkerView = CenterMarkerView(this, aMap) + + aMap.setOnMapLoadedListener(this) + aMap.setOnCameraChangeListener(this) + } + + override fun initEvent() { + binding.confirmButton.setOnClickListener { + val intent = Intent() + intent.putExtra("longitude", binding.longitudeView.text) + intent.putExtra("latitude", binding.latitudeView.text) + setResult(RESULT_OK, intent) + finish() + } + } + + override fun initViewBinding(): ActivityDragMapBinding { + return ActivityDragMapBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun onMapLoaded() { + centerMarkerView.addCenterMarker() + } + + override fun onCameraChange(cameraPosition: CameraPosition) { + //隐藏中心点marker的InfoWindow + centerMarkerView.hideCenterMarkerInfoWindow() + } + + override fun onCameraChangeFinish(cameraPosition: CameraPosition) { + val latLng = cameraPosition.target + //显示infoWindow + centerMarkerView.showInfoWindow(latLng) + binding.longitudeView.text = latLng.longitude.toString() + binding.latitudeView.text = latLng.latitude.toString() + } + + override fun onResume() { + super.onResume() + binding.mapView.onResume() + } + + override fun onPause() { + super.onPause() + binding.mapView.onPause() + } + + override fun onDestroy() { + centerMarkerView.destroy() + binding.mapView.onDestroy() + super.onDestroy() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + binding.mapView.onSaveInstanceState(outState) + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).init() + + val insetsController = WindowCompat.getInsetsController(window, binding.rootView) + insetsController.hide(WindowInsetsCompat.Type.statusBars()) + insetsController.hide(WindowInsetsCompat.Type.navigationBars()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index c3b502c..decb588 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -1,12 +1,15 @@ package com.casic.br.operationsite.view +import android.app.Activity +import android.content.Intent import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.util.Log import android.view.View -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import com.casic.br.operationsite.R import com.casic.br.operationsite.callback.OnImageCompressListener import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding @@ -15,7 +18,6 @@ import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector @@ -34,9 +36,6 @@ import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch import java.io.File class InstallEquipmentActivity : KotlinBaseActivity() { @@ -79,7 +78,7 @@ //左右边距 val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 3, 3) + imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) binding.recyclerView.addItemDecoration( RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) ) @@ -90,20 +89,24 @@ } + private val selectLocationLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + binding.longitudeView.setText(data.getStringExtra("longitude")) + binding.latitudeView.setText(data.getStringExtra("latitude")) + } + } + }) + override fun initEvent() { binding.deviceCodeView.addTextChangedListener(textWatcher) binding.locationImageView.setOnClickListener { - LocationKit.getCurrentLocation(context, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "信号差,定位失败,请移动位置再试".show(context) - } else { - binding.longitudeView.setText(aMapLocation.longitude.toString()) - binding.latitudeView.setText(aMapLocation.latitude.toString()) - } - } - }) + selectLocationLauncher.launch(Intent(this, DragMapActivity::class.java)) } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -164,11 +167,9 @@ PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) .forResult(object : OnResultCallbackListener { override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return + result?.apply { + analyticalSelectResults(first()) } - analyticalSelectResults(result.first()) } override fun onCancel() { @@ -180,19 +181,12 @@ 1 -> { PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) + .setMaxSelectNum(1).isDisplayCamera(false) .setImageEngine(GlideLoadEngine.get) .forResult(object : OnResultCallbackListener { override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } + result?.apply { + analyticalSelectResults(first()) } } diff --git a/app/build.gradle b/app/build.gradle index 2cef713..9ee2ec9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,6 +100,8 @@ implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //高德地图 implementation 'com.amap.api:3dmap:latest.integration' + //高德地图搜索 + implementation 'com.amap.api:search:8.1.0' //CameraX def camerax_version = '1.2.3' implementation "androidx.camera:camera-core:$camerax_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2dbaa56..ee67360 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -73,6 +73,7 @@ + (), AMap.OnMapLoadedListener, + AMap.OnCameraChangeListener { + + private lateinit var aMap: AMap + private lateinit var centerMarkerView: CenterMarkerView + + override fun initOnCreate(savedInstanceState: Bundle?) { + binding.mapView.onCreate(savedInstanceState) + + aMap = binding.mapView.map + aMap.mapType = AMap.MAP_TYPE_NORMAL + val locationStyle = MyLocationStyle() + //定位一次,且将视角移动到地图中心点 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) + //设置是否显示定位小蓝点 + locationStyle.showMyLocation(true) + locationStyle.strokeColor(Color.TRANSPARENT) + locationStyle.strokeWidth(0f) + locationStyle.radiusFillColor(Color.TRANSPARENT) + aMap.myLocationStyle = locationStyle + aMap.isMyLocationEnabled = true + val uiSettings = aMap.uiSettings + uiSettings.isCompassEnabled = true + uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER + //不许地图随手势倾斜角度 + uiSettings.isTiltGesturesEnabled = false + //不允许地图旋转 + uiSettings.isRotateGesturesEnabled = false + //设置默认定位按钮是否显示 + uiSettings.isMyLocationButtonEnabled = true + //改变地图的缩放级别 + aMap.moveCamera(CameraUpdateFactory.zoomTo(18f)) + centerMarkerView = CenterMarkerView(this, aMap) + + aMap.setOnMapLoadedListener(this) + aMap.setOnCameraChangeListener(this) + } + + override fun initEvent() { + binding.confirmButton.setOnClickListener { + val intent = Intent() + intent.putExtra("longitude", binding.longitudeView.text) + intent.putExtra("latitude", binding.latitudeView.text) + setResult(RESULT_OK, intent) + finish() + } + } + + override fun initViewBinding(): ActivityDragMapBinding { + return ActivityDragMapBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun onMapLoaded() { + centerMarkerView.addCenterMarker() + } + + override fun onCameraChange(cameraPosition: CameraPosition) { + //隐藏中心点marker的InfoWindow + centerMarkerView.hideCenterMarkerInfoWindow() + } + + override fun onCameraChangeFinish(cameraPosition: CameraPosition) { + val latLng = cameraPosition.target + //显示infoWindow + centerMarkerView.showInfoWindow(latLng) + binding.longitudeView.text = latLng.longitude.toString() + binding.latitudeView.text = latLng.latitude.toString() + } + + override fun onResume() { + super.onResume() + binding.mapView.onResume() + } + + override fun onPause() { + super.onPause() + binding.mapView.onPause() + } + + override fun onDestroy() { + centerMarkerView.destroy() + binding.mapView.onDestroy() + super.onDestroy() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + binding.mapView.onSaveInstanceState(outState) + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).init() + + val insetsController = WindowCompat.getInsetsController(window, binding.rootView) + insetsController.hide(WindowInsetsCompat.Type.statusBars()) + insetsController.hide(WindowInsetsCompat.Type.navigationBars()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index c3b502c..decb588 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -1,12 +1,15 @@ package com.casic.br.operationsite.view +import android.app.Activity +import android.content.Intent import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.util.Log import android.view.View -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import com.casic.br.operationsite.R import com.casic.br.operationsite.callback.OnImageCompressListener import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding @@ -15,7 +18,6 @@ import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector @@ -34,9 +36,6 @@ import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch import java.io.File class InstallEquipmentActivity : KotlinBaseActivity() { @@ -79,7 +78,7 @@ //左右边距 val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 3, 3) + imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) binding.recyclerView.addItemDecoration( RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) ) @@ -90,20 +89,24 @@ } + private val selectLocationLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + binding.longitudeView.setText(data.getStringExtra("longitude")) + binding.latitudeView.setText(data.getStringExtra("latitude")) + } + } + }) + override fun initEvent() { binding.deviceCodeView.addTextChangedListener(textWatcher) binding.locationImageView.setOnClickListener { - LocationKit.getCurrentLocation(context, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "信号差,定位失败,请移动位置再试".show(context) - } else { - binding.longitudeView.setText(aMapLocation.longitude.toString()) - binding.latitudeView.setText(aMapLocation.latitude.toString()) - } - } - }) + selectLocationLauncher.launch(Intent(this, DragMapActivity::class.java)) } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -164,11 +167,9 @@ PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) .forResult(object : OnResultCallbackListener { override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return + result?.apply { + analyticalSelectResults(first()) } - analyticalSelectResults(result.first()) } override fun onCancel() { @@ -180,19 +181,12 @@ 1 -> { PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) + .setMaxSelectNum(1).isDisplayCamera(false) .setImageEngine(GlideLoadEngine.get) .forResult(object : OnResultCallbackListener { override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } + result?.apply { + analyticalSelectResults(first()) } } diff --git a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt new file mode 100644 index 0000000..1bdbcb4 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt @@ -0,0 +1,100 @@ +package com.casic.br.operationsite.widgets + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Point +import android.view.LayoutInflater +import android.view.View +import android.widget.TextView +import com.amap.api.maps.AMap +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.Marker +import com.amap.api.maps.model.MarkerOptions +import com.amap.api.maps.model.animation.Animation +import com.amap.api.maps.model.animation.ScaleAnimation +import com.amap.api.services.core.LatLonPoint +import com.amap.api.services.geocoder.GeocodeResult +import com.amap.api.services.geocoder.GeocodeSearch +import com.amap.api.services.geocoder.RegeocodeQuery +import com.amap.api.services.geocoder.RegeocodeResult +import com.casic.br.operationsite.R +import com.pengxh.kt.lite.extensions.breakLine + +class CenterMarkerView(private val context: Context, private var aMap: AMap) { + private lateinit var centerMarker: Marker + + //拿到地图中心点的坐标 + private var latLng = aMap.cameraPosition.target + private val geocoderSearch by lazy { GeocodeSearch(context) } + + init { + aMap.setInfoWindowAdapter(object : AMap.InfoWindowAdapter { + override fun getInfoWindow(marker: Marker): View { + val infoWindow = LayoutInflater.from(context).inflate( + R.layout.map_info_window, null + ) + val locationView: TextView = infoWindow.findViewById(R.id.locationView) + val queryParam = RegeocodeQuery( + LatLonPoint(latLng.latitude, latLng.longitude), 100f, GeocodeSearch.AMAP + ) + geocoderSearch.getFromLocationAsyn(queryParam) + geocoderSearch.setOnGeocodeSearchListener(object : + GeocodeSearch.OnGeocodeSearchListener { + override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult, code: Int) { + if (code == 1000) { + //手动换行 + val address = regeocodeResult.regeocodeAddress.formatAddress + locationView.text = address.breakLine(22) + } + } + + override fun onGeocodeSearched(geocodeResult: GeocodeResult?, i: Int) {} + }) + return infoWindow + } + + override fun getInfoContents(p0: Marker?): View? { + return null + } + }) + } + + fun addCenterMarker() { + val options = MarkerOptions() + //对应Marker.setIcon方法 设置Marker的图片 + options.icon(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin)) + //设置infoWindow与锚点的相对位置 + options.anchor(0.5f, 1f) + //把中心点的坐标转换成屏幕像素位置 + val screenPosition: Point = aMap.projection.toScreenLocation(latLng) + //在地图上添加Marker并获取到Marker. + centerMarker = aMap.addMarker(options) + //给marker设置像素位置。 + centerMarker.setPositionByPixels(screenPosition.x, screenPosition.y) + centerMarker.setAnchor(0.5f, 1f) + } + + fun showInfoWindow(latLng: LatLng) { + this.latLng = latLng + //缩放动画 + val scaleAnimation: Animation = ScaleAnimation(1f, 1f, 0.75f, 1f) + //时间设置短点 + scaleAnimation.setDuration(500) + centerMarker.setAnimation(scaleAnimation) + centerMarker.startAnimation() + centerMarker.showInfoWindow() + } + + fun hideCenterMarkerInfoWindow() { + centerMarker.hideInfoWindow() + val bitmap: Bitmap = BitmapFactory.decodeResource(context.resources, R.mipmap.map_pin) + centerMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap)) + } + + fun destroy() { + centerMarker.destroy() + centerMarker.showInfoWindow() + } +} \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 2cef713..9ee2ec9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,6 +100,8 @@ implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //高德地图 implementation 'com.amap.api:3dmap:latest.integration' + //高德地图搜索 + implementation 'com.amap.api:search:8.1.0' //CameraX def camerax_version = '1.2.3' implementation "androidx.camera:camera-core:$camerax_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2dbaa56..ee67360 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -73,6 +73,7 @@ + (), AMap.OnMapLoadedListener, + AMap.OnCameraChangeListener { + + private lateinit var aMap: AMap + private lateinit var centerMarkerView: CenterMarkerView + + override fun initOnCreate(savedInstanceState: Bundle?) { + binding.mapView.onCreate(savedInstanceState) + + aMap = binding.mapView.map + aMap.mapType = AMap.MAP_TYPE_NORMAL + val locationStyle = MyLocationStyle() + //定位一次,且将视角移动到地图中心点 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) + //设置是否显示定位小蓝点 + locationStyle.showMyLocation(true) + locationStyle.strokeColor(Color.TRANSPARENT) + locationStyle.strokeWidth(0f) + locationStyle.radiusFillColor(Color.TRANSPARENT) + aMap.myLocationStyle = locationStyle + aMap.isMyLocationEnabled = true + val uiSettings = aMap.uiSettings + uiSettings.isCompassEnabled = true + uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER + //不许地图随手势倾斜角度 + uiSettings.isTiltGesturesEnabled = false + //不允许地图旋转 + uiSettings.isRotateGesturesEnabled = false + //设置默认定位按钮是否显示 + uiSettings.isMyLocationButtonEnabled = true + //改变地图的缩放级别 + aMap.moveCamera(CameraUpdateFactory.zoomTo(18f)) + centerMarkerView = CenterMarkerView(this, aMap) + + aMap.setOnMapLoadedListener(this) + aMap.setOnCameraChangeListener(this) + } + + override fun initEvent() { + binding.confirmButton.setOnClickListener { + val intent = Intent() + intent.putExtra("longitude", binding.longitudeView.text) + intent.putExtra("latitude", binding.latitudeView.text) + setResult(RESULT_OK, intent) + finish() + } + } + + override fun initViewBinding(): ActivityDragMapBinding { + return ActivityDragMapBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun onMapLoaded() { + centerMarkerView.addCenterMarker() + } + + override fun onCameraChange(cameraPosition: CameraPosition) { + //隐藏中心点marker的InfoWindow + centerMarkerView.hideCenterMarkerInfoWindow() + } + + override fun onCameraChangeFinish(cameraPosition: CameraPosition) { + val latLng = cameraPosition.target + //显示infoWindow + centerMarkerView.showInfoWindow(latLng) + binding.longitudeView.text = latLng.longitude.toString() + binding.latitudeView.text = latLng.latitude.toString() + } + + override fun onResume() { + super.onResume() + binding.mapView.onResume() + } + + override fun onPause() { + super.onPause() + binding.mapView.onPause() + } + + override fun onDestroy() { + centerMarkerView.destroy() + binding.mapView.onDestroy() + super.onDestroy() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + binding.mapView.onSaveInstanceState(outState) + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).init() + + val insetsController = WindowCompat.getInsetsController(window, binding.rootView) + insetsController.hide(WindowInsetsCompat.Type.statusBars()) + insetsController.hide(WindowInsetsCompat.Type.navigationBars()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index c3b502c..decb588 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -1,12 +1,15 @@ package com.casic.br.operationsite.view +import android.app.Activity +import android.content.Intent import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.util.Log import android.view.View -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import com.casic.br.operationsite.R import com.casic.br.operationsite.callback.OnImageCompressListener import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding @@ -15,7 +18,6 @@ import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector @@ -34,9 +36,6 @@ import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch import java.io.File class InstallEquipmentActivity : KotlinBaseActivity() { @@ -79,7 +78,7 @@ //左右边距 val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 3, 3) + imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) binding.recyclerView.addItemDecoration( RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) ) @@ -90,20 +89,24 @@ } + private val selectLocationLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + binding.longitudeView.setText(data.getStringExtra("longitude")) + binding.latitudeView.setText(data.getStringExtra("latitude")) + } + } + }) + override fun initEvent() { binding.deviceCodeView.addTextChangedListener(textWatcher) binding.locationImageView.setOnClickListener { - LocationKit.getCurrentLocation(context, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "信号差,定位失败,请移动位置再试".show(context) - } else { - binding.longitudeView.setText(aMapLocation.longitude.toString()) - binding.latitudeView.setText(aMapLocation.latitude.toString()) - } - } - }) + selectLocationLauncher.launch(Intent(this, DragMapActivity::class.java)) } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -164,11 +167,9 @@ PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) .forResult(object : OnResultCallbackListener { override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return + result?.apply { + analyticalSelectResults(first()) } - analyticalSelectResults(result.first()) } override fun onCancel() { @@ -180,19 +181,12 @@ 1 -> { PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) + .setMaxSelectNum(1).isDisplayCamera(false) .setImageEngine(GlideLoadEngine.get) .forResult(object : OnResultCallbackListener { override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } + result?.apply { + analyticalSelectResults(first()) } } diff --git a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt new file mode 100644 index 0000000..1bdbcb4 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt @@ -0,0 +1,100 @@ +package com.casic.br.operationsite.widgets + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Point +import android.view.LayoutInflater +import android.view.View +import android.widget.TextView +import com.amap.api.maps.AMap +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.Marker +import com.amap.api.maps.model.MarkerOptions +import com.amap.api.maps.model.animation.Animation +import com.amap.api.maps.model.animation.ScaleAnimation +import com.amap.api.services.core.LatLonPoint +import com.amap.api.services.geocoder.GeocodeResult +import com.amap.api.services.geocoder.GeocodeSearch +import com.amap.api.services.geocoder.RegeocodeQuery +import com.amap.api.services.geocoder.RegeocodeResult +import com.casic.br.operationsite.R +import com.pengxh.kt.lite.extensions.breakLine + +class CenterMarkerView(private val context: Context, private var aMap: AMap) { + private lateinit var centerMarker: Marker + + //拿到地图中心点的坐标 + private var latLng = aMap.cameraPosition.target + private val geocoderSearch by lazy { GeocodeSearch(context) } + + init { + aMap.setInfoWindowAdapter(object : AMap.InfoWindowAdapter { + override fun getInfoWindow(marker: Marker): View { + val infoWindow = LayoutInflater.from(context).inflate( + R.layout.map_info_window, null + ) + val locationView: TextView = infoWindow.findViewById(R.id.locationView) + val queryParam = RegeocodeQuery( + LatLonPoint(latLng.latitude, latLng.longitude), 100f, GeocodeSearch.AMAP + ) + geocoderSearch.getFromLocationAsyn(queryParam) + geocoderSearch.setOnGeocodeSearchListener(object : + GeocodeSearch.OnGeocodeSearchListener { + override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult, code: Int) { + if (code == 1000) { + //手动换行 + val address = regeocodeResult.regeocodeAddress.formatAddress + locationView.text = address.breakLine(22) + } + } + + override fun onGeocodeSearched(geocodeResult: GeocodeResult?, i: Int) {} + }) + return infoWindow + } + + override fun getInfoContents(p0: Marker?): View? { + return null + } + }) + } + + fun addCenterMarker() { + val options = MarkerOptions() + //对应Marker.setIcon方法 设置Marker的图片 + options.icon(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin)) + //设置infoWindow与锚点的相对位置 + options.anchor(0.5f, 1f) + //把中心点的坐标转换成屏幕像素位置 + val screenPosition: Point = aMap.projection.toScreenLocation(latLng) + //在地图上添加Marker并获取到Marker. + centerMarker = aMap.addMarker(options) + //给marker设置像素位置。 + centerMarker.setPositionByPixels(screenPosition.x, screenPosition.y) + centerMarker.setAnchor(0.5f, 1f) + } + + fun showInfoWindow(latLng: LatLng) { + this.latLng = latLng + //缩放动画 + val scaleAnimation: Animation = ScaleAnimation(1f, 1f, 0.75f, 1f) + //时间设置短点 + scaleAnimation.setDuration(500) + centerMarker.setAnimation(scaleAnimation) + centerMarker.startAnimation() + centerMarker.showInfoWindow() + } + + fun hideCenterMarkerInfoWindow() { + centerMarker.hideInfoWindow() + val bitmap: Bitmap = BitmapFactory.decodeResource(context.resources, R.mipmap.map_pin) + centerMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap)) + } + + fun destroy() { + centerMarker.destroy() + centerMarker.showInfoWindow() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml new file mode 100644 index 0000000..6b497b0 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 2cef713..9ee2ec9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,6 +100,8 @@ implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //高德地图 implementation 'com.amap.api:3dmap:latest.integration' + //高德地图搜索 + implementation 'com.amap.api:search:8.1.0' //CameraX def camerax_version = '1.2.3' implementation "androidx.camera:camera-core:$camerax_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2dbaa56..ee67360 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -73,6 +73,7 @@ + (), AMap.OnMapLoadedListener, + AMap.OnCameraChangeListener { + + private lateinit var aMap: AMap + private lateinit var centerMarkerView: CenterMarkerView + + override fun initOnCreate(savedInstanceState: Bundle?) { + binding.mapView.onCreate(savedInstanceState) + + aMap = binding.mapView.map + aMap.mapType = AMap.MAP_TYPE_NORMAL + val locationStyle = MyLocationStyle() + //定位一次,且将视角移动到地图中心点 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) + //设置是否显示定位小蓝点 + locationStyle.showMyLocation(true) + locationStyle.strokeColor(Color.TRANSPARENT) + locationStyle.strokeWidth(0f) + locationStyle.radiusFillColor(Color.TRANSPARENT) + aMap.myLocationStyle = locationStyle + aMap.isMyLocationEnabled = true + val uiSettings = aMap.uiSettings + uiSettings.isCompassEnabled = true + uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER + //不许地图随手势倾斜角度 + uiSettings.isTiltGesturesEnabled = false + //不允许地图旋转 + uiSettings.isRotateGesturesEnabled = false + //设置默认定位按钮是否显示 + uiSettings.isMyLocationButtonEnabled = true + //改变地图的缩放级别 + aMap.moveCamera(CameraUpdateFactory.zoomTo(18f)) + centerMarkerView = CenterMarkerView(this, aMap) + + aMap.setOnMapLoadedListener(this) + aMap.setOnCameraChangeListener(this) + } + + override fun initEvent() { + binding.confirmButton.setOnClickListener { + val intent = Intent() + intent.putExtra("longitude", binding.longitudeView.text) + intent.putExtra("latitude", binding.latitudeView.text) + setResult(RESULT_OK, intent) + finish() + } + } + + override fun initViewBinding(): ActivityDragMapBinding { + return ActivityDragMapBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun onMapLoaded() { + centerMarkerView.addCenterMarker() + } + + override fun onCameraChange(cameraPosition: CameraPosition) { + //隐藏中心点marker的InfoWindow + centerMarkerView.hideCenterMarkerInfoWindow() + } + + override fun onCameraChangeFinish(cameraPosition: CameraPosition) { + val latLng = cameraPosition.target + //显示infoWindow + centerMarkerView.showInfoWindow(latLng) + binding.longitudeView.text = latLng.longitude.toString() + binding.latitudeView.text = latLng.latitude.toString() + } + + override fun onResume() { + super.onResume() + binding.mapView.onResume() + } + + override fun onPause() { + super.onPause() + binding.mapView.onPause() + } + + override fun onDestroy() { + centerMarkerView.destroy() + binding.mapView.onDestroy() + super.onDestroy() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + binding.mapView.onSaveInstanceState(outState) + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).init() + + val insetsController = WindowCompat.getInsetsController(window, binding.rootView) + insetsController.hide(WindowInsetsCompat.Type.statusBars()) + insetsController.hide(WindowInsetsCompat.Type.navigationBars()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index c3b502c..decb588 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -1,12 +1,15 @@ package com.casic.br.operationsite.view +import android.app.Activity +import android.content.Intent import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.util.Log import android.view.View -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import com.casic.br.operationsite.R import com.casic.br.operationsite.callback.OnImageCompressListener import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding @@ -15,7 +18,6 @@ import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector @@ -34,9 +36,6 @@ import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch import java.io.File class InstallEquipmentActivity : KotlinBaseActivity() { @@ -79,7 +78,7 @@ //左右边距 val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 3, 3) + imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) binding.recyclerView.addItemDecoration( RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) ) @@ -90,20 +89,24 @@ } + private val selectLocationLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + binding.longitudeView.setText(data.getStringExtra("longitude")) + binding.latitudeView.setText(data.getStringExtra("latitude")) + } + } + }) + override fun initEvent() { binding.deviceCodeView.addTextChangedListener(textWatcher) binding.locationImageView.setOnClickListener { - LocationKit.getCurrentLocation(context, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "信号差,定位失败,请移动位置再试".show(context) - } else { - binding.longitudeView.setText(aMapLocation.longitude.toString()) - binding.latitudeView.setText(aMapLocation.latitude.toString()) - } - } - }) + selectLocationLauncher.launch(Intent(this, DragMapActivity::class.java)) } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -164,11 +167,9 @@ PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) .forResult(object : OnResultCallbackListener { override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return + result?.apply { + analyticalSelectResults(first()) } - analyticalSelectResults(result.first()) } override fun onCancel() { @@ -180,19 +181,12 @@ 1 -> { PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) + .setMaxSelectNum(1).isDisplayCamera(false) .setImageEngine(GlideLoadEngine.get) .forResult(object : OnResultCallbackListener { override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } + result?.apply { + analyticalSelectResults(first()) } } diff --git a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt new file mode 100644 index 0000000..1bdbcb4 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt @@ -0,0 +1,100 @@ +package com.casic.br.operationsite.widgets + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Point +import android.view.LayoutInflater +import android.view.View +import android.widget.TextView +import com.amap.api.maps.AMap +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.Marker +import com.amap.api.maps.model.MarkerOptions +import com.amap.api.maps.model.animation.Animation +import com.amap.api.maps.model.animation.ScaleAnimation +import com.amap.api.services.core.LatLonPoint +import com.amap.api.services.geocoder.GeocodeResult +import com.amap.api.services.geocoder.GeocodeSearch +import com.amap.api.services.geocoder.RegeocodeQuery +import com.amap.api.services.geocoder.RegeocodeResult +import com.casic.br.operationsite.R +import com.pengxh.kt.lite.extensions.breakLine + +class CenterMarkerView(private val context: Context, private var aMap: AMap) { + private lateinit var centerMarker: Marker + + //拿到地图中心点的坐标 + private var latLng = aMap.cameraPosition.target + private val geocoderSearch by lazy { GeocodeSearch(context) } + + init { + aMap.setInfoWindowAdapter(object : AMap.InfoWindowAdapter { + override fun getInfoWindow(marker: Marker): View { + val infoWindow = LayoutInflater.from(context).inflate( + R.layout.map_info_window, null + ) + val locationView: TextView = infoWindow.findViewById(R.id.locationView) + val queryParam = RegeocodeQuery( + LatLonPoint(latLng.latitude, latLng.longitude), 100f, GeocodeSearch.AMAP + ) + geocoderSearch.getFromLocationAsyn(queryParam) + geocoderSearch.setOnGeocodeSearchListener(object : + GeocodeSearch.OnGeocodeSearchListener { + override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult, code: Int) { + if (code == 1000) { + //手动换行 + val address = regeocodeResult.regeocodeAddress.formatAddress + locationView.text = address.breakLine(22) + } + } + + override fun onGeocodeSearched(geocodeResult: GeocodeResult?, i: Int) {} + }) + return infoWindow + } + + override fun getInfoContents(p0: Marker?): View? { + return null + } + }) + } + + fun addCenterMarker() { + val options = MarkerOptions() + //对应Marker.setIcon方法 设置Marker的图片 + options.icon(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin)) + //设置infoWindow与锚点的相对位置 + options.anchor(0.5f, 1f) + //把中心点的坐标转换成屏幕像素位置 + val screenPosition: Point = aMap.projection.toScreenLocation(latLng) + //在地图上添加Marker并获取到Marker. + centerMarker = aMap.addMarker(options) + //给marker设置像素位置。 + centerMarker.setPositionByPixels(screenPosition.x, screenPosition.y) + centerMarker.setAnchor(0.5f, 1f) + } + + fun showInfoWindow(latLng: LatLng) { + this.latLng = latLng + //缩放动画 + val scaleAnimation: Animation = ScaleAnimation(1f, 1f, 0.75f, 1f) + //时间设置短点 + scaleAnimation.setDuration(500) + centerMarker.setAnimation(scaleAnimation) + centerMarker.startAnimation() + centerMarker.showInfoWindow() + } + + fun hideCenterMarkerInfoWindow() { + centerMarker.hideInfoWindow() + val bitmap: Bitmap = BitmapFactory.decodeResource(context.resources, R.mipmap.map_pin) + centerMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap)) + } + + fun destroy() { + centerMarker.destroy() + centerMarker.showInfoWindow() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml new file mode 100644 index 0000000..6b497b0 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_blue.xml b/app/src/main/res/drawable/bg_stroke_layout_blue.xml new file mode 100644 index 0000000..26ddc25 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_blue.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 2cef713..9ee2ec9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -100,6 +100,8 @@ implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0' //高德地图 implementation 'com.amap.api:3dmap:latest.integration' + //高德地图搜索 + implementation 'com.amap.api:search:8.1.0' //CameraX def camerax_version = '1.2.3' implementation "androidx.camera:camera-core:$camerax_version" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2dbaa56..ee67360 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -73,6 +73,7 @@ + (), AMap.OnMapLoadedListener, + AMap.OnCameraChangeListener { + + private lateinit var aMap: AMap + private lateinit var centerMarkerView: CenterMarkerView + + override fun initOnCreate(savedInstanceState: Bundle?) { + binding.mapView.onCreate(savedInstanceState) + + aMap = binding.mapView.map + aMap.mapType = AMap.MAP_TYPE_NORMAL + val locationStyle = MyLocationStyle() + //定位一次,且将视角移动到地图中心点 + locationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_LOCATE) + //设置是否显示定位小蓝点 + locationStyle.showMyLocation(true) + locationStyle.strokeColor(Color.TRANSPARENT) + locationStyle.strokeWidth(0f) + locationStyle.radiusFillColor(Color.TRANSPARENT) + aMap.myLocationStyle = locationStyle + aMap.isMyLocationEnabled = true + val uiSettings = aMap.uiSettings + uiSettings.isCompassEnabled = true + uiSettings.zoomPosition = AMapOptions.ZOOM_POSITION_RIGHT_CENTER + //不许地图随手势倾斜角度 + uiSettings.isTiltGesturesEnabled = false + //不允许地图旋转 + uiSettings.isRotateGesturesEnabled = false + //设置默认定位按钮是否显示 + uiSettings.isMyLocationButtonEnabled = true + //改变地图的缩放级别 + aMap.moveCamera(CameraUpdateFactory.zoomTo(18f)) + centerMarkerView = CenterMarkerView(this, aMap) + + aMap.setOnMapLoadedListener(this) + aMap.setOnCameraChangeListener(this) + } + + override fun initEvent() { + binding.confirmButton.setOnClickListener { + val intent = Intent() + intent.putExtra("longitude", binding.longitudeView.text) + intent.putExtra("latitude", binding.latitudeView.text) + setResult(RESULT_OK, intent) + finish() + } + } + + override fun initViewBinding(): ActivityDragMapBinding { + return ActivityDragMapBinding.inflate(layoutInflater) + } + + override fun observeRequestState() { + + } + + override fun onMapLoaded() { + centerMarkerView.addCenterMarker() + } + + override fun onCameraChange(cameraPosition: CameraPosition) { + //隐藏中心点marker的InfoWindow + centerMarkerView.hideCenterMarkerInfoWindow() + } + + override fun onCameraChangeFinish(cameraPosition: CameraPosition) { + val latLng = cameraPosition.target + //显示infoWindow + centerMarkerView.showInfoWindow(latLng) + binding.longitudeView.text = latLng.longitude.toString() + binding.latitudeView.text = latLng.latitude.toString() + } + + override fun onResume() { + super.onResume() + binding.mapView.onResume() + } + + override fun onPause() { + super.onPause() + binding.mapView.onPause() + } + + override fun onDestroy() { + centerMarkerView.destroy() + binding.mapView.onDestroy() + super.onDestroy() + } + + override fun onSaveInstanceState(outState: Bundle) { + super.onSaveInstanceState(outState) + binding.mapView.onSaveInstanceState(outState) + } + + override fun setupTopBarLayout() { + ImmersionBar.with(this).init() + + val insetsController = WindowCompat.getInsetsController(window, binding.rootView) + insetsController.hide(WindowInsetsCompat.Type.statusBars()) + insetsController.hide(WindowInsetsCompat.Type.navigationBars()) + } +} \ No newline at end of file diff --git a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt index c3b502c..decb588 100644 --- a/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt +++ b/app/src/main/java/com/casic/br/operationsite/view/InstallEquipmentActivity.kt @@ -1,12 +1,15 @@ package com.casic.br.operationsite.view +import android.app.Activity +import android.content.Intent import android.os.Bundle import android.text.Editable import android.text.TextWatcher import android.util.Log import android.view.View -import androidx.lifecycle.lifecycleScope -import com.amap.api.location.AMapLocation +import androidx.activity.result.ActivityResult +import androidx.activity.result.ActivityResultCallback +import androidx.activity.result.contract.ActivityResultContracts import com.casic.br.operationsite.R import com.casic.br.operationsite.callback.OnImageCompressListener import com.casic.br.operationsite.databinding.ActivityInstallEquipmentBinding @@ -15,7 +18,6 @@ import com.casic.br.operationsite.model.UserDetailModel import com.casic.br.operationsite.utils.GlideLoadEngine import com.casic.br.operationsite.utils.LocaleConstant -import com.casic.br.operationsite.utils.LocationKit import com.google.gson.Gson import com.google.gson.reflect.TypeToken import com.luck.picture.lib.basic.PictureSelector @@ -34,9 +36,6 @@ import com.pengxh.kt.lite.utils.SaveKeyValues import com.pengxh.kt.lite.widget.TitleBarView import com.pengxh.kt.lite.widget.dialog.BottomActionSheet -import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.flow -import kotlinx.coroutines.launch import java.io.File class InstallEquipmentActivity : KotlinBaseActivity() { @@ -79,7 +78,7 @@ //左右边距 val viewWidth = getScreenWidth() - (10 + 10).dp2px(this) - imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 3, 3) + imageAdapter = EditableImageAdapter(this, recyclerViewImages, viewWidth, 1, 3) binding.recyclerView.addItemDecoration( RecyclerViewItemOffsets(marginOffset, marginOffset, marginOffset, marginOffset) ) @@ -90,20 +89,24 @@ } + private val selectLocationLauncher = registerForActivityResult( + ActivityResultContracts.StartActivityForResult(), + object : ActivityResultCallback { + override fun onActivityResult(result: ActivityResult?) { + if (result?.resultCode == Activity.RESULT_OK) { + val data = result.data ?: return + + binding.longitudeView.setText(data.getStringExtra("longitude")) + binding.latitudeView.setText(data.getStringExtra("latitude")) + } + } + }) + override fun initEvent() { binding.deviceCodeView.addTextChangedListener(textWatcher) binding.locationImageView.setOnClickListener { - LocationKit.getCurrentLocation(context, object : LocationKit.ILocationListener { - override fun onAMapLocationGet(aMapLocation: AMapLocation?) { - if (aMapLocation == null) { - "信号差,定位失败,请移动位置再试".show(context) - } else { - binding.longitudeView.setText(aMapLocation.longitude.toString()) - binding.latitudeView.setText(aMapLocation.latitude.toString()) - } - } - }) + selectLocationLauncher.launch(Intent(this, DragMapActivity::class.java)) } imageAdapter.setOnItemClickListener(object : EditableImageAdapter.OnItemClickListener { @@ -164,11 +167,9 @@ PictureSelector.create(context).openCamera(SelectMimeType.ofImage()) .forResult(object : OnResultCallbackListener { override fun onResult(result: ArrayList?) { - if (result == null) { - "拍照保存失败,请重试".show(context) - return + result?.apply { + analyticalSelectResults(first()) } - analyticalSelectResults(result.first()) } override fun onCancel() { @@ -180,19 +181,12 @@ 1 -> { PictureSelector.create(context).openGallery(SelectMimeType.ofImage()) .isGif(false).isMaxSelectEnabledMask(true).setFilterMinFileSize(100) - .setMaxSelectNum(3).isDisplayCamera(false) + .setMaxSelectNum(1).isDisplayCamera(false) .setImageEngine(GlideLoadEngine.get) .forResult(object : OnResultCallbackListener { override fun onResult(result: ArrayList?) { - lifecycleScope.launch { - flow { - result?.forEach { - emit(it) - delay(1000) - } - }.collect { - analyticalSelectResults(it) - } + result?.apply { + analyticalSelectResults(first()) } } diff --git a/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt new file mode 100644 index 0000000..1bdbcb4 --- /dev/null +++ b/app/src/main/java/com/casic/br/operationsite/widgets/CenterMarkerView.kt @@ -0,0 +1,100 @@ +package com.casic.br.operationsite.widgets + +import android.content.Context +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.Point +import android.view.LayoutInflater +import android.view.View +import android.widget.TextView +import com.amap.api.maps.AMap +import com.amap.api.maps.model.BitmapDescriptorFactory +import com.amap.api.maps.model.LatLng +import com.amap.api.maps.model.Marker +import com.amap.api.maps.model.MarkerOptions +import com.amap.api.maps.model.animation.Animation +import com.amap.api.maps.model.animation.ScaleAnimation +import com.amap.api.services.core.LatLonPoint +import com.amap.api.services.geocoder.GeocodeResult +import com.amap.api.services.geocoder.GeocodeSearch +import com.amap.api.services.geocoder.RegeocodeQuery +import com.amap.api.services.geocoder.RegeocodeResult +import com.casic.br.operationsite.R +import com.pengxh.kt.lite.extensions.breakLine + +class CenterMarkerView(private val context: Context, private var aMap: AMap) { + private lateinit var centerMarker: Marker + + //拿到地图中心点的坐标 + private var latLng = aMap.cameraPosition.target + private val geocoderSearch by lazy { GeocodeSearch(context) } + + init { + aMap.setInfoWindowAdapter(object : AMap.InfoWindowAdapter { + override fun getInfoWindow(marker: Marker): View { + val infoWindow = LayoutInflater.from(context).inflate( + R.layout.map_info_window, null + ) + val locationView: TextView = infoWindow.findViewById(R.id.locationView) + val queryParam = RegeocodeQuery( + LatLonPoint(latLng.latitude, latLng.longitude), 100f, GeocodeSearch.AMAP + ) + geocoderSearch.getFromLocationAsyn(queryParam) + geocoderSearch.setOnGeocodeSearchListener(object : + GeocodeSearch.OnGeocodeSearchListener { + override fun onRegeocodeSearched(regeocodeResult: RegeocodeResult, code: Int) { + if (code == 1000) { + //手动换行 + val address = regeocodeResult.regeocodeAddress.formatAddress + locationView.text = address.breakLine(22) + } + } + + override fun onGeocodeSearched(geocodeResult: GeocodeResult?, i: Int) {} + }) + return infoWindow + } + + override fun getInfoContents(p0: Marker?): View? { + return null + } + }) + } + + fun addCenterMarker() { + val options = MarkerOptions() + //对应Marker.setIcon方法 设置Marker的图片 + options.icon(BitmapDescriptorFactory.fromResource(R.mipmap.map_pin)) + //设置infoWindow与锚点的相对位置 + options.anchor(0.5f, 1f) + //把中心点的坐标转换成屏幕像素位置 + val screenPosition: Point = aMap.projection.toScreenLocation(latLng) + //在地图上添加Marker并获取到Marker. + centerMarker = aMap.addMarker(options) + //给marker设置像素位置。 + centerMarker.setPositionByPixels(screenPosition.x, screenPosition.y) + centerMarker.setAnchor(0.5f, 1f) + } + + fun showInfoWindow(latLng: LatLng) { + this.latLng = latLng + //缩放动画 + val scaleAnimation: Animation = ScaleAnimation(1f, 1f, 0.75f, 1f) + //时间设置短点 + scaleAnimation.setDuration(500) + centerMarker.setAnimation(scaleAnimation) + centerMarker.startAnimation() + centerMarker.showInfoWindow() + } + + fun hideCenterMarkerInfoWindow() { + centerMarker.hideInfoWindow() + val bitmap: Bitmap = BitmapFactory.decodeResource(context.resources, R.mipmap.map_pin) + centerMarker.setIcon(BitmapDescriptorFactory.fromBitmap(bitmap)) + } + + fun destroy() { + centerMarker.destroy() + centerMarker.showInfoWindow() + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml new file mode 100644 index 0000000..6b497b0 --- /dev/null +++ b/app/src/main/res/drawable/bg_solid_text_blue_radius_top_5.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/app/src/main/res/drawable/bg_stroke_layout_blue.xml b/app/src/main/res/drawable/bg_stroke_layout_blue.xml new file mode 100644 index 0000000..26ddc25 --- /dev/null +++ b/app/src/main/res/drawable/bg_stroke_layout_blue.xml @@ -0,0 +1,11 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_drag_map.xml b/app/src/main/res/layout/activity_drag_map.xml new file mode 100644 index 0000000..799d0e9 --- /dev/null +++ b/app/src/main/res/layout/activity_drag_map.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + +