[FAQ] 지도/로컬 API 문의 전 꼭 읽어 주세요.
https://devtalk.kakao.com/t/faq-api/125610
Android에서 WebView에서 카카오맵 표시 후 가로 - 세로 기기 Rotation 시에 지도에서 중심에 있던 Pin이 좌측 하단으로 이동하고 있습니다.
현상을 보니 WebView 회전 시 중심을 기준으로 회전하는게 아니고 좌측 상단 모서리의 위치가 변하지 않는 방향으로 회전이 되는 것으로 보이는데 Client App에서 Google Map 처럼 화면 중심을 기준으로 회전을 제어할 수 있는 방법이 있는지 문의드립니다.
뷰포트가 변경될 때 resize 이벤트를 통해 지도 중심좌표를 다시 설정하는 방법이 있습니다.
안녕하세요. 아래 답변을 보고 작업 중입니다.
웹에서 지도를 두개띄우고 화면을 회전하는경우 마커가 사라지는 상황입니다 - 지도/로컬 API - 카카오 데브톡 (kakao.com)
window orientation 변경 시 이벤트는 잘 동작하며 relayout 및 setCenter 호출을 하고 있으나 직 후에 center_changed 이벤트가 불리고 있으며 center_changed시의 map의 center가 다시 틀어져 있습니다.
순서로 보아서는 setCenter 시에 적용한 좌표로 중심이 제대로 이동하지 않고 틀어진 좌표로 맵이 이동하여 center_changed 가 불린 것 같은데, 추가적으로 확인해야 할 사항이 있을까요?
관련 코드는 아래와 같습니다
var mapContainer = document.getElementById('map');
var mapOption = {
center: new kakao.maps.LatLng(0, 0),
level: 5,
disableDoubleClickZoom: true
};
var map = new kakao.maps.Map(mapContainer, mapOption);
var center = map.getCenter();
$(window).on('orientationchange', function(event) {
console.log('Orientation Changed: ' + center.getLat() + ', ' + center.getLng());
map.relayout();
map.setCenter(center);
sendMessage('Orientation Changed: ' + center.getLat() + ', ' + center.getLng());
setTimeout(function(){
}, 100);
});
kakao.maps.event.addListener(map, 'click', function(mouseEvent) {
var latlng = mouseEvent.latLng;
sendMessage('Clicked: ' + latlng.getLat() + ', ' + latlng.getLng());
window.android.onClick(latlng.getLat(), latlng.getLng());
});
kakao.maps.event.addListener(map, 'center_changed', function() {
center = map.getCenter();
sendMessage('Center Changed: ' + center.getLat() + ', ' + center.getLng());
window.android.onCameraPosition(center.getLat(), center.getLng());
});
kakao.maps.event.addListener(map, 'drag', function(event) {
center = map.getCenter();
sendMessage('Dragged: ' + level);
});
kakao.maps.event.addListener(map, 'zoom_changed', function() {
center = map.getCenter();
let level = map.getLevel();
sendMessage('Zoom Changed: ' + level);
window.android.onZoomChanged(level);
});
크롬 device mode로 확인해 보면 center_changed 실행 후 orientationchange 이벤트가 실행되는 걸 확인할 수 있는데요.
center_changed에서 변경된 좌표로 center를 재할당하고 있어
회전 시 좌표 이동 없이 동일한 중심 좌표로 보여주고 있을 것 같습니다.
회전 직전에는 center를 재할당하지 않게 방어하는 방법을 고려해주셔야 할 것 같아요.
안드로이드 웹뷰를 잘 몰라서 답변이 정확하지 않을 수 있지만
javascript에서 회전 상태를 확인하는 변수를 생성하고
안드로이드 onPause에서 해당 변수를 true로 바꿔주는 함수를 호출
center_changed가 실행될 때 true면 center를 재할당하지 않는 로직이 가능하면 이 부분도 고려해보면 좋을 것 같습니다.
제가 테스트 한 결과는 orientationchange가 먼저 호출되고 이후에 center_changed가 실행되고 있습니다.
orientationchange에서 이미 기존 좌표에 해서 setCenter를 호출했는데도 불구하고 이후에 center_changed가 호출되면서 map이 이동하는 원인을 알수가 없어서 답변드리게 되었습니다 ㅠㅠ
[INFO:CONSOLE(37)] “Orientation Changed:”, source: file:///android_asset/www/kakaomap.html (37)
[INFO:CONSOLE(55)] "Center Changed: ", source: file:///android_asset/www/kakaomap.html (55)
이벤트가 발생한 직후에는 화면이 변경 중일 수 있습니다.
변경 중에 이벤트에서 좌표를 처리하면 말씀하신 것처럼 이전과 동일한 상황으로 보일 수 있는데요.
시점의 문제로 setTimeout으로 해결할 수 있습니다.
아래 코드는 참고로만 봐주세요.
var center = map.getCenter();
screen.orientation.addEventListener('change', function(e) {
const mapCenter = center; //이벤트가 들어왔을 때 중심 좌표를 저장
console.log('Orientation Changed: ' + mapCenter.getLat() + ', ' + mapCenter.getLng());
setTimeout(() => {
map.relayout();
map.setCenter(mapCenter);
console.log('setCenter');
}, 10);
});
kakao.maps.event.addListener(map, 'center_changed', function() {
console.log('Center Changed: ' + center.getLat() + ', ' + center.getLng());
center = map.getCenter();
});