使用数据快照从地图标记中获取数据

Posted

技术标签:

【中文标题】使用数据快照从地图标记中获取数据【英文标题】:Fetch data from map Marker using datasnapshot 【发布时间】:2020-03-12 09:51:12 【问题描述】:

我有这个数据库:


  "Locale" : 
    "Feed1" : 
      "title" : "title1"
      "desc" : "description"
       "lat" : 47.56494,
      "lng" : 46.245,
    ,
    "Feed2" : 
      "desc" : "Desc nomer 2",
      "id" : "id 2",
      "lat" : 45.56494,
      "lng" : 47.245,
      "title" : "title2"
    
  ,

我在我的活动中添加了带有标记的 g-map。当我单击标记时,它会打开新的详细信息活动。所以我希望这个标记将数据从标记传递到详细活动中。

我使用 onMarkerClick:

override fun onMarkerClick(marker: Marker): Boolean 
        mRefLocal.addValueEventListener(vael)
        return false
    

这是我的 addValueEventListener(vael)

  var vael: ValueEventListener = object : ValueEventListener 
            override fun onDataChange(dataSnapshot: DataSnapshot) 
                for (snapshot in dataSnapshot.children) 
                    val feeds = snapshot.getValue(Feeds::class.java)
                    title = feeds!!.title
                    id = feeds.id
                    desc = feeds.desc
                
                val intent = Intent(this@MapsActivity, FeedsDetail::class.java)
                intent.putExtra("id", id)
                intent.putExtra("desc", desc)
                intent.putExtra("title", title)
                startActivity(intent)
                Toast.makeText(this@MapsActivity, title, Toast.LENGTH_SHORT).show()
            
            override fun onCancelled(databaseError: DatabaseError) 
        

所以无论我点击什么标记,我总是从 db 获得相同的数据。 我想从单击的标记中获取分配的数据。怎么了?

【问题讨论】:

【参考方案1】:

当您使用以下代码时:

override fun onMarkerClick(marker: Marker): Boolean 
    mRefLocal.addValueEventListener(vael)
    return false

您将在 mRefLocal 节点上添加一个侦听器,该侦听器指向 Locale 节点,而不是特定的 FeedsDetail 对象。 Locale 节点包含所有 FeedsDetail 对象。因此,您应该使用:

mRefLocal.child(marker.title).addValueEventListener(vael)

看,我已经添加了对.child(marker.name) 的呼叫。由于您没有 name 属性,因此您应该在每个对象下添加它。您的架构应如下所示:


  "Locale" : 
    "Feed1" : 
       "name" : "Feed1", //Added
       "title" : "title1",
       "desc" : "description1",
       "id" : "id 1",
       "lat" : 47.56494,
       "lng" : 46.245
    ,
    "Feed2" : 
       "name" : "Feed2", //Added
       "title" : "title2",
       "desc" : "Desc nomer 2",
       "id" : "id 2",
       "lat" : 45.56494,
       "lng" : 47.245
    
  ,

看到,每个对象下的新name 属性?

所以无论我点击什么标记,我总是从 db 获得相同的数据。

让我猜猜,它总是最后一个,对吧?请注意,这是预期的行为,因为您正在遍历所有对象并且您只添加到 Intent 的最后一个对象。因此,您分配给 titleiddesc 变量,这些值仅来自上次迭代。

我想从点击的标记中获取分配的数据。

要仅获取特定元素的数据,请使用以下代码:

var vael: ValueEventListener = object : ValueEventListener 
    override fun onDataChange(dataSnapshot: DataSnapshot) 
        val feeds = dataSnapshot.getValue(Feeds::class.java)

        val intent = Intent(this@MapsActivity, FeedsDetail::class.java)
        intent.putExtra("id", feeds.id)
        intent.putExtra("desc", feeds.desc)
        intent.putExtra("title", feeds!!.title)
        startActivity(intent)
        Toast.makeText(this@MapsActivity, title, Toast.LENGTH_SHORT).show()
    
    override fun onCancelled(databaseError: DatabaseError) 

看,现在不需要任何循环,因为监听器只添加到特定的FeedsDetail 对象上。

所以我希望这个标记将数据从标记传递到详细活动。

使用此解决方案,您只需传递所单击标记的详细信息。

【讨论】:

嗨,当我添加这个 mRefLocal.child(marker.name).addValueEventListener(vael) 时,我应该在哪里添加名称,因为它是红色的(错误)。 首先,在您的 FeedsDetail 类中添加一个新的 name 字段,然后按照上述架构中的说明将其也添加到数据库中。现在可以用了吗? FeedsDetail 中的 name 字段您的意思是 var name: String? = null?,我按照你说的做了,还是红色的 名称应首先添加到您的FeedsDetail 类、数据库和Marker 对象中。所以每个Marker 对象都应该设置Title 对应的名称。例如,如果一个位置有一个名称为Feed1 的标记,那么您应该将标题设置为Feed1。要获得标记的名称,您应该使用maker.title,如我更新的答案中所示。抱歉写了marker.name,我的错。 我把title放在mRefLocal.child(marker.title).addValueEventListener(vael)里面,现在可以了,谢谢,你真的帮了我!【参考方案2】:

在 onMapReady 中从 firebase 加载您的标记。

override fun onMapReady(googleMap: GoogleMap) 
    mMap = googleMap
    mRefLocal.addValueEventListener(vael)

当您创建标记时,设置您的提要对象

var vael: ValueEventListener = object : ValueEventListener 
    override fun onDataChange(dataSnapshot: DataSnapshot) 
         for (snapshot in dataSnapshot.children) 
            val feeds = snapshot.getValue(Feeds::class.java)
            val marker = mMap.addMarker(MarkerOptions())
            marker.tag = feeds
        
    
    override fun onCancelled(databaseError: DatabaseError) 

在您的活动中打开 - onClickMarker

override fun onMarkerClick(marker: Marker): Boolean 
    val feed = marker.tag as Feed
    val intent = Intent(this@MapsActivity, FeedsDetail::class.java)
    intent.putExtra("id", feed.id)
    intent.putExtra("desc", feed.desc)
    intent.putExtra("title", feed.title)
    startActivity(intent)
    Toast.makeText(this@MapsActivity, title, Toast.LENGTH_SHORT).show()
    return false

【讨论】:

你需要执行onMapReady

以上是关于使用数据快照从地图标记中获取数据的主要内容,如果未能解决你的问题,请参考以下文章

使用数据库中的坐标在地图上添加标记,使用 JSON 检索数据

谷歌地图没有从数据库中提取我的标记

谷歌地图标记聚类不适用于缩小

在谷歌地图标记上显示信息

使用标记从谷歌地图获取纬度/经度坐标

带有自定义标记的 Android 地图(标记上的文本)