如何从 recyclerview 片段传递到另一个 recyclerview 片段

Posted

技术标签:

【中文标题】如何从 recyclerview 片段传递到另一个 recyclerview 片段【英文标题】:How to pass from recyclerview fragment to another recyclerview fragment 【发布时间】:2021-12-26 07:15:27 【问题描述】:

有人可以帮助我了解如何将数据从一个 recyclerview 片段传输到另一个 recyclerview 片段吗?

这是我新创建的CartRecyclerAdapter.kt 用于我的购物车recyclerview 从一个片段。 SubmitItem()的主要思想是在Itemrecyclerview中接受选中的项目。

package com.example.karawapplication
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.bumptech.glide.request.RequestOptions
import com.example.karawapplication.models.ItemPost
import kotlinx.android.synthetic.main.layout_item_cart_list.view.*
import kotlinx.android.synthetic.main.layout_item_list_item.view.*

class CartRecyclerAdapter : RecyclerView.Adapter<RecyclerView.ViewHolder>() 
    private var Items : List<ItemPost> = emptyList()
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder 
        return ItemRecyclerAdapter.ItemViewHolder(
            LayoutInflater.from(parent.context)
                .inflate(R.layout.layout_item_cart_list, parent, false)
        )
    

    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) 
        when(holder)
        
            is ItemRecyclerAdapter.ItemViewHolder ->
            
                holder.bind(Items.get(position))
            
        
    

    override fun getItemCount(): Int 
        return Items.size
    
    fun SubmitItem(Item : ItemPost)
    
        Items.toMutableList().add(Item)
    
    class ItemViewHolder constructor(
        Itemview : View
    ): RecyclerView.ViewHolder(Itemview)
    
        val ItemImage : ImageView = Itemview.Item_image_cart
        val ItemTitle : TextView = Itemview.Item_title_cart
        val ItemCategory: TextView = Itemview.Item_category_cart
        val ItemPrice : TextView = Itemview.Item_price_cart
        fun bind (itempost : ItemPost)
        
            ItemTitle.setText(itempost.Itemtitle)
            ItemCategory.setText(itempost.ItemCategory)
            ItemPrice.setText(itempost.ItemPrice)
            val requestOptions = RequestOptions()
                .placeholder(R.drawable.ic_baseline_brush_24)
                .error(R.drawable.ic_baseline_brush_24)

            Glide.with(itemView.getContext())
                .applyDefaultRequestOptions(requestOptions)
                .load(itempost.image)
                .into(ItemImage)
        

    

这是我在ItemRecyclerAdapter.kt 中使用SubmitItem() 的地方,其中包含我的商店应用程序的项目并从另一个片段显示。 CartAdapter 是我最近创建的用于访问函数SubmitItem() 的购物车适配器。

        ItemButton.setOnClickListener()
        
            Toast.makeText(itemView.context, "$itempost.image, $itempost.Itemtitle, $itempost.ItemPrice", Toast.LENGTH_SHORT).show()
            CartAdapter.SubmitItem(ItemPost(itempost.image,itempost.Itemtitle,itempost.ItemCategory,itempost.ItemPrice))
        

这是我的片段代码

ShopFragment.kt 包含我的物品的回收站视图。

package com.example.karawapplication.fragments

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.Toast
import androidx.recyclerview.widget.LinearLayoutManager
import com.android.volley.Request
import com.android.volley.VolleyError
import com.android.volley.toolbox.JsonArrayRequest
import com.android.volley.toolbox.Volley
import com.example.karawapplication.ItemRecyclerAdapter
import com.example.karawapplication.R
import com.example.karawapplication.models.ItemPost
import kotlinx.android.synthetic.main.fragment_shop.*
import org.json.JSONException
import org.json.JSONObject

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [Shop.newInstance] factory method to
 * create an instance of this fragment.
 */
class Shop : Fragment()
    // TODO: Rename and change types of parameters
    private lateinit var ItemAdapter : ItemRecyclerAdapter
    private var param1: String? = null
    private var param2: String? = null
    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        arguments?.let 
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        

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

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

    
    // CUSTOM FUNCTIONS
    private fun addDataSet()
    
        createDataset 
            list -> ItemAdapter.SubmitList(list)
        
    
    private fun initRecyclerView()
    
        ShopRecycleView.layoutManager = LinearLayoutManager(activity)
        ItemAdapter = ItemRecyclerAdapter()
        ShopRecycleView.adapter = ItemAdapter
        //Toast.makeText(context, "Recycler Trigger", Toast.LENGTH_SHORT).show()
    
     // https://tutorials.eu/json-parsing-and-how-to-use-gson-in-android/
    // Generates the data for the recycleview
    fun createDataset(onSuccess: (List<ItemPost>) -> Unit)
         val url = "http://api.karawcraftventure.com/item"
         // LIST DATA VARIABLE FOR RECYCLEVIEW
         val list = ArrayList<ItemPost>()
         // VOLLEY API REQUEST
         val Queue = Volley.newRequestQueue(activity)
         val jsonObject = JsonArrayRequest(
             Request.Method.GET,url,null,
             response ->
                 try
                 
                     for (i in 0 until response.length())
                     
                         val item : JSONObject = response.getJSONObject(i)
                         val API_Image : String = item.getString("product_url_image")
                         val API_ItemName : String = item.getString("product_name")
                         val API_Price : String = item.getString("product_price")
                         val API_Category : String = item.getString("product_category")
                         // Toast Notif if data is extracted or not
                         //Toast.makeText(context, "$API_ItemName - $API_Price - $API_Category", Toast.LENGTH_SHORT).show()
                         list.add(ItemPost(API_Image, API_ItemName, API_Category, API_Price))
                     
                     onSuccess(list)
                 
                 catch (e: JSONException)
                 
                     e.printStackTrace()
                 
             ,
              error: VolleyError? -> Toast.makeText(context, error?.message.toString(), Toast.LENGTH_SHORT).show()

             
         )
         Queue.add(jsonObject)
    

    companion object 
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment Shop.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic

        fun newInstance(param1: String, param2: String) =
            Shop().apply 
                arguments = Bundle().apply 
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                
            
    

另一方面,Cart.kt 片段包含我的购物车。

package com.example.karawapplication.fragments

import android.os.Bundle
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.karawapplication.CartRecyclerAdapter
import com.example.karawapplication.ItemRecyclerAdapter
import com.example.karawapplication.R
import kotlinx.android.synthetic.main.fragment_cart.*
import kotlinx.android.synthetic.main.fragment_shop.*
import kotlinx.android.synthetic.main.fragment_shop.ShopRecycleView

// TODO: Rename parameter arguments, choose names that match
// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
private const val ARG_PARAM1 = "param1"
private const val ARG_PARAM2 = "param2"

/**
 * A simple [Fragment] subclass.
 * Use the [Cart.newInstance] factory method to
 * create an instance of this fragment.
 */
class Cart : Fragment() 
    // TODO: Rename and change types of parameters
    private lateinit var ItemAdapter : CartRecyclerAdapter
    private var param1: String? = null
    private var param2: String? = null

    override fun onCreate(savedInstanceState: Bundle?) 
        super.onCreate(savedInstanceState)
        arguments?.let 
            param1 = it.getString(ARG_PARAM1)
            param2 = it.getString(ARG_PARAM2)
        
    

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) 
        super.onViewCreated(view, savedInstanceState)
        initRecyclerView()
    
    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? 
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_cart, container, false)
    
    private fun initRecyclerView()
    
        Cart_RecyclerView.layoutManager = LinearLayoutManager(activity)
        ItemAdapter = CartRecyclerAdapter()
        Cart_RecyclerView.adapter = ItemAdapter
        //Toast.makeText(context, "Recycler Trigger", Toast.LENGTH_SHORT).show()
    

    companion object 
        /**
         * Use this factory method to create a new instance of
         * this fragment using the provided parameters.
         *
         * @param param1 Parameter 1.
         * @param param2 Parameter 2.
         * @return A new instance of fragment Cart.
         */
        // TODO: Rename and change types and number of parameters
        @JvmStatic
        fun newInstance(param1: String, param2: String) =
            Cart().apply 
                arguments = Bundle().apply 
                    putString(ARG_PARAM1, param1)
                    putString(ARG_PARAM2, param2)
                
            
    

代码没有错误,但在我的购物车 recyclerview 片段中没有显示任何输出。

【问题讨论】:

【参考方案1】:

(这里我将遵循变量和函数的“以小写字母开头”的约定,因为我累了,而且不那么混乱)

您的submitItem 函数只是创建items (items.toMutableList()) 的新副本并添加到该副本。然后当你退出函数时它会立即被丢弃。

所有处理数据的适配器代码(getItemCountonBindViewHolder)都引用了items,因此您需要更新它,并让适配器知道它已更改:

fun submitItem(item: ItemPost) 
    // plus creates a copy, but adds the new item without making the result mutable
    items = items.plus(item)
    // we also need to tell the adapter that the data has changed, so it can
    // update - there are more efficient calls (you'll probably get a lint
    // warning telling you to use one) but this is the simplest
    notifyDataSetChanged()

这只是使您的适配器正确更新-我假设您已正确设置了两个片段之间的通信(通过父活动进行通信,将一个片段的适配器传递给另一个,使用视图模型)。如果需要,请阅读此内容:Communicating with fragments

【讨论】:

我去看看。 似乎我的片段通信设置有问题,尝试了您的解决方案,我的购物车 recyclerview 中仍然没有输出。 如果通信已经建立,请确保您还在Cart 片段中输入代码以将项目/列表提交到您的ItemAdapter。如果还是不行,请附上更新后的代码来更新你的问题

以上是关于如何从 recyclerview 片段传递到另一个 recyclerview 片段的主要内容,如果未能解决你的问题,请参考以下文章

如何将价值从 recyclerview 项目传递到另一个活动

将数据从 RecyclerView.Adapter 传递到片段 onClick

如何将值从一个片段的回收器视图项传递到另一个片段

为啥我不能将数据从 RecyclerView 传递到另一个 RecyclerView - AndroidX

如何将值从一个活动中的片段传递到另一个活动? [复制]

从片段中获取意图值后,我如何在 recyclerview 项目中实现单击