Kotlin 和 Firebase :根据点击的地图标记在底部工作表中显示不同的数据

Posted

技术标签:

【中文标题】Kotlin 和 Firebase :根据点击的地图标记在底部工作表中显示不同的数据【英文标题】:Kotlin & Firebase : Display different data in the bottom sheet according to the map marker that is clicked 【发布时间】:2021-09-02 14:46:13 【问题描述】:

我正在使用 Kotlin。我有一张地图,显示与 Firebase 中存在的数据不同的标记(经度、纬度)。 这方面一切正常。

但是我现在想在单击标记时在底部表中显示其余的 Firebase 数据。 为此,我创建了一个底部工作表,当我单击地图上的标记时显示该工作表(使用 setOnMarkerClickListener)。 但是现在,我不知道如何根据点击的标记显示数据。

这是我的名为“Mission”的数据库。

这是我点击标记时显示的底部表格。效果很好。

这是地图的代码。

package com.example.givenaskv1.fragment

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import com.airbnb.lottie.model.Marker
import com.example.givenaskv1.Map.BottomsheetMissionMap
import com.example.givenaskv1.R
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.model.BitmapDescriptorFactory
import com.google.android.gms.maps.model.LatLng
import com.google.android.gms.maps.model.MarkerOptions
import com.google.firebase.database.*
import kotlinx.android.synthetic.main.fragment_map.*

private lateinit var mMap: GoogleMap

class MapFragment : Fragment(), OnMapReadyCallback 
    
    private lateinit var dbref : DatabaseReference
    var marker: Marker? = null
    
    override fun onActivityCreated(savedInstanceState: Bundle?) 
        super.onActivityCreated(savedInstanceState)

        map_view.onCreate(savedInstanceState)
        map_view.onResume()
        map_view.getMapAsync(this)
        
    
    override fun onMapReady(googleMap: GoogleMap?) 
        mMap = googleMap!!
        // GOES UP TO 21
        val zoomLevel = 14.0f 
        // MARKER FROM DATABASE
        dbref = FirebaseDatabase.getInstance().getReference("Mission")
        dbref.addValueEventListener(object : ValueEventListener 
            override fun onDataChange(snapshot: DataSnapshot) 
                if (snapshot.exists()) 
                    for (missionSnapshot in snapshot.children) 
                        val lat: String = missionSnapshot.child("latitude").value.toString()
                        val lng: String = missionSnapshot.child("longitude").value.toString()
                        val latitude = lat.toDouble()
                        val longitude = lng.toDouble()
                        val loc = LatLng(latitude, longitude)
                        val idMission = missionSnapshot.child("postid").value.toString()
                        googleMap.addMarker(
                            MarkerOptions().position(loc)
                                .title(idMission).icon(
                                    BitmapDescriptorFactory.fromResource(R.drawable.pinroll))

                        )
                
            
            override fun onCancelled(error: DatabaseError) 
                TODO("Not yet implemented")
            
        )
        // Add a marker in Sydney and move the camera
        val paris = LatLng(48.82, 2.28)

        mMap.addMarker(MarkerOptions().position(paris).title("Bienvenue à Paris").icon(
            BitmapDescriptorFactory.fromResource(R.drawable.pinroll)))
        mMap.moveCamera(CameraUpdateFactory.newLatLng(paris))
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(paris, zoomLevel));

        // OPEN BOTTOMSHEET WHEN CLICKED
        googleMap.setOnMarkerClickListener(GoogleMap.OnMarkerClickListener 
            val bottomSheet = BottomsheetMissionMap()
            bottomSheet.show(requireFragmentManager(), "BottomSheet")
            false
        )

    
    
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_map, container, false)
    

你能帮帮我吗?

【问题讨论】:

这段代码中到底有什么不符合您的预期?告诉我们共享代码有什么问题。你有什么错误吗? 我没有错误。但我不知道如何根据在地图上单击的制造商在底部表的 TextView 中显示不同的文本。每个标记都表示 Firebase 中的不同人员。作为两个不同的片段,我无法将地图的标记链接到底页的 3 TextView。我搜索但找不到解决方案。 好的,我马上给你写答案。 【参考方案1】:

正如我在您的屏幕截图中看到的,您的标记标题实际上是您正在显示的对象的键。由于您已经拥有密钥,因此在标记上单击 add the title to a Bundle object,因此可以在第二个活动中使用它。

在第二个活动中,获取标题的字符串表示形式,并将其用于精确指向存储在 Bundle 中的键的引用中。进行新的数据库调用并获取相应的数据,以便将其显示在您的视图中。就是这样!

【讨论】:

【参考方案2】:

请检查注释为/* ==== UPDATED CODE ==== */的行

override fun onMapReady(googleMap: GoogleMap?) 
        mMap = googleMap!!
        // GOES UP TO 21
        val zoomLevel = 14.0f
        // MARKER FROM DATABASE
        dbref = FirebaseDatabase.getInstance().getReference("Mission")
        dbref.addValueEventListener(object : ValueEventListener 
            override fun onDataChange(snapshot: DataSnapshot) 
                if (snapshot.exists()) 
                    for (missionSnapshot in snapshot.children) 
                        val lat: String = missionSnapshot.child("latitude").value.toString()
                        val lng: String = missionSnapshot.child("longitude").value.toString()
                        val latitude = lat.toDouble()
                        val longitude = lng.toDouble()
                        val loc = LatLng(latitude, longitude)
                        val idMission = missionSnapshot.child("postid").value.toString()
                        
                        /* ==== UPDATED CODE ==== */
                        val mMarker = googleMap.addMarker(
                            MarkerOptions().position(loc)
                                .title(idMission).icon(
                                    BitmapDescriptorFactory.fromResource(R.drawable.pinroll)
                                )
                        )

                        /* ==== UPDATED CODE ==== */
                        mMarker?.tag = idMission as String? // or any other desired id 
                    
                
            

            override fun onCancelled(error: DatabaseError) 
                TODO("Not yet implemented")
            
        )
        // Add a marker in Sydney and move the camera
        val paris = LatLng(48.82, 2.28)

        mMap.addMarker(
            MarkerOptions().position(paris).title("Bienvenue à Paris").icon(
                BitmapDescriptorFactory.fromResource(R.drawable.pinroll)
            )
        )
        mMap.moveCamera(CameraUpdateFactory.newLatLng(paris))
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(paris, zoomLevel));

        // OPEN BOTTOMSHEET WHEN CLICKED
        googleMap.setOnMarkerClickListener(GoogleMap.OnMarkerClickListener 

            /* ==== UPDATED CODE ==== */
            val id = it.tag as String?
            if (!id.isNullOrEmpty() && id == /* COMPARE WITH YOUR ID */) 
                // if true, fetch data here for bottom sheet
             else 
                // do something else here
             
            
            false
        )

    

【讨论】:

以上是关于Kotlin 和 Firebase :根据点击的地图标记在底部工作表中显示不同的数据的主要内容,如果未能解决你的问题,请参考以下文章

如何从firebase Android kotlin获取基于userId的数据?

从 Firebase 实时数据库 Kotlin 中检索有序数据

如何根据 android studio 中的 listview 项目点击更改活动图像和文本? java 或 kotlin

Kotlin 和 Firebase 读写数据

使用 Kotlin 和 Firebase 通过 onAuthStateChanged 回调触发 sendEmailVerification

Android 中的 Firebase 通知 (Kotlin)