首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自定义InfoWindow标记

自定义InfoWindow标记
EN

Stack Overflow用户
提问于 2021-10-31 20:33:41
回答 1查看 42关注 0票数 0

我已经创建了一个应用程序,它为用户提供了五个选项。他们可以从这些选项中选择一个城市,并被引导到一个新的屏幕,在那里他们将看到该城市的MapView以及3个标记。我想在用户单击标记时创建一个customer InfoWindow。因此,我创建了一个名为infowindow.xml的自定义文件,并在其中创建了InfoWindow的布局。

然而,我不太确定如何在我的MapView中实现它。我已经提供了下面所有相关的代码:

任何帮助或指导都将不胜感激。

MainActivity.kt

代码语言:javascript
复制
    import android.content.Intent
    import androidx.appcompat.app.AppCompatActivity
    import android.os.Bundle
    import android.view.View
    import androidx.recyclerview.widget.LinearLayoutManager
    import androidx.recyclerview.widget.RecyclerView
    import com.tanav.tanavsharma_mapd711_assignment3.models.Place
    import com.tanav.tanavsharma_mapd711_assignment3.models.UserMap
    
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            /* Setting the layout manager on the recycler view
             ************* layout manager is responsible for telling the
             ************* recycler view how to layout the views on the
             ************* screen
             * Set adapter on the recycler view
             */
    
            val cityMaps = findViewById<RecyclerView>(R.id.cityMaps)
    
            val userMaps = generateSampleData()
            cityMaps.layoutManager = LinearLayoutManager(this)
            cityMaps.adapter = MapsAdapter(this, userMaps, object : MapsAdapter.OnClickListener{
                override fun onItemClick(position: Int) {
                    val intent = Intent(this@MainActivity, DisplayMapActivity::class.java)
                    intent.putExtra("UserMap", userMaps[position])
                    startActivity(intent)
                }
    
            })
        }
    
        private fun generateSampleData(): List<UserMap> {
            return listOf(
                UserMap(
                    "Toronto",
                    listOf(
    
                        Place("CN Tower Cruise", "290 Bremner Blvd, Toronto, ON M5V 3L9", "416-900-0098", "Open 9:00 AM to 6:30 PM",43.642905, -79.386900),
                        Place("Rail Way Cruise", "255 Bremner Blvd, Toronto, ON M5V 3M9", "416-900-0098","Open 9:00 AM to 6:30 PM",43.640805, -79.385945),
                        Place("Pinkbery Cruise", "161 King St E, Toronto, ON M5C 1G9", "416-900-0098","Open 9:00 AM to 6:30 PM",43.650050, -79.372404)
                    )
                ),
                UserMap("Mississauga",
                    listOf(
                        Place("Celebration Cruise", "300 City Centre Dr, Mississauga, ON L5B 3C1", "416-900-0098","Open 9:00 AM to 6:30 PM",43.588070, -79.643000),
                        Place("Golden Cruise", "1177 Central Pkwy W Unit 59, Mississauga, ON L5C 4P3", "416-900-0098","Open 9:00 AM to 6:30 PM",43.567164, -79.660391),
                        Place("Waterfall Cruise", "1180 Lakeshore Rd W, Mississauga, ON L5H 3L1", "416-900-0098","Open 9:00 AM to 6:30 PM",43.519416, -79.603003)
                    )),
                UserMap("Oakville",
                    listOf(
                        Place("Lions Valley Cruise", "1227 Lions Valley Park Rd, Oakville, ON L6M 4L8", "416-900-0098","Open 9:00 AM to 6:30 PM",43.459962, -79.748594),
                        Place("Lake Side Cruise", "2 Navy St, Oakville, ON L6J 2Y5", "416-900-0098","Open 9:00 AM to 6:30 PM",43.441586,-79.666197),
                        Place("Coronation Cruise", "1426 Lakeshore Rd W, Oakville, ON L6L 1G2","416-900-0098","Open 9:00 AM to 6:30 PM",43.409619, -79.692486),
                    )
                ),
                UserMap("Hamilton",
                    listOf(
                        Place("Heritage Cruise", "9280 Airport Rd, Mount Hope, ON L0R 1W0", "416-900-0098","Open 9:00 AM to 6:30 PM",43.159565, -79.925317),
                        Place("Red Hill Cruise", "768 Mountain Brow Blvd, Hamilton, ON L8W 1R6", "416-900-0098","Open 9:00 AM to 6:30 PM",43.200056, -79.819558),
                        Place("Spencer Cruise", "001 Harvest Rd, Dundas, ON L9H 4W2", "416-900-0098","Open 9:00 AM to 6:30 PM",43.281500, -79.980189),
                    )
                ),
                UserMap("North York",
                    listOf(
                        Place("Fairview Cruise", "1800 Sheppard Ave E, Toronto, ON M2J 5A7", "416-900-0098","Open 9:00 AM to 6:30 PM",43.777332, -79.344127),
                        Place("Pures Cruise", "1450 Midland Ave suite 200&300, Scarborough, ON M1P 4Z8","416-900-0098", "Open 9:00 AM to 6:30 PM",43.751293, -79.265983),
                        Place("Leion Cruise", "430 Nugget Ave, Scarborough, ON M1S 5E1", "416-900-0098","Open 9:00 AM to 6:30 PM",43.798544, -79.243165),
                    )
                )
            )
        }

}

DisplayMapActivity.kt

代码语言:javascript
复制
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuItem

import com.google.android.gms.maps.CameraUpdateFactory
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.OnMapReadyCallback
import com.google.android.gms.maps.SupportMapFragment
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.LatLngBounds
import com.google.android.gms.maps.model.MarkerOptions
import com.tanav.tanavsharma_mapd711_assignment3.databinding.ActivityDisplayMapBinding
import com.tanav.tanavsharma_mapd711_assignment3.models.UserMap


class DisplayMapActivity : AppCompatActivity(), OnMapReadyCallback {

    private lateinit var mMap: GoogleMap
    private lateinit var binding: ActivityDisplayMapBinding
    private lateinit var userMap: UserMap

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        binding = ActivityDisplayMapBinding.inflate(layoutInflater)
        setContentView(binding.root)

        userMap = intent.getSerializableExtra("UserMap") as UserMap

        supportActionBar?.title = userMap.title


        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        val mapFragment = supportFragmentManager
            .findFragmentById(R.id.map) as SupportMapFragment
        mapFragment.getMapAsync(this)
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.map_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        if(item.itemId == R.id.standard){
            mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL)
        }else if(item.itemId == R.id.satellite){
            mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE)
        }else if(item.itemId == R.id.hybrid){
            mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID)
        }
        return super.onOptionsItemSelected(item)

    }

    /**
     * Manipulates the map once available.
     * This callback is triggered when the map is ready to be used.
     * This is where we can add markers or lines, add listeners or move the camera. In this case,
     * we just add a marker near Sydney, Australia.
     * If Google Play services is not installed on the device, the user will be prompted to install
     * it inside the SupportMapFragment. This method will only be triggered once the user has
     * installed Google Play services and returned to the app.
     */
    override fun onMapReady(googleMap: GoogleMap) {
        mMap = googleMap

        // Add a marker in the place of click and move the camera

        val boundsBuilder = LatLngBounds.Builder()
        for(place in userMap.places){
            val latlng = LatLng(place.latitude, place.longitude)
            boundsBuilder.include(latlng)
            mMap.addMarker(MarkerOptions().position(latlng).title(place.title).snippet(place.address).snippet(place.number).snippet(place.hours))
        }
        mMap.moveCamera(CameraUpdateFactory.newLatLngBounds(boundsBuilder.build(), 1000, 1000, 0))
    }

MapsAdapter.kt

代码语言:javascript
复制
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.tanav.tanavsharma_mapd711_assignment3.models.UserMap

class MapsAdapter(val context: Context, val userMaps: List<UserMap>, val onClickListener: OnClickListener) : RecyclerView.Adapter<MapsAdapter.ViewHolder>() {

    interface OnClickListener {
        fun onItemClick(position: Int)
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(context).inflate(android.R.layout.simple_expandable_list_item_1, parent,false)
        return ViewHolder(view)
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        val userMap = userMaps[position]
        holder.itemView.setOnClickListener {
            onClickListener.onItemClick(position)
        }

        val textViewTitle = holder.itemView.findViewById<TextView>(android.R.id.text1)
        textViewTitle.text = userMap.title
    }

    override fun getItemCount() = userMaps.size

    class ViewHolder(itemView: View): RecyclerView.ViewHolder(itemView)
}

下面是我用过的类,Place.kt

代码语言:javascript
复制
import java.io.Serializable

data class Place(val title: String, val address: String, val number: String, val hours: String, val latitude: Double, val longitude: Double ) : Serializable

& UserMap.kt

代码语言:javascript
复制
import java.io.Serializable

data class UserMap(val title: String, val places: List<Place>) : Serializable

infowindow.xml

代码语言:javascript
复制
 <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        android:background="@drawable/common_google_signin_btn_icon_dark_normal_background"
        android:orientation="horizontal"
        android:padding="10dp">
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#99A2D6"
            android:orientation="vertical">
    
            <ImageView
                android:id="@+id/pictureStreet"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
    
                />
    
            <TextView
                android:id="@+id/title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingLeft="10dp"
                android:layout_gravity="start"
                android:ellipsize="end"
                android:maxLines="1"
                android:textColor="#000"
                android:textSize="20sp"
                android:textStyle="bold" />
    
            <TextView
                android:id="@+id/address"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingLeft="10dp"
                android:ellipsize="end"
                android:maxLines="10"
                android:textColor="#000"
                android:textSize="14sp" />
    
            <TextView
                android:id="@+id/number"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingLeft="10dp"
                android:ellipsize="end"
                android:maxLines="10"
                android:textColor="#000"
                android:textSize="14sp" />
    
            <TextView
                android:id="@+id/hours"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:paddingLeft="10dp"
                android:ellipsize="end"
                android:maxLines="10"
                android:textColor="#000"
                android:textSize="14sp" />
    
        </LinearLayout>
    
    
    </LinearLayout>

CustomInfoWindowAdapter.kt

代码语言:javascript
复制
import android.app.Activity
import android.view.LayoutInflater
import android.view.View
import android.widget.ImageView
import android.widget.TextView
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.model.Marker

class CustomInfoWindowAdapter(private val layoutInflater: LayoutInflater): GoogleMap.InfoWindowAdapter {

    var mlayoutInflater = layoutInflater
    var mWindow = (layoutInflater as Activity).layoutInflater.inflate(R.layout.infowindow, null)

    private fun rendowWindowText(marker: Marker, view: View){

        val tvTitle = view.findViewById<TextView>(R.id.title)
        val tvAddress = view.findViewById<TextView>(R.id.address)
        val tvNumber = view.findViewById<TextView>(R.id.number)
        val tvHours = view.findViewById<TextView>(R.id.hours)
        val ivPicture = view.findViewById<ImageView>(R.id.pictureStreet)

        tvTitle.text = marker.title
        tvAddress.text = marker.address // red underline
        tvNumber.text = marker.number // red underline
        tvHours.text = marker.hours // red underline
        ivPicture.setImageDrawable(R.drawable.cntower) //red underline
    }

    override fun getInfoWindow(marker: Marker): View {
        //Inflate and return your infolayout
        rendowWindowText(marker, mWindow)
        return mWindow
    }

    override fun getInfoContents(marker: Marker): View {
        //Inflate and return your infolayout
        rendowWindowText(marker, mWindow)
        return mWindow
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-31 23:25:06

首先,通过扩展GoogleMap.InfoWindowAdapter创建一个定制的InfoViewAdapter类,如下所示

代码语言:javascript
复制
class CustomInfoWindowAdapter(private val layoutInflater: LayoutInflater):GoogleMap.InfoWindowAdapter {
    override fun getInfoWindow(p0: Marker): View {
        //Inflate and return your infolayout
        return #YourInfoView
    }

    override fun getInfoContents(p0: Marker): View {
        //Inflate and return your infolayout
        return #YourInfoView
    }
}

然后,在您的onMapReady函数中,将您的适配器分配给map

代码语言:javascript
复制
mMap.setInfoWindowAdapter(CustomInfoWindowAdapter(layoutInflater))

就是这样。它应该会在点击标记时显示你的信息视图

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69790382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档