【问题标题】:How to Open a "Details" Fragment onclick of Recyclerview如何在 Recyclerview 的单击上打开“详细信息”片段
【发布时间】:2020-01-20 05:15:10
【问题描述】:

我有这个片段、它的视图模型和它的适配器。它已经可以听到点击,但我所知道的只是显示 toast。我希望它转到另一个片段,该片段将显示其“详细信息”,它将单击的 recyclerview 项目的数据传递给该“详细信息”片段。提示:在片段上,有一个//TODO,我需要它的代码。

这是片段:

class HomeFragment : Fragment(), RecyclerViewClickListener {

    private lateinit var factory: HomeViewModelFactory
    private lateinit var viewModel: HomeViewModel

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.fragment_home, container, false)
    }

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

        val api = DormsAPI()
        val repository = DormRepository(api)

        factory = HomeViewModelFactory(repository)
        viewModel = ViewModelProviders.of(this, factory).get(HomeViewModel::class.java)

        viewModel.getDorms()

        viewModel.dorms.observe(viewLifecycleOwner, Observer { dorms ->
            recyclerViewDorms.also{
                it.layoutManager = LinearLayoutManager(requireContext())
                it.setHasFixedSize(true)
                it.adapter = dormAdapter(dorms, this)
            }
        })
    }
    override fun onRecyclerViewItemClick(view: View, dorms: Dorms) {
        when(view.id){
            R.id.button_reserve -> {
                // TODO: Go to new account if not signed up, etc...
                Toast.makeText(requireContext(), "Reserve button clicked", Toast.LENGTH_LONG).show()
            }
            R.id.layoutBox -> {
                // TODO: Go to Dorm Details
                Toast.makeText(requireContext(), "Go to dorm details", Toast.LENGTH_LONG).show()
            }
        }
    }
}

至于适配器类:

class dormAdapter(
    private val dorms: List<Dorms>,
    private val listener: RecyclerViewClickListener
) : RecyclerView.Adapter<dormAdapter.DormViewHolder>() {

    override fun getItemCount() = dorms.size

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
        DormViewHolder(
            DataBindingUtil.inflate(
                LayoutInflater.from(parent.context),
                R.layout.layout_home,
                parent, false
            )
        )

    override fun onBindViewHolder(holder: DormViewHolder, position: Int) {
        holder.recyclerviewDormBinding.dorm = dorms[position]
        holder.recyclerviewDormBinding.buttonReserve.setOnClickListener {
            listener.onRecyclerViewItemClick(holder.recyclerviewDormBinding.buttonReserve, dorms[position])

        }
        holder.recyclerviewDormBinding.layoutBox.setOnClickListener {
            listener.onRecyclerViewItemClick(holder.recyclerviewDormBinding.layoutBox, dorms[position])
        }
    }

    inner class DormViewHolder(
        val recyclerviewDormBinding: LayoutHomeBinding
    ) : RecyclerView.ViewHolder(recyclerviewDormBinding.root)

}

最后,这是 ViewModel:

class HomeViewModel(private val repository: DormRepository) : ViewModel() {

    private lateinit var job: Job

    private val _dorms = MutableLiveData<List<Dorms>>()
    val dorms: LiveData<List<Dorms>>
        get() = _dorms

    fun getDorms() {
        job = Coroutines.ioThenMain(
            { repository.getDorms() },
            { _dorms.value = it }
        )
    }

    override fun onCleared() {
        super.onCleared()
        if(::job.isInitialized) job.cancel()
    }
}

编辑:如果需要,我也有这个界面:

interface RecyclerViewClickListener {
    fun onRecyclerViewItemClick(view: View, dorms: Dorms)
}

【问题讨论】:

    标签: android android-fragments kotlin android-recyclerview


    【解决方案1】:

    由于我们是从一个活动中添加HomeFragment,我们将尝试做的是创建一个接口来在活动和片段之间进行通信。

    1.创建界面

    class HomeFragment : Fragment(), RecyclerViewClickListener {
        ...
        ...
    
        private var callback : Callback? = null
    
        ...
        ...
    
        override fun onAttach(context: Context) {
            ...
            // Callback instance is initialized 
            if(context is Callback) callback = context
            else throw RuntimeException("$context must implement Callback")
        }
    
        ...
        ...
    
        override fun onDetach() {
            callback = null
        }
    
        ...
        ...
    
        override fun onRecyclerViewItemClick(view: View, dorms: Dorms) {
            when(view.id){
                R.id.button_reserve -> {
                    // TODO: Go to new account if not signed up, etc...
                    Toast.makeText(requireContext(), "Reserve button clicked", Toast.LENGTH_LONG).show()
                }
                R.id.layoutBox -> {
                    // Go to Dorm Details
                    callback?.onShowDormDetail(dorm)
                }
            }
        }
    
        ...
        ...
    
        // This interface will act as mode to communication between
        // activity and fragment
        interface Callback {
            fun onShowDormDetail(dorm: Dorm)
        }
    }
    

    2。在调用活动上实现Callback

    class HomeActivity : AppCompatActivity(), HomeFragment.Callback {
    
    ...
    ...
    
        override onShowDormDetail(dorm: Dorm) {
            // Add or replace the detail fragment here
        }
    }
    

    【讨论】:

    • 谢谢。但是,我遇到了一个问题,其中在单击 recyclerview 项目时,详细信息片段与 homefragment 重叠。我已经为此提出了另一个question
    猜你喜欢
    • 1970-01-01
    • 2019-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多