افزودن نشانگر (Marker) – کاتلین

مستندات جامع اندروید

در این آموزش هدف ما اضافه کردن یک نشانگر بر روی نقطه‌ای از نقشه است که کاربر بر روی آن نقطه لمس طولانی کرده است. همچنین تغییر نشانگر به آبی هنگامی که روی آن کلیک کند.

activity_add_marker.xml

فایل لی‌اوت این بخش صرفا شامل یک نقشه از کلاس org.neshan.mapsdk.MapView است.

                    
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="activity.AddLabel">

    <org.neshan.mapsdk.MapView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:id="@+id/map"/>

</android.support.constraint.ConstraintLayout>                    
                

AddMarkerActivity.kt

متغیری از نوع MapView جهت دریافت المان نقشه که در فایل لی‌اوت وجود دارد در نظر گرفته شده‌است و متغیری از نوع AnimationStyle برای انیمیشن ایجاد نشانه ها.

                    
    // map UI element
    private lateinit var mapView: MapView

    // marker animation style
    private lateinit var animSt: AnimationStyle                    
                

متد initLayoutRefrences جهت مقداردهی اولیه کردن به تمامی المان‌های مربوط به رابط کاربری نوشته شده‌است. به دلیل این که لازم است تا المان اندرویدی نقشه نشان ابتدا به طور کامل ایجاد شود و سپس با آن تعامل برقرار شود (متدهای مختلف بر روی المان نقشه اجرا شود)، تمامی متدهای مربوط به رابط کاربری باید در متد onStart انجام شوند.

                    
override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_add_marker)
    }

    override fun onStart() {
        super.onStart()
        // everything related to ui is initialized here
        initLayoutReferences()
    }                    
                

در این متد تمامی المان‌های مربوط به رابط کاربری – که در اینجا فقط نقشه نشان است – دریافت شده و به متغیری نسبت داده می‌شوند.

                    
// We use findViewByID for every element in our layout file here
    private fun initViews() {
        mapView = findViewById(R.id.mapview)
    }                    
                

در این متد ابتدا متد initViews صدا زده می شود که برای دریافت المان‌های رابط کاربری است و سپس listener های مورد نیاز برای نقشه تعریف می شود که در ادامه توضیح داده می شوند. یک OnMapClickListener بر روی نقشه **set ** می‌شود. هنگامی که هر کلیک بر روی نقشه انجام شود، تابع onMapClick صدا زده می‌شود که اینجا بدلیل استفاده از کد lambda نام این تابع نوشته نشده است. در این تابع با استفاده از موقعیتی که کاربر بر روی آن کلیک کرده، متد createMarker جهت ساخت یک نشانه جدید فراخوانی می شود و خروجی آن که یک شی از نوع Marker است به متد addMarker نقشه ارسال می شود تا نشانه جدید بر روی نقشه اضافه شده و نمایش داده شود.

همچنین یک OnMarkerClickListener تعریف شده که به هنگام کلیک شدن بر روی هر یک از نشانه های موجود بر روی نقشه فرخوانی خواهد شد. در این تابع نشانه ای که بر روی آن کلیک شده را دریافت کرده و با کمک تابع changeMarkerToBlue که جلوتر توضیح داده می شود، رنگ آن نشانه را به آبی تغییر می دهیم.

                    
// Initializing layout references (views, map and map events)
    private fun initLayoutReferences() {
        // Initializing views
        initViews()

        // when long clicked on map, a marker is added in clicked location
        mapView.setOnMapLongClickListener {
            mapView.addMarker(createMarker(it))
        }
        // when on marker clicked, change marker style to blue
        mapView.setOnMarkerClickListener { marker1: Marker ->
            changeMarkerToBlue(marker1)
        }
    }                    
                

متد addMarker یک نقطه جغرافیایی از نوع LatLng دریافت می‌کند. سپس برای ساخت انیمیشنِ ایجاد نشانگر بر روی نقشه، ابتدا یک شی از کلاس AnimationStyleBuilder ساخته و ویژگی‌های انیمیشن از جمله اندازه آن، نوع محو شدن و مدت ‌زمان‌های شروع و پایان انیمیشن در این شی set می‌شود. در نهایت با صدا زدن متد buildStyle بر روی این شی، شی‌ای از نوع AnimationStyle ساخته می‌شود. برای ایجاد style نشان‌گر نیز ابتدا یک شی از کلاس MarkerStyleBuilder ساخته می‌شود، سپس ویژگی‌های نشان‌گر مورد نظر بر روی آن set می‌شود. از جمله این ویژگی‌ها، نوع انیمیشن آن است که در بخش قبل ساخته شده است. در نهایت با صدا زدن متد buildStyle شی ای از نوع MarkerStyle به وجود می‌آید. در ادامه یک شی از نوع Marker ساخته می‌شود که سازنده آن، مکان درج نشان‌گر و style آن را به عنوان ورودی دریافت می‌کند. نشان‌گر ساخته شده به عنوان خروجی متد برگردانده می شود تا با استفاده از متد map.addMarker(marker) به نقشه اضافه شود

                    
// This method gets a LatLng as input and adds a marker on that position
    private fun createMarker(loc: LatLng): Marker {
        // Creating animation for marker. We should use an object of type AnimationStyleBuilder, set
        // all animation features on it and then call buildStyle() method that returns an object of type
        // AnimationStyle
        val animStBl = AnimationStyleBuilder()
        animStBl.fadeAnimationType = AnimationType.ANIMATION_TYPE_SMOOTHSTEP
        animStBl.sizeAnimationType = AnimationType.ANIMATION_TYPE_SPRING
        animStBl.phaseInDuration = 0.5f
        animStBl.phaseOutDuration = 0.5f
        animSt = animStBl.buildStyle()

        // Creating marker style. We should use an object of type MarkerStyleCreator, set all features on it
        // and then call buildStyle method on it. This method returns an object of type MarkerStyle
        val markStCr = MarkerStyleBuilder()
        markStCr.size = 30f
        markStCr.bitmap = BitmapUtils.createBitmapFromAndroidBitmap(
            BitmapFactory.decodeResource(
                resources, R.drawable.ic_marker
            )
        )
        // AnimationStyle object - that was created before - is used here
        markStCr.animationStyle = animSt
        val markSt = markStCr.buildStyle()

        // Creating marker
        return Marker(loc, markSt)
    }                    
                

متد changeMarkerToBlue که با کلیک بر روی هر نشانه فراخوانی می شود، یک نشانگر را به عنوان پارامتر ورودی دریافت میکند و با استفاده از MarkerStyleBuilder یک استایل با آیکون ic_marker_blue ساخته و به نشانه مورد نظر ست میکند. به این ترتیب با کلیک بر روی هر نشانه، آیکون آن از قرمز به رنگ آبی تغییر میکند.

                    
private fun changeMarkerToBlue(redMarker: Marker) {
        // create new marker style
        val markStCr = MarkerStyleBuilder()
        markStCr.size = 30f
        // Setting a new bitmap as marker
        markStCr.bitmap = BitmapUtils.createBitmapFromAndroidBitmap(
            BitmapFactory.decodeResource(
                resources, R.drawable.ic_marker_blue
            )
        )
        markStCr.animationStyle = animSt
        val blueMarkSt = markStCr.buildStyle()

        // changing marker style using setStyle
        redMarker.setStyle(blueMarkSt)
    }                    
                

حذف نشانگر

همچنین با استفاده از شی marker ساخته شده و متد removeMarker می توان نشانه رسم شده بر روی نقشه را بصورت زیر از روی نقشه حذف کرد:

                    
map.removeMarker(marker)