ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [ Android ] View 의 이미지 화 (구글 맵 마커 커스터 마이징 예제)
    Android & Kotlin 2022. 6. 20. 00:52

     

    📌  배경

    구글맵의 마커 부분을 기존 서비스에서 제공하는 ui 형태가 아닌

    새로운 ui 로 커스터마이징 해서 사용하고 싶어 찾던중

     

    View 를 Bitmap 으로 변환하는 방법을 알게 되었습니다.

     

     

    📌 주요 코드 분석 

     

     

    1. View 의 Instance 화

    • 커스터마이징할 뷰를 생성하고 인플레이트하여 인스턴스화 시켜줍니다.
    • 그 외 필요한 값에 대해 초기화 해줍니다.

     

    2. View 의 위치 및 크기 설정

    • measure 함수를 호출함으로써 onMeasure 가 내부적으로 호출되고 비로서 우리는 View 의 크기에 대한 접근을 할 수 있게 됩니다. 그전에는 0 값을 반환함.
    • measure 의 인자인 measureSpec 에 UNSPECIFIED 에 해당하는 0 을 넣었습니다.

     

     

    https://developer.android.com/reference/android/view/View.MeasureSpec

     

    View.MeasureSpec  |  Android Developers

    android.net.wifi.hotspot2.omadm

    developer.android.com

     

    3. View 의 Bitmap 화

    • View 의 키기에 맞는 비트맵(View 를 그릴 빈 도화지 ) 을 생성합니다.
      • createBitmap()
    • 비트맵을(빈 도화지를 ) 캔버스 위에 올립니다.
      •  Canvas(bitmap)
    • 원하는 뷰를 캔버스를 통해 비트맵에 그립니다.
      •  markerContainer(=View).draw(canvas)

     

    진행중 View 를 통해 draw 함수를 호출하고 인자로 canvas 넣었는데 그 안에 있는 비트맵이 변경된는 

    다소 부자연스러운 플로우로 인해 이해가 좀 어려웠던 것 같습니다.

     

     

    📌  결과

     

    class MapActivity : AppCompatActivity(), OnMapReadyCallback {
        private lateinit var binding: ActivityMapBinding
        private lateinit var mMap: GoogleMap
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            binding = DataBindingUtil.setContentView(this, R.layout.activity_map)
            setContentView(binding.root)
    
            setMapFragment()
            listenBackButtonClick()
        }
    
        private fun listenBackButtonClick() {
            binding.btnBackToMenu.setOnClickListener {
                finish()
            }
        }
    
        private fun setMapFragment() {
            val mapFragment = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment
            mapFragment.getMapAsync(this)
        }
    
    
        override fun onMapReady(googleMap: GoogleMap) {
            mMap = googleMap
            val location = LatLng(37.491, 127.0335)
    
            // 방법2. View를 이미지화하여 구현한 방법(완전한 Custom이 가능함)
            addMyMarker(Marker(37.491, 127.0335, "₩201,599"))
            addMyMarker(Marker(37.501, 127.0362, "₩101,699"))
            addMyMarker(Marker(37.4612, 127.0513, "₩11,599"))
    
            mMap.moveCamera(CameraUpdateFactory.newLatLng(location))
            mMap.animateCamera(CameraUpdateFactory.zoomTo(12.0f));
    
        }
    
        private fun addMyMarker(marker: Marker) {
    
            val markerOptions = MarkerOptions().apply {
                position(LatLng(marker.lat, marker.lon))
                title(marker.price)
                icon(
                    BitmapDescriptorFactory.fromBitmap(
                        createDrawableFromView(
                            marker.price
                        )
                    )
                )
            }
            mMap.addMarker(markerOptions)
        }
    
        private fun createDrawableFromView(price: String): Bitmap {
            val markerContainer = LayoutInflater.from(this).inflate(R.layout.custom_marker, null);
            val markerTextView = markerContainer.findViewById<TextView>(R.id.tv_marker)
            markerTextView.text = price
    
            val displayMetrics = DisplayMetrics()
    
            markerContainer.measure(displayMetrics.widthPixels, displayMetrics.heightPixels)
            markerContainer.layout(0, 0, displayMetrics.widthPixels, displayMetrics.heightPixels)
    
            val bitmap =
                Bitmap.createBitmap(
                    markerContainer.measuredWidth,
                    markerContainer.measuredHeight,
                    Bitmap.Config.ARGB_8888
                )
            val canvas = android.graphics.Canvas(bitmap)
            markerContainer.draw(canvas)
    
            return bitmap
        }
    }

     

    댓글

Designed by Tistory.