使用数据快照从地图标记中获取数据
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
的最后一个对象。因此,您分配给 title
、id
和 desc
变量,这些值仅来自上次迭代。
我想从点击的标记中获取分配的数据。
要仅获取特定元素的数据,请使用以下代码:
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以上是关于使用数据快照从地图标记中获取数据的主要内容,如果未能解决你的问题,请参考以下文章