【问题标题】:How can I pass data from a recycler view button to fragment? [ kotlin or java]如何将数据从回收器视图按钮传递到片段? [科特林或 java]
【发布时间】:2021-08-29 17:17:29
【问题描述】:

我有一个底部工作表片段,它有两个片段,其中一个片段有一个回收器视图,里面有一个按钮。我需要的是,如果用户单击该按钮,它将滑动到第二个片段并传递文本视图的标题。一切都很好,但如果可能的话,我不知道如何使用我的编码理念。我尝试寻找答案,但没有一个对我有用。

我需要的是

  • 从回收站视图内的按钮打开片段
  • 当另一个片段打开时,我需要显示我从回收站视图传递的标题

任何帮助将不胜感激/请使用 java 或 kotlin

我的回收站视图适配器

    class tvTitleAdapter (val context: Context,val TITLE_LIST : ArrayList<TvTitlesViewModel>)
    :  RecyclerView.Adapter<tvTitleAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.tv_titles_design, parent, false)
        return ViewHolder(view)
    }

    override fun getItemCount(): Int {
        return TITLE_LIST.size
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        val tvShow: TvTitlesViewModel = TITLE_LIST[position]
        holder.titleShow.text = tvShow.title
        holder.description.text = tvShow.description
        holder.showImage.setImageResource(tvShow.title_image)
        holder.tvTitleExpand.setOnClickListener {
            holder.description.visibility = View.VISIBLE
            holder.showImage.visibility = View.VISIBLE
            holder.tvTitleButton.visibility = View.VISIBLE

        }
        holder.tvTitleButton.setOnClickListener {
            when(position){
                0->{
                    // I need to swipe to the other fragment and pass data to it from here if 
                     that's possible 
                }
            }
        }
    }
    class ViewHolder(Itemview : View): RecyclerView.ViewHolder(Itemview){

        val titleShow = itemView.findViewById<TextView>(R.id.tvTitle)
        val description = itemView.findViewById<TextView>(R.id.tvDesription)
        val showImage = itemView.findViewById<ImageView>(R.id.tvImage)
        var tvTitleExpand = itemView.findViewById<CardView>(R.id.tvTitleExpand)
        val tvTitleButton = itemView.findViewById<Button>(R.id.tvTitleButton) // this is a button inside a recycler view
    }
}

我的片段

class TvTitlesFragment : Fragment() {

val TV_TITLE : ArrayList<TvTitlesViewModel> = ArrayList()

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

}

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

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

    val adapter = tvTitleAdapter(context!!,TV_TITLE)
    tvTitles.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
    tvTitles.setHasFixedSize(true)
    tvTitles.adapter = adapter
    tvShowTitles()
}
private fun tvShowTitles(){
    TV_TITLE.add(TvTitlesViewModel(R.drawable.abdelbasset_abdessamad, "برنامج على مائدة الأفطار", "برنامج على مائدة الافطار من تقديم الشيخ علي الطنطاوي رحمه الله, تم بث أول حلقة منه في عام 1960 م واستمر الى عام1992 م"))
    TV_TITLE.add(TvTitlesViewModel(R.drawable.abdelbasset_abdessamad, "برنامج على مائدة الأفطار", "برنامج على مائدة الافطار من تقديم الشيخ علي الطنطاوي رحمه الله, تم بث أول حلقة منه في عام 1960 م واستمر الى عام1992 م"))
    TV_TITLE.add(TvTitlesViewModel(R.drawable.abdelbasset_abdessamad, "برنامج على مائدة الأفطار", "برنامج على مائدة الافطار من تقديم الشيخ علي الطنطاوي رحمه الله, تم بث أول حلقة منه في عام 1960 م واستمر الى عام1992 م"))
    TV_TITLE.add(TvTitlesViewModel(R.drawable.abdelbasset_abdessamad, "برنامج على مائدة الأفطار", "برنامج على مائدة الافطار من تقديم الشيخ علي الطنطاوي رحمه الله, تم بث أول حلقة منه في عام 1960 م واستمر الى عام1992 م"))
    TV_TITLE.add(TvTitlesViewModel(R.drawable.abdelbasset_abdessamad, "برنامج على مائدة الأفطار", "برنامج على مائدة الافطار من تقديم الشيخ علي الطنطاوي رحمه الله, تم بث أول حلقة منه في عام 1960 م واستمر الى عام1992 م"))
    TV_TITLE.add(TvTitlesViewModel(R.drawable.abdelbasset_abdessamad, "برنامج على مائدة الأفطار", "برنامج على مائدة الافطار من تقديم الشيخ علي الطنطاوي رحمه الله, تم بث أول حلقة منه في عام 1960 م واستمر الى عام1992 م"))

}

PC我没有在我的第二个片段中添加任何代码

这是我的回收站视图

如果用户点击按钮,我需要传递标题值并滑动到第二个片段

我的第二个片段图片

【问题讨论】:

标签: java android kotlin android-fragments android-recyclerview


【解决方案1】:

使用kotlin,你可以使用高阶函数来调用回调,而不是像java那样创建接口。

在适配器的构造函数中创建一个高阶函数。然后,当您设置 click 然后您调用并在视图中获取调用的数据。如下:

// You should change the class name to uppercase. Like `TvTitleAdapter`
class tvTitleAdapter (
    val context: Context, 
    val TITLE_LIST : ArrayList<TvTitlesViewModel>,
    private val onClick: ((tvTitleName: String) -> Unit)? = null // Pass the param you want. Here I try to pass String with name tvTitleName.
) : RecyclerView.Adapter<tvTitleAdapter.ViewHolder>() {

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        ...
        holder.tvTitleButton.setOnClickListener {
            when(position){
                0 -> {
                    onClick?.invoke(`your title`) // Pass your title in invoke.
                }
                else -> return@setOnClickListener
            }
        }
    }
}

TvTitleAdapter 的初始化中,您声明了onClick 参数。当你调用invoke()时它会监听回调。

class TvTitlesFragment : Fragment() {
    
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        val adapter = tvTitleAdapter(
            requireContext(), 
            TV_TITLE,
            onClick = { tvTitleName ->
                // This code opens the `Second Fragment` with `tvTitleName` passed by the `newInstance()` function.
                requireActivity().supportFragmentManager
                    .beginTransaction()
                    .replace(R.id.your_fragment_container, SecondFragment.newInstance(tvTitleName))
                    .commit()
            } 
        )
    }
}
class SecondFragment : Fragment() {
    
    ...
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        ...
        // Get data from `TvTitlesFragment`
        val tvTitleName = argument?.getString(KEY_TV_TITLE_NAME)
        
        // Set data to your title
        binding.tvTitle.text = tvTitleName
    }

    companion object {
        private const val KEY_TV_TITLE_NAME = "KEY_TV_TITLE_NAME"

        // Create `SecondFragment` with bundle so you can send data from certain fragment to `SecondFragment`.
        fun newInstance(tvTitleName: String) : SecondFragment = SecondFragment().apply {
            val bundle = bundleOf(KEY_TV_TITLE_NAME to tvTitleName)
            arguments = bundle
        }
    }
}

【讨论】:

  • 是否可以将数据传递给第二个片段? ...我想将标题传递给第二个片段
  • @Abood 在onClick{} 块内,您可以完全将tvTitleName 传递给另一个片段。上面我为大家解决了如何从RecyclerView.Adapter获取数据到Fragment的问题。剩下的就是你如何使用你得到的数据,我不确定。因为我不知道你是在使用 Navigation Component 还是在使用 supportFragmentManager.beginTransaction() 打开另一个 Fragment。
  • 当用户单击按钮时,我需要它打开第二个片段并传递 tvTitleName 值“我不知道如何通过单击按钮打开或滑动到另一个片段”
  • 如果您更新您的问题以显示问题一的答案,这将是一个巨大的帮助
  • @Abood 所以我想问一个问题?您是否在项目中使用导航组件?我需要知道,以便尽我所能为您提供帮助。
猜你喜欢
  • 2021-10-03
  • 1970-01-01
  • 2017-10-13
  • 1970-01-01
  • 2021-03-31
  • 2023-03-23
  • 1970-01-01
  • 2017-06-13
  • 2018-04-09
相关资源
最近更新 更多