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

时间:2019-11-16 12:17:53

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

我有这个数据库:

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

2 个答案:

答案 0 :(得分: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属性了吗?

  

因此,无论我单击什么标记,我总是从数据库中获得相同的数据。

让我猜,它总是最后一个,对吧?请注意,这是预期的行为,因为您正在遍历所有对象,并且仅将最后一个添加到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对象上,因此不需要循环。

  

所以我希望该标记将数据从标记传递到详细信息活动中。

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

答案 1 :(得分:0)

从firebase的onMapReady中加载标记。

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
}