Kotlin/Java如何从RecyclerView内置按钮传递数据到Fragment并切换页面
实现方案
步骤1:修改RecyclerView适配器,添加点击回调
给适配器新增按钮点击回调参数,将点击事件和对应的标题数据向外抛出,避免适配器直接操作Fragment:
class tvTitleAdapter( val context: Context, val TITLE_LIST : ArrayList<TvTitlesViewModel>, // 新增点击回调,返回当前项的标题 private val onItemButtonClick: (title: String) -> Unit ) : 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 { // 点击按钮时将当前项的标题传给回调 onItemButtonClick.invoke(tvShow.title) } } 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) } }
步骤2:修改TvTitlesFragment,处理跳转逻辑
初始化适配器时传入回调实现,拿到标题后创建目标Fragment,携带参数并完成页面切换:
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? { return inflater.inflate(R.layout.fragment_tv_titles, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 初始化适配器时传入回调 val adapter = tvTitleAdapter(requireContext(), TV_TITLE) { title -> // 创建目标Fragment实例,传入标题 val targetFragment = TvDetailFragment.newInstance(title) // 执行Fragment切换,R.id.bottom_sheet_container替换为你BottomSheet中装子Fragment的容器ID parentFragmentManager.beginTransaction() .replace(R.id.bottom_sheet_container, targetFragment) .addToBackStack(null) // 加入返回栈,用户点击返回可回到列表页 .commit() } 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 م")) // 其余添加数据逻辑保持不变 } }
步骤3:实现第二个接收数据的Fragment
新建TvDetailFragment,编写参数接收和展示逻辑:
class TvDetailFragment : Fragment() { private val ARG_TITLE = "tv_title" private var currentTitle: String? = null companion object { // 统一实例创建方法,避免参数传递错误 fun newInstance(title: String) = TvDetailFragment().apply { arguments = Bundle().apply { putString(ARG_TITLE, title) } } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 取出传递的标题 arguments?.let { currentTitle = it.getString(ARG_TITLE) } } override fun onCreateView( inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? ): View? { // 替换为你第二个Fragment的布局ID return inflater.inflate(R.layout.fragment_tv_detail, container, false) } override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) // 将标题设置到对应的TextView,替换为你布局里的标题控件ID view.findViewById<TextView>(R.id.detail_title).text = currentTitle } }
如果你两个子Fragment是通过ViewPager/ViewPager2承载,无需replace操作,拿到标题后可以通过
parentFragmentManager.setFragmentResult传值,再将ViewPager切到第二页即可。
内容的提问来源于stack exchange,提问作者Abood
相关产品推荐
相关产品推荐

