通过适配器在片段之间传递数据(Kotlin Android)

Posted

技术标签:

【中文标题】通过适配器在片段之间传递数据(Kotlin Android)【英文标题】:Passing data between fragments via adapter (Kotlin Android) 【发布时间】:2021-03-31 19:54:33 【问题描述】:

刚接触编码约 1 个月。抱歉,如果在其他地方回答了这个问题,但花了几个小时查看其他类似的问题,但无法完全正确。 什么:试图将位置点击数据从片段1(MainFragment)传递给片段2(MapsFragment)以加载对应的地图。通过适配器 onclick 方法,因为我想在 MainFragment 上使用 RecyclerView。项目是可构建的,但是当我单击 recyclerview 上的项目时崩溃(无法打开地图)。怎么了???

提前谢谢!!

编辑:已回答 谢谢大家的cmets。能够通过以下方式解决此问题:1)将 mapsfragment 上的 lateinit var 更改为常规 var + nullable,以及 2)将主片段中的 bundle 行更改为

val bundle = bundleOf(EXTRA_USER_MAP to sports[position])
view.findNavController(.navigate(R.id.action_mainFragment_to_mapsFragment, bundle)

哇哦 Kotlin!

主要片段:

const val EXTRA_USER_MAP = "EXTRA_USER_MAP"
private const val TAG = "MainFragment"

class MainFragment : Fragment() 

override fun onCreateView ... // code to inflate my fragment view

override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)
        val sports = generateData()

        myMaps.layoutManager = LinearLayoutManager(activity)

        myMaps.adapter = this.context?.let 
            MapsAdapter(it, sports, object: MapsAdapter.OnClickListener 
                override fun onItemClick(position: Int) 
                    Log.i(TAG, "onItemClick $position")

                    // When user taps on view in recyclerview, navigate to new fragment and opens corresponding map
                    val bundle =  Bundle()
                    bundle.putSerializable(EXTRA_USER_MAP, sports[position])

                    view.findNavController().navigate(R.id.action_mainFragment_to_mapsFragment)
                
            )
        
    
private fun generateData(): List<Sport>  ... // code for my data set

地图片段

private const val TAG = "MapsFragment"
class MapsFragment : Fragment(), OnMapReadyCallback 

    private lateinit var map: GoogleMap
    private lateinit var sport: Sport

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View? 
        return inflater.inflate(R.layout.fragment_maps, container, false)
    

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)

        val bundle = arguments
        if (bundle !=null) 
            sport = bundle.getSerializable(EXTRA_USER_MAP) as Sport
        

        val mapFragment = childFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
        mapFragment?.getMapAsync(this)
    

    // Actions for map
    override fun onMapReady(googleMap: GoogleMap) 
        map = googleMap
        Log.i(TAG, "Map rendered: $sport.title") // Logcat check once working
...

相关适配器代码

class MapsAdapter(
    val context: Context,
    val sports: List<Sport>,
    val onClickListener: OnClickListener)
    : RecyclerView.Adapter<MapsAdapter.ViewHolder>() 

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)

    interface OnClickListener 
        fun onItemClick(position: Int)
    
    override fun onBindViewHolder(holder: ViewHolder, position: Int) 
        val sport = sports[position]
        holder.itemView.setOnClickListener 
            Log.i(TAG, "Tapped on position $position")
            onClickListener.onItemClick(position)

        
...

【问题讨论】:

您不会将您的Bundle 传递给您对navigate 的调用。你是故意的吗? 抱歉,这会是什么样子?这可能是它 阅读此developer.android.com/guide/navigation/navigation-pass-data 您已经进行了 1 个月的编码,并且已经到了这一步。哇 @kaustubhpatange 我按照捆绑说明进行操作,终于搞定了!!谢谢 【参考方案1】:

您可以拥有一个共享视图模型,您可以在其中拥有一个 LiveData 属性,您可以从 MainFragment 更改他的值,并从 MapsFragment 监听他的更改,并做您想做的一切,或者您可以拥有一个监听器,并且可以在用户单击和获得职位。希望对你有帮助

【讨论】:

以上是关于通过适配器在片段之间传递数据(Kotlin Android)的主要内容,如果未能解决你的问题,请参考以下文章

使用导航从工具栏菜单项单击在片段之间传递数据 - Kotlin

片段内的 RecyclerView 的 Kotlin OnItemClickListener

Kotlin:获取点击项目列表视图的值(片段+适配器)

kotlin 在片段中的 RecyclerView 中显示来自 Firebase 数据库的数据

通过导航组件在底部导航片段之间传递数据

如何在kotlin的片段内显示网格视图?