【问题标题】: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 获得相同的数据。 我想从单击的标记中获取分配的数据。怎么了?

【问题讨论】:

    标签: android firebase google-maps kotlin firebase-realtime-database


    【解决方案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
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 2020-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多