티스토리 뷰

728x90

지난 안드로이드에서 구글맵 기본 사용법에 이어 이번에는 마커를 생성하고 응용하는 방법에 대해 알아보겠습니다.

지도가 생성되자마자 마커 하나를 생성하고 해당 마커를 선택하였을 때 커스텀한 마커 정보창을 띄워보겠습니다.

 

구글맵을 띄우는 방법은 지난 포스팅에서 다루었기 때문에 이미 앱에 지도를 띄운 상태를 전제로 진행해보도록 하겠습니다.

 

구글맵에 마커를 추가 하기 위해선 MarkOptions와 Marker 클래스를 사용하면 됩니다.

지도가 생성할 준비가 되면 오버라이딩한 onMapReady() 메소드가 실행되는데요. 지도가 생성되자마자 추가하고 싶은 마커가 있다면 해당 메소드에서 마커를 생성하면 되겠습니다.

 

우선 MarkerOptions객체를 만들어 생성할 마커의 기본설정을 해줍니다. 

 

        LatLng seoul = new LatLng(37.494870, 126.960763);

        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(seoul);
        markerOptions.title("서울");
        markerOptions.snippet("한국의 수도");

기본 설정은 다음과 같이 해줍니다. MakersOptions.position(LatLng)은 마커의 위치를 설정합니다. 해당 메서드는 구글맵에서 위도 경도 위치정보를 갖는 LatLng 객체를 매개변수로 받습니다.

title은 마커의 이름이고 snippet은 마커의 설명입니다. 이 두가지를 설정하면 마커를 선택하였을 때 여기서 설정한 이름과 설명을 보여주는 팝업창이 생성됩니다.

 

이제 설정한 내용을 마커에 적용하고 지도에 띄워보겠습니다.

 

        Marker marker = mMap.addMarker(markerOptions);

        mMap.moveCamera(CameraUpdateFactory.newLatLng(seoul));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(14));

방법은 아주 간단합니다. onMapReady메서드의 매개변수인 구글지도 인스턴스의 addMarker메서드를 호출합니다.

그리고 여기서 지도에 추가한 마커를 계속해서 재사용하고 싶다면 addMarker메서드의 리턴값을 Marker객체에 저장하여 활용할 수 있습니다.

 

만약 최초에 마커를 추가하고 변경 및 사용할 일이 없다면 반환값을 받을 필요없이 addMarker메서드를 호출하기만 하면됩니다. 

 

마커를 추가하기만 한다면 앱을 실행하였을 때 지도의 시작지점이 정해지지 않았기 때문에 엉뚱한 곳에 초점이 맞춰진 상태로 실행됩니다. 저는 지도 인스턴스의 moveCamere메서드를 호출하여 위에서 생성한 seoul위치가 지도의 가운데에 오도록 설정하였습니다.

 

그리고 amimateCamere메서드를 호출하여 지도의 확대범위를 적당히 조절할 수 있습니다.

여기까지 완료한다면 서울을 중심으로 한 지도가 정상적으로 생성될 것입니다.

 

마커를 선택하면 위에서 설정한 title과 snippet이 나타나는데요. 이 두가지만 보여주기엔 너무 간단하여 여러분들이 보여주고 싶은 내용을 온전히 보여주지 못할수도 있습니다. 따라서 이 정보창을 커스텀하여 나타내는 방법을 알아보겠습니다.

 

우선 커스텀한 팝업창의 레이아웃 xml파일을 res->layout폴더에 생성합니다. 그리고 해당 레이아웃을 적용하기 위한 Adapter클래스를 생성해야합니다. 이 클래스는 GoogleMap.InfoWindowAdapter 인터페이스를 구현해야합니다.

이를 위해서 getInfoWindow와 getInfoContents메서드를 오버라이딩 해야합니다. 이 두 메서드는 Marker 객체를 매개변수로 받고 마커를 눌렀을 때 생성할 레이아웃 View를 리턴합니다.

두 메서드의 차이점은 만약 getInfoWindow가 null을 리턴하면 getInfoContents가 실행되고 반대로 getInfoContents가 null을 리턴하면 getInfoWindow가 실행됩니다. 

따라서 저희는 getInfoWindow만 구현해보도록 하겠습니다. 

 

public class DriverInfoAdapter implements GoogleMap.InfoWindowAdapter {
    View window;
    Student student;
    public DriverInfoAdapter(View window, Student student){
        this.window = window;
        this.student = student;//정보를 담은 객체
    }

    @Override
    public View getInfoWindow(Marker marker) {
        TextView driverName = window.findViewById(R.id.driverName);
        TextView driverPhone = window.findViewById(R.id.driverPhone);
        TextView arrivetime = window.findViewById(R.id.arriveTime);

        driverName.setText(student.driverName);
        driverPhone.setText(student.driverPhone);
        arrivetime.setText(student.arriveTime.toString());
        return window;
    }

    @Override
    public View getInfoContents(Marker marker) {
        return null;
    }
}

Adapter클래스의 예제 코드입니다. 저는 마커를 눌렀을 때 세개의 TextView를 가진 팝업창을 띄우도록 작성해보았습니다. 지도를 생성한 액티비티의 layoutinflater를 이용하여 위에서 생성한 커스텀 xml파일을 inflate해주고 이를 통해 할당 받은 View 를 해당 클래스의 생성자에서 window변수에 할당하였습니다.

 

그 뒤 각 TextView에 커스텀 레이아웃의 View들을 findViewById메서드를 통해 매핑시켜주고 내용을 생성자를 통해 할당받은 원하는 정보들로 채워주면 됩니다.

 

간략하게 정리하면

지도를 생성한 액티비티에서 커스텀 xml파일을 inflate -> inflate한 View를 Adapter 클래스의 생성자로 넘김-> Adapter클래스에서 커스텀View의 구성요소들을 매핑하고 내용을 채움

 

그렇다면 밖의 액티비티에서 어떻게 inflate하고 Adapter클래스 인스턴스를 생성하는지 보겠습니다.

        View infoWindow = getLayoutInflater().inflate(R.layout.your_custom_layout, null);
        DriverInfoAdapter driverInfoAdapter = new DriverInfoAdapter(infoWindow, student);

해당 코드는 지도를 생성한 액티비티의 onMapReady() 오버라이딩 메서드의 일부입니다. layoutinflater를 통해 커스텀 레이아웃을 inflate하고 이를 infoWindow라는 View인스턴스에 할당하였습니다. 그 후 위에서 생성한 Adapter클래스의 생성자로 넘겨줍니다.

 

그리고 이렇게 생성한 Adapter인스턴스를 구글 지도에 셋팅해주어야 합니다.

onMapReady의 매개변수로 들어온 구글지도 인스턴스에 해당 Adapter를 설정해줍니다.

 

        mMap.setInfoWindowAdapter(driverInfoAdapter);

다음은 제가 구현한 onMapReady의 풀 예제 코드입니다.

 

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        LatLng seoul = new LatLng(37.494870, 126.960763);

        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(seoul);
        markerOptions.title("서울");
        markerOptions.snippet("한국의 수도");
        mMap.addMarker(markerOptions);

        View infoWindow = getLayoutInflater().inflate(R.layout.activity_drive_info, null);
        DriverInfoAdapter driverInfoAdapter = new DriverInfoAdapter(infoWindow, student);
        mMap.setInfoWindowAdapter(driverInfoAdapter);
        mMap.moveCamera(CameraUpdateFactory.newLatLng(seoul));
        mMap.animateCamera(CameraUpdateFactory.zoomTo(14));

    }

여기까지 완료하면 구글지도 생성시 서울의 위치에 마커가 하나 생성되고 지도의 중심에 위치해 있으며

해당 마커를 선택하였을 때 원하는 정보를 담은 팝업창이 생성됩니다.

 

 

 

댓글