마스터Q&A 안드로이드는 안드로이드 개발자들의 질문과 답변을 위한 지식 커뮤니티 사이트입니다. 안드로이드펍에서 운영하고 있습니다. [사용법, 운영진]

네이버 지도 api 안드로이드 개발(말풍선 화살표 아이콘 클릭시 화면 이동)

0 추천
public class MapView extends NMapActivity implements NMapView.OnMapStateChangeListener, NMapOverlayManager.OnCalloutOverlayListener{

    NMapViewerResourceProvider mMapViewerResourceProvider = null; //NMapViewerResourceProvider 클래스 상속
    NMapOverlayManager mOverlayManager; //지도 위에 표시되는 오버레이 객체를 관리한다.
    NMapPOIdataOverlay.OnStateChangeListener onPOIdataStateChangeListener = null; //POI 아이템의 선택 상태 변경 시 호출되는 콜백 인터페이스를 정의한다.
    NMapOverlayManager.OnCalloutOverlayListener onCalloutOverlayListener; //말풍선 오버레이 객체 생성 시 호출되는 콜백 인터페이스를 정의한다.
    NMapLocationManager mMapLocationManager; //단말기의 현재 위치 탐색 기능을 사용하기 위한 클래스이다.
    //NMapLocationManager.OnLocationChangeListener onMyLocationChangeListener;
    NMapCompassManager mMapCompassManager; //단말기의 나침반 기능을 사용하기 위한 클래스이다.
    NMapMyLocationOverlay mMyLocationOverlay; //지도 위에 현재 위치를 표시하는 오버레이 클래스이며 NMapOverlay 클래스를 상속한다.

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.map_view);

        //네이버 지도를 넣기 위한 LinearLayout 컴포넌트
        MapContainer = (LinearLayout)findViewById(R.id.MapContainer);

        //네이버 지도 객체 생성
        mMapView = new NMapView(this);

        //지도 객체로부터 컨트롤러 추출
        mMapController = mMapView.getMapController();

        //네이버 지도 객체에 APIKEY 지정
        mMapView.setClientId(CLIENT_ID);

        //생성된 네이버 지도 객체를 LinearLayout에 추가시킨다.
        MapContainer.addView(mMapView);

        //지도를 터치할 수 있도록 옵션 활성화
        mMapView.setClickable(true);

        //확대/축소를 위한 줌 컨트롤러 표시 옵션 활성화
        mMapView.setBuiltInZoomControls(true, null);

        //지도에 대한 상태 변경 이벤트 연결
        mMapView.setOnMapStateChangeListener(this);


        //create resource provider(오버레이 객체)
        mMapViewerResourceProvider = new NMapViewerResourceProvider(this); //NMapViewerResourceProvider 클래스 상속
        mOverlayManager = new NMapOverlayManager(this, mMapView, mMapViewerResourceProvider); //오버레이 객체를 화면에 표시하기 위하여 NMapResourceProvider 클래스를 상속받은 resourceProvider 객체를 전달한다
        mOverlayManager.setOnCalloutOverlayListener(onCalloutOverlayListener); //말풍선 오버레이 객체 생성 시 호출되는 콜백 인터페이스를 설정한다.

        int markerId = NMapPOIflagType.PIN;
        NMapPOIdata poiData = new NMapPOIdata(2, mMapViewerResourceProvider); //전체 POI 아이템의 개수와 NMapResourceProvider를 상속받은 클래스를 인자로 전달한다.
        poiData.beginPOIdata(2); //POI 아이템 추가를 시작한다.

        NMapPOIitem item1 = poiData.addPOIitem(126.872772, 37.546848, "KB국민은행 염창역 지점 앞", markerId, 0); //POI아이템 설정
        item1.setRightAccessory(true, NMapPOIflagType.CLICKABLE_ARROW); //마커 선택 시 표시되는 말풍선의 오른쪽 아이콘을 설정한다.
        item1.hasRightAccessory(); //마커 선택 시 표시되는 말풍선의 오른쪽 아이콘 설정 여부를 반환한다.
        item1.setRightButton(true); //마커 선택 시 표시되는 말풍선의 오른쪽 버튼을 설정한다.
        item1.showRightButton(); //마커 선택 시 표시되는 말풍선의 오른쪽 버튼 설정 여부를 반환한다.

        NMapPOIitem item2 = poiData.addPOIitem(126.914925, 37.528728, "국회의원회관", markerId, 0);
        item2.setRightAccessory(true, NMapPOIflagType.CLICKABLE_ARROW);
        item2.hasRightAccessory();
        item2.setRightButton(true);
        item2.showRightButton();

        //poiData.addPOIitem(126.872772, 37.546848, "KB국민은행 염창역 지점 앞", markerId, 0); //경도위도 좌표 입력해주면, 그 좌표가 표시됨
        //poiData.addPOIitem(126.914925, 37.528728, "국회의원회관", markerId, 0); //경도위도 좌표 입력해주면, 그 좌표가 표시됨
        poiData.endPOIdata(); //POI 아이템 추가를 종료한다.
        NMapPOIdataOverlay poiDataOverlay = mOverlayManager.createPOIdataOverlay(poiData, null); //POI 데이터를 인자로 전달하여 NMapPOIdataOverlay 객체를 생성한다.
        poiDataOverlay.showAllPOIdata(0); //POI 데이터가 모두 화면에 표시되도록 지도 축척 레벨 및 지도 중심을 변경한다. zoomLevel이 0이 아니면 지정한 지도 축척 레벨에서 지도 중심만 변경한다.
        poiDataOverlay.setOnStateChangeListener(onPOIdataStateChangeListener); //POI 아이템의 선택 상태 변경 시 호출되는 콜백 인터페이스를 설정한다.

        // set data provider listener
        super.setMapDataProviderListener(onDataProviderListener); //지도 라이브러리에서 제공하는 서버 API 호출 시 응답에 대한 콜백 인터페이스를 설정한다.

        //locationManager(위치매니저)
        mMapLocationManager = new NMapLocationManager(this);
        mMapLocationManager.setOnLocationChangeListener(onMyLocationChangeListener);

        // compass manager(나침반 매니저)
        mMapCompassManager = new NMapCompassManager(this);

        // create my location overlay(내 위치 오버레이)
        mMyLocationOverlay = mOverlayManager.createMyLocationOverlay(mMapLocationManager, mMapCompassManager);

        editText = (EditText)findViewById(R.id.editText);
        btn_back = (ImageButton)findViewById(R.id.btn_back);
        str_text = editText.getText().toString();
    }

소스는 이렇습니다.

public void onCalloutClick(NMapPOIdataOverlay poiDataOverlay, NMapPOIitem item)

이 메소드가 말풍선 클릭시 호출되는 메소드라고 알고있는데, 여기서 말풍선의 빨간색 화살표 아이콘을 클릭하면 Detail.class 화면으로 intent로 넘기고 싶어요.

소스를 어떻게 작성해야 할까요?

현재 이런식으로 되어있는데요, 여기서 빨간색 버튼을 클릭하면 Detail.class로 넘어가야 합니다.

이런 예제가 없어서 구현하기가 힘드네요..

그리고 한 가지 더 질문하자면, POI Item의 id값을 받아오는 메소드도 있나요?

제가 Detail에서 구현하고자 하는게, 빨간색 버튼을 클릭해서 넘어가면 저 화면이 그대로 뜨고, '국회의원회관'이라는 명칭과 주소를 지도 View 아래 TextView로 표시하고 싶거든요.

예시이미지를 보여드리자면, 빨간버튼을 클릭해서 넘어가면, 이 화면이 뜨는거죠.

전혀 감이 안 와서요..

답변 기다리겠습니다..ㅠㅠ

 

+글자수 제한 때문에 덧글로 나머지 소스 올리겠습니다.

소스가 너무 길어서 import부분이랑 일부 윗부분 제외했어요!

진여울 (300 포인트) 님이 2016년 12월 1일 질문
진여울님이 2016년 12월 1일 수정
public void onCalloutClick(NMapPOIdataOverlay poiDataOverlay, NMapPOIitem item) { //POI 아이템의 말풍선이 선택되면 호출된다.
        //[[TEMP]] handle a click event of the callout
        Toast.makeText(MapView.this, "onCalloutClick: " + item.getTitle(), Toast.LENGTH_LONG).show();

        Intent it = new Intent(this, Desc.class);
        startActivity(it);
        finish();
    }

    public void onFocusChanged(NMapPOIdataOverlay poiDataOverlay, NMapPOIitem item) { //그룹 오버레이 아이템의 선택 상태가 변경되면 호출된다.
        if (item != null) {
            Log.i("NMAP", "onFocusChanged: " +item.toString());
        } else {
            Log.i("NMAP", "onFocusChanged: ");
        }
    }


    public NMapCalloutOverlay onCreateCalloutOverlay(NMapOverlay arg0, NMapOverlayItem arg1, Rect arg2) { //POI 아이템 선택 시 말풍선 오버레이 객체를 생성하기 전에 호출된다.
        //set your callout overlay
        return new NMapCalloutBasicOverlay(arg0, arg1, arg2);
    }


    public void startMyLocation() { //현재 위치 시작 메소드
        if (mMyLocationOverlay != null) {  //mMyLocationOverlay(지도 위에 현재 위치를 표시하는 오버레이 클래스이며 NMapOverlay 클래스를 상속한다.)값이 null이 아닐 때
            if (!mOverlayManager.hasOverlay(mMyLocationOverlay)) { //전달된 overlay 객체의 존재 여부를 반환한다.
                mOverlayManager.addOverlay(mMyLocationOverlay); //오버레이 객체를 추가한다.
            }

            if (mMapLocationManager.isMyLocationEnabled()) { //현재 위치 탐색 중인지 여부를 반환한다.

                if (!mMapView.isAutoRotateEnabled()) { //지도 회전 기능 활성화 상태를 가져온다.
                    mMyLocationOverlay.setCompassHeadingVisible(true); //나침반 각도 표시 여부를 설정한다.

                    mMapCompassManager.enableCompass(); //나침반 모니터링을 종료한다.

                    mMapView.setAutoRotateEnabled(true, false); //지도 회전 기능 활성화 여부를 설정한다.(지도 회전 활성화 여부, 지도 회전 해제 시 애니메이션 여부)

                    MapContainer.requestLayout(); //레이아웃에 반영
                } else {
                    stopMyLocation();
                }

                mMapView.postInvalidate();
            } else {
                boolean isMyLocationEnabled = mMapLocationManager.enableMyLocation(true);
                if (!isMyLocationEnabled) {
                    Toast.makeText(MapView.this, "Please enable a My Location source in system settings", Toast.LENGTH_LONG).show();

                    Intent goToSettings = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    startActivity(goToSettings);

                    return;
                }
            }
        }
    }

    public void stopMyLocation() { //현재 위치 탐색 멈춤 메소드
        if (mMyLocationOverlay != null) {
            mMapLocationManager.disableMyLocation(); //현재 위치 탐색을 종료한다.

            if (mMapView.isAutoRotateEnabled()) { //지도 회전 기능 활성화 상태를 가져온다.
                mMyLocationOverlay.setCompassHeadingVisible(false); //나침반 각도 표시 여부를 설정한다.

                mMapCompassManager.disableCompass(); //나침반 모니터링을 종료한다.

                mMapView.setAutoRotateEnabled(false, false); //지도 회전 기능 활성화 여부를 설정한다.(지도 회전 활성화 여부, 지도 회전 해제 시 애니메이션 여부)

                MapContainer.requestLayout(); //레이아웃에 반영
            }
        }
    }

    public final NMapActivity.OnDataProviderListener onDataProviderListener = new NMapActivity.OnDataProviderListener() { //오버레이 객체 사용을 위한 리스너
        @Override
        public void onReverseGeocoderResponse(NMapPlacemark placeMark, NMapError errInfo) { //지도 라이브러리에서 제공하는 서버 API 호출 시 응답에 대한 콜백 인터페이스를 정의한다.

            if (errInfo != null) { //에러발생시
                Log.e("myLog", "Failed to findPlacemarkAtLocation: error=" + errInfo.toString());

                Toast.makeText(MapView.this, errInfo.toString(), Toast.LENGTH_LONG).show();

                return;
            }else{ //에러가 없을 때 위치 정보 토스트로 띄움
                Toast.makeText(MapView.this, placeMark.toString(), Toast.LENGTH_LONG).show();
            }
        }
    };

    public final NMapLocationManager.OnLocationChangeListener onMyLocationChangeListener = new NMapLocationManager.OnLocationChangeListener() { //단말기의 현재 위치 상태 변경 시 호출되는 콜백 인터페이스를 정의한다.

        @Override
        public boolean onLocationChanged(NMapLocationManager locationManager, NGeoPoint myLocation) { //현재 위치 변경 시 호출된다. myLocation객체에 변경된 좌표가 전달된다. 현재 위치를 계속 탐색하려면 true를 반환한다.
//   if (mMapController != null) {
//    mMapController.animateTo(myLocation);
//   }

            Log.d("myLog", "myLocation  lat " + myLocation.getLatitude());
            Log.d("myLog", "myLocation  lng " + myLocation.getLongitude());

            findPlacemarkAtLocation(myLocation.getLongitude(), myLocation.getLatitude());
            //위도, 경도를 주소로 변환

            return true;
        }

        @Override
        public void onLocationUpdateTimeout(NMapLocationManager locationManager) { //정해진 시간 내에 현재 위치 탐색 실패 시 호출된다.
            // stop location updating
            // Runnable runnable = new Runnable() {
            // public void run() {
            // stopMyLocation();
            // }
            // };
            // runnable.run();

            Toast.makeText(MapView.this, "Your current location is temporarily unavailable.", Toast.LENGTH_LONG).show();
        }

        @Override

        public void onLocationUnavailableArea(NMapLocationManager locationManager, NGeoPoint myLocation) { //현재 위치가 지도 상에 표시할 수 있는 범위를 벗어나는 경우에 호출된다.
            Toast.makeText(MapView.this, "Your current location is unavailable area.", Toast.LENGTH_LONG).show();
            stopMyLocation();
        }
    };

}

1개의 답변

0 추천
 
채택된 답변
안녕하세요

개발자 사이트에 소상히 나와 있는데요...

개발문서나 튜토리얼에서 찾아보신 후에 안되시는 부분을 문의하시는게 좋을 것 같습니다.

http://developer.naver.com/wiki/pages/Android
히로시 (10,800 포인트) 님이 2016년 12월 2일 답변
진여울님이 2016년 12월 13일 채택됨
개발자 사이트 봐도 이해가 잘 안 가서요.. 혹시 이건 알려주실 수 있나요? 말풍선의 빨간색 버튼 클릭시 화면 넘어가는 메소드가 어떤 거인가요?
예제가 말풍선 띄우는 것까진 있는데, 말풍선에서 상세정보 보기 화면으로 넘어가는 건 못 찾겠더라구요..
빨간색 버튼을 클릭 가능하게 설정까진 했는데, 클릭하면 intent로 화면이 넘어가게 하는 소스를 넣고 싶습니다.

NMapPOIitem item1 = poiData.addPOIitem(126.872772, 37.546848, "KB국민은행 염창역 지점 앞", markerId, 0); //POI아이템 설정
        item1.setRightAccessory(true, NMapPOIflagType.CLICKABLE_ARROW); //마커 선택 시 표시되는 말풍선의 오른쪽 아이콘을 설정한다.
        item1.hasRightAccessory(); //마커 선택 시 표시되는 말풍선의 오른쪽 아이콘 설정 여부를 반환한다.
        item1.setRightButton(true); //마커 선택 시 표시되는 말풍선의 오른쪽 버튼을 설정한다.
        item1.showRightButton(); //마커 선택 시 표시되는 말풍선의 오른쪽 버튼 설정 여부를 반환한다.

버튼 관련 부분은 여기인 것 같은데요, 이건 버튼을 표시하는 부분인 것 같은데, 여기서 더 뭘 써야 하나요..? Intent를 어디다가 넣어야할지 모르겠어서요..
NMapCalloutCustomOverlayView.java 파일이 말풍선 커스텀 하는 것 입니다.
네이버 참고 소스에서 가져왔다면 아래와 같이 하시면 됩니다.

화살표에 이벤트 넣을 때 이렇게 하시면 됩니다
// mCalloutView.setOnClickListener(callOutClickListener);   << 이부분 주석으로 막으시고
callout_overlay_view.xml 에서 callout_overlay << android:clickable="true" 삭제 후
이벤트 리스너 설정하시면 됩니다.
(말풍선 레이아웃 전체 클릭 이벤트가 걸려 있음)
mRightArrow.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent = new Intent(getContext(), 이동할 액티비티);
                getContext().startActivity(intent);
            }
        });

커스텀 예제는 정해진 대로만 해놓은거라서 질문자님이 하고자하는대로 하실때는
소스를 분석하셔서 커스텀 하셔야합니다.
...