提问者:小点点

Kotlin:如何使用ViewModel/Interface将数据从fragment中的RecycerView传递到另一个fragment?


我在Kotlin中找不到使用viewmodel或接口将数据从RecycerView适配器传递到片段的示例。

我曾尝试只使用一个bundle,但我在接收片段中接收到一个空bundle。

这是我的recyclerview适配器

class QnAMyProfileEditRecyclerViewAdapter(private val context: Context) : RecyclerView.Adapter<QnAMyProfileEditRecyclerViewAdapter.Holder>() {


    private var currentUserQnADataMyProfileEdit = emptyList<QnAData>()

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {

        val view: View = if (viewType == R.layout.rv_item_qn_a_my_profile) {

            LayoutInflater.from(parent.context)
                .inflate(R.layout.rv_item_qn_a_my_profile, parent, false)

        } else {

            LayoutInflater.from(parent.context)
                .inflate(R.layout.rv_footer_new_qna_my_profile, parent, false)

        }
        return Holder(view)
    }

    override fun getItemCount(): Int {
        return currentUserQnADataMyProfileEdit.size + 1
    }

    //implement Floating Action Button at the bottom of the recyclerview
    override fun getItemViewType(position: Int): Int {

        return if (position == currentUserQnADataMyProfileEdit.size) {
            R.layout.rv_footer_new_qna_my_profile
        } else {
            R.layout.rv_item_qn_a_my_profile
        }
    }

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

        if (position == currentUserQnADataMyProfileEdit.size) {
            holder.viewHolderNewQnA?.setOnClickListener {
                Toast.makeText(context, "New item intent", Toast.LENGTH_SHORT).show()
            }
        } else {
            //Normal bind for RecyclerView
            holder.bindData(currentUserQnADataMyProfileEdit[position])
            holder.viewHolderCRUDQnAMyProfile?.setOnClickListener {


                //Give QnACrud current QnAData --- send bundle
                val bundle = Bundle()
                bundle.putString(
                    "currentQnAQuestion",
                    currentUserQnADataMyProfileEdit[position].question
                )
                bundle.putString(
                    "currentQnAAnswer",
                    currentUserQnADataMyProfileEdit[position].answer
                )
                QnAMyProfileEditCRUDFragment().arguments = bundle
                val activity: AppCompatActivity = context as AppCompatActivity
                activity.supportFragmentManager.beginTransaction()
                    .add(R.id.cl_my_profile_edit, QnAMyProfileEditCRUDFragment())
                    .addToBackStack(null).commit()




            }
        }
    }


    fun setData(updateList: List<QnAData>) {
        this.currentUserQnADataMyProfileEdit = updateList
        notifyDataSetChanged()
    }

    inner class Holder(itemView: View) : RecyclerView.ViewHolder(itemView) {




        val viewHolderQuestion =
            itemView.findViewById(R.id.txt_question_qna_my_profile_edit) as TextView?
        val viewHolderAnswer =
            itemView.findViewById(R.id.txt_answer_qna_my_profile_edit) as TextView?

        val viewHolderNewQnA =
            itemView.findViewById(R.id.fab_new_qna_my_profile_edit) as FloatingActionButton?

        val viewHolderCRUDQnAMyProfile =
            itemView.findViewById(R.id.fab_crud_qna_my_profile_edit) as FloatingActionButton?


        //Bind data with inflaters
        fun bindData(currentUserInList: QnAData) {

            viewHolderQuestion?.text = currentUserInList.question
            viewHolderAnswer?.text = currentUserInList.answer
        }

    }
}

下面是我的片段,它是接收数据(bundle)的支持:

class QnAMyProfileEditCRUDFragment : Fragment() {

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

        //Get bundle data and set Edit Text values


        val bundle:Bundle? = arguments //Bundle == null!!!!
        val qnaQuestionData: String? = bundle?.getString("currentQnAQuestion")
        val qnaAnswerData: String? = bundle?.getString("currentQnAAnswer")
        et_qna_question.setText(qnaQuestionData)
        et_qna_answer.setText(qnaAnswerData)


    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {



        return inflater.inflate(R.layout.fragment_qn_a_my_profile_edit_c_r_u_d, container, false)
    }

    override fun onAttach(context: Context) {
        super.onAttach(context)


    }

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

        //Pop fragment if grey area(outside the box) is tapped
        imv_overlay.setOnClickListener {
            fragmentManager?.popBackStack()
        }
    }

}

QnAData是一个简单的数据类,具有Question:String和Answer:String


共2个答案

匿名用户

尝试在您的片段中创建一个构造函数,然后创建beginTransaction

val fragment = QnAMyProfileEditCRUDFragment.newInstance( 
currentUserQnADataMyProfileEdit[position].question, 
currentUserQnADataMyProfileEdit[position].answer)

activity.supportFragmentManager.beginTransaction()
                    .add(R.id.cl_my_profile_edit,fragment)
                    .addToBackStack(null).commit()

在QnAMyProfileEditCRUDFragment中,您可以只使用构造函数中的值

匿名用户

首先,要对代码进行一些重构:

  1. 内部类可能导致内存泄漏,因此请将查看器更改为:
  2. 将单击侦听器带入查看器

查看器

class MyViewHolder(...) : RecyclerView.ViewHolder(...) {

    fun bind(model: Model) {
        ...

        itemView.setOnClickListener {
            callback?.onSomeEventHappened(model)
            //you can also pass lambda here instead of using an interface for callback
        }

    }

}
class Adapter : RecyclerView.Adapter<T>() {

    interface callback {
        fun onSomeEventHappened()
    }


    private var callback: callback? = null

    
    fun setListener(listener: Callback) {
        callback = listener
    }

}
val SomeFragment = SomeFragment().apply {
    SomeFragment.arguments = ... //A bundle for example
}