android-fragments 如何将数据从适配器传递到片段?

n7taea2i  于 2022-11-14  发布在  Android
关注(0)|答案(2)|浏览(159)

我一直在尝试将数据(用户的电子邮件和电话)从我的适配器到我的片段。从我在网上读到的,我应该使用一个接口,但我仍然不能把数据到我的片段。谁能解释一下我应该如何添加一个接口,以及如何把数据从我的适配器到我的接口,这样我就可以在我的片段中调用它。或者有没有其他方法可以将数据从我的适配器传递到我的片段。下面是我的适配器和片段。
适配器:

package ie.wit.savvytutor.adapters
import android.content.Context
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import ie.wit.savvytutor.R
import ie.wit.savvytutor.activity.MainActivity
import ie.wit.savvytutor.fragments.ViewChatFragment
import ie.wit.savvytutor.models.UserModel

class UserAdapter(private val userList: ArrayList<UserModel>, val context: Context) :
RecyclerView.Adapter<UserAdapter.UserViewHolder>() {

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

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

    val username: TextView = itemView.findViewById(R.id.userNameView)

}

override fun onBindViewHolder(holder: UserViewHolder, position: Int, ) {
    val currentItem = userList[position]


    holder.username.text = currentItem.email
    holder.itemView.setOnClickListener {
        println(currentItem)

        



        val optionsFrag = ViewChatFragment()
        (context as MainActivity).getSupportFragmentManager().beginTransaction()
            .replace(R.id.fragment_container, optionsFrag, "OptionsFragment").addToBackStack(
                null
            )
            .commit()
    }

}

override fun getItemCount(): Int {
    return userList.size

}

}
碎片

package ie.wit.savvytutor.fragments

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup    
import androidx.annotation.Nullable
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.google.firebase.auth.FirebaseAuth
import com.google.firebase.database.*
import ie.wit.savvytutor.R
import ie.wit.savvytutor.adapters.UserAdapter
import ie.wit.savvytutor.models.UserModel

class TutorChatFragment : Fragment() {

private lateinit var userRecyclerView: RecyclerView
private lateinit var userArrayList: ArrayList<UserModel>
private lateinit var dbRef: DatabaseReference
private lateinit var mAuth: FirebaseAuth


override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    dbRef = FirebaseDatabase.getInstance("DATABASE LINK").getReference("Users").ref
    mAuth = FirebaseAuth.getInstance()
}

@Nullable
override fun onCreateView(
    inflater: LayoutInflater,
    @Nullable container: ViewGroup?,
    @Nullable savedInstanceState: Bundle?
): View {
    //inflate the fragment layout
    val root = inflater.inflate(R.layout.tutor_chat_fragment, container, false)
    userRecyclerView = root.findViewById(R.id.userListView)
    userRecyclerView.layoutManager = LinearLayoutManager(context)
    userRecyclerView.setHasFixedSize(true)

    userArrayList = arrayListOf<UserModel>()
    getUser()
    return root
}

private fun getUser() {

    userArrayList.clear()

    dbRef.addValueEventListener(object: ValueEventListener{
        override fun onDataChange(snapshot: DataSnapshot) {
            for (postSnapshot in snapshot.children) {
                val currentUser = postSnapshot.getValue(UserModel::class.java)

                //BUG FIX 1.26.13

                val email = currentUser?.email
                if (email != null) {
                    userArrayList.add(currentUser)
                }

                userRecyclerView.adapter?.notifyDataSetChanged()
                userRecyclerView.adapter = context?.let { UserAdapter(userArrayList, it) }

            }
        }

        override fun onCancelled(error: DatabaseError) {
            TODO("Not yet implemented")
        }

    })

}

}

sulc1iza

sulc1iza1#

如果你想使用一个接口,你只需要定义一个带有函数的接口来接收你的数据,让片段实现它,然后把片段作为该接口的实现传递给适配器:

data class UserData(val email: String, val phone: String)

class UserAdapter(
    private val userList: ArrayList<UserModel>,
    val context: Context,
    val handler: UserAdapter.Callbacks // added this here, so you're passing it in at construction
) : RecyclerView.Adapter<UserAdapter.UserViewHolder>() {

    ...

    private fun doWhatever(email: String, phone: String) {
        // pass the data to the handler (which will probably be your Fragment)
        handler.handleUserData(UserData(email, phone))
    }

    // nested inside the UserAdapter class to keep things tidy
    interface Callbacks {
        fun handleUserData(data: UserData)
    }
}

然后在片段中:

// add the Callbacks interface type
class TutorChatFragment : Fragment(), UserAdapter.Callbacks {
    override fun onCreateView(
        inflater: LayoutInflater,
        @Nullable container: ViewGroup?,
        @Nullable savedInstanceState: Bundle?
    ): View {
        ...
        userRecyclerView.layoutManager = LinearLayoutManager(context)

        // set up the adapter here, passing this fragment as the Callbacks handler
        userRecyclerView.adapter = UserAdapter(userArrayList, context, this)
        ...
    }

    // interface implementation
    override fun handleUserData(data: UserData) {
        // whatever
    }
}

就是这样,你没有硬编码一个对特定Fragment类型的依赖,只是接口,这个fragment实现了它,所以它可以传递自己.
一种更Kotliny的方法是忽略接口,而只传递一个函数
第一个
理想情况下,你应该做我在那里做的事情--在安装过程中创建适配器 * 一次 *,并在它上面有一个允许你更新它的函数。你的代码在每次获得数据时都会创建一个新的适配器。
另一个选择是使用适配器和片段都可以访问的视图模型,但这是接口/回调方法的实现方式

wgmfuz8q

wgmfuz8q2#

实际上,有一种非常简单的方法可以将数据从适配器导入到片段或Activity中。它是使用高阶函数调用的。在适配器中在适配器中添加高阶函数。

class UserAdapter(private val userList: ArrayList<UserModel>, val context: Context) :
RecyclerView.Adapter<UserAdapter.UserViewHolder>() {
//your rest of the adapter's code

private var onItemClickListener:((UserModel)->Unit)? = null
fun setOnItemClickListener(listener: (UserModel)->Unit) {
     onItemClickListener = listener
   }
}

在您的UserViewHolder中

val rootView = itemView.rootView

在您的onBindViewHolder中在rootView上设置单击侦听器

holder.rootView.setOnClickListener {
   onItemClickListener?.let{
          it(currentItem)
    }
}

"在你的碎片中"

//create the instance of UserAdapter
userAdapter.setOnItemClickListener {
  //here you have your UserModel in your fragment, do whatever you want to with it
}

还有,最后一个建议。开始使用ViewBinding,它会让你从大量繁忙的工作中解脱出来。

相关问题