简体   繁体   English

如何在片段中添加 RecyclerView?

[英]How to add RecyclerView in a Fragment?

Currently, I am trying to implement RecyclerView inside of Fragment but I cannot find a way to display it.目前,我正在尝试在Fragment内部实现RecyclerView ,但我找不到显示它的方法。

Here is my MainActivity :这是我的MainActivity

package com.example

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import androidx.fragment.app.Fragment
import com.example.projectdrivemark.R
import com.example.projectdrivemark.databinding.ActivityMainBinding
import com.example.recyclerView.MockDatabase.Companion.createMockData
import com.example.recyclerView.PostAdapter
import com.example.recyclerView.RecyclerViewFragment
import com.example.tempConverter.TempConverterFragment
import com.example.uploaderView.UploaderFragment

class MainActivity : AppCompatActivity(), PostAdapter.OnPostClickListener {
    private lateinit var binding: ActivityMainBinding
    val dummyList = createMockData()
    val adapter = PostAdapter(dummyList, this)

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        title = "First Kotlin App"
        binding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(binding.root)

        val recyclerView = RecyclerViewFragment()
        val tempConverterView = TempConverterFragment()
//        recyclerView.layoutManager = LinearLayoutManager(this)
        val uploaderView = UploaderFragment(this)
        setFragmentView(recyclerView)

        binding.bottomNavBar.setOnNavigationItemSelectedListener {
            when(it.itemId){
                R.id.listView ->  setFragmentView(recyclerView)
                R.id.tempConverterView -> setFragmentView(tempConverterView)
                R.id.videoUploaderView -> setFragmentView(uploaderView)
            }
            true
        }
    }

    private fun setFragmentView(fragment: Fragment){
        supportFragmentManager.beginTransaction().apply {
            replace(R.id.main_fragment_view, fragment)
            //Will return to previous page when tap "Back Button" on the phone
            addToBackStack(null)
            commit()
        }
    }

    override fun onEditPost(position: Int){
        val clickedPost = dummyList[position]
        clickedPost.title = "Updated title"
        clickedPost.body = "Updated body"
        adapter.notifyItemChanged(position)
    }

    override fun onDeletePost(position: Int) {
        dummyList.removeAt(position)
        adapter.notifyItemRemoved(position)
    }

    fun celsiusFunction(view: View) {
        val tempConverter = TempConverterFragment()
        tempConverter.celsiusFunction(view)
    }

    fun farenheitFunction(view: View){
       val fahrenheitConverter = TempConverterFragment()
        fahrenheitConverter.farenheitFunction(view)
    }
}

Here is my RecyclerFragment :这是我的RecyclerFragment

package com.example.recyclerView

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.MainActivity
import com.example.projectdrivemark.R

class RecyclerViewFragment: Fragment() {
    var adapter: RecyclerView.Adapter<PostAdapter.PostViewHolder>? = null
    var layoutManager: RecyclerView.LayoutManager? = null

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        super.onCreate(savedInstanceState)
        val binding = inflater.inflate(R.layout.fragment_list, container, false)
        return binding
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        view.apply{
            layoutManager = LinearLayoutManager(activity)
            adapter = PostAdapter(dummyData = ArrayList<Post>(), MainActivity())
        }
    }
}

Here is my PostAdapter code:这是我的PostAdapter代码:

package com.example.recyclerView

import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.example.MainActivity
import com.example.projectdrivemark.R

class PostAdapter(val dummyData: ArrayList<Post>, val myListener: MainActivity) : RecyclerView.Adapter<PostAdapter.PostViewHolder>() {

    inner class PostViewHolder(postView: View) : RecyclerView.ViewHolder(postView), View.OnClickListener{
        val iconImage: ImageView = postView.findViewById(R.id.icon_image_view)
        val title: TextView = postView.findViewById(R.id.title)
        val body: TextView = postView.findViewById(R.id.body)
        val deleteIcon: ImageView = postView.findViewById(R.id.delete_post_image)
        val editIcon: ImageView = postView.findViewById(R.id.edit_post_image)

        init {
            deleteIcon.setOnClickListener(this)
            editIcon.setOnClickListener(this)
        }

        override fun onClick(v: View?){
            val position = adapterPosition
            if(v?.id == editIcon.id){
                myListener.onEditPost(position)
            }else{
                myListener.onDeletePost(position)
            }
        }
    }

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

    override fun onBindViewHolder(holder: PostViewHolder, position: Int) {
        val currentPost = dummyData[position]
        holder.iconImage.setImageResource(currentPost.image)
        holder.title.text = currentPost.title
        holder.body.text = currentPost.body
    }

    override fun getItemCount(): Int {
        return dummyData.size
    }

    interface OnPostClickListener{

        fun onEditPost(position: Int)
        fun onDeletePost(position: Int)
    }
}

If anyone saw something I miss, please do tell me because I am stuck at how to display the RecyclerView .如果有人看到我想念的东西,请告诉我,因为我被困在如何显示RecyclerView上。 Any help would be appreciate.任何帮助将不胜感激。

Edit:编辑:

Here is my MockDatabase :这是我的MockDatabase

package com.example.recyclerView

import com.example.projectdrivemark.R

class MockDatabase {
    companion object{
        fun createMockData(): ArrayList<Post>{
            val list = ArrayList<Post>()
            for(i in 0 until 20){
                val imageToSelect = when (i % 3){
                    0 -> R.drawable.ic_baseline_account_balance
                    1 -> R.drawable.ic_baseline_account_circle
                    2 ->R.drawable.ic_baseline_ac_unit
                    else -> R.drawable.ic_baseline_access_alarms
                }
                list.add(
                        Post(
                            imageToSelect,
                            title = "Title post of $i",
                            body = "Title post of $i"
                        )
                )
            }
            return list
        }
    }
}

Here is my Layout_list xml file:这是我的Layout_list xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/recycleViewMain"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="10dp"
        tools:listitem="@layout/recycler_view_item" />
</androidx.constraintlayout.widget.ConstraintLayout>

It's simple you are passing empty dummyData try using createMockData() instead.您传递空的dummyData尝试使用createMockData()很简单。 Also as a rule of thumb in Android, never ever instatiate an Activity yourself, if you need the reference from within a fragment you can use getActivity() method.同样作为 Android中的经验法则,永远不要自己实例化 Activity,如果您需要片段中的引用,您可以使用getActivity()方法。 So this:所以这:

adapter = PostAdapter(dummyData = ArrayList<Post>(), MainActivity())

Should be:应该:

adapter = PostAdapter(dummyData = createMockData(), getActivity() as MainActivity)

You need to cast view to RecyclerView to access RecyclerView properties inside apply, also you cannot create instances of Activity by yourself, MainActivity() is wrong and won't work, instead use requireActivity() which will provide context of Activity to which Fragment is attached to您需要将view投射到RecyclerView以访问应用内的RecyclerView属性,您也不能自己创建Activity实例, MainActivity()是错误的并且不起作用,而是使用requireActivity()它将提供Fragment所在的Activity的上下文附在

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    view.findViewbyId<RecyclerView>(R.id.recycleViewMain).apply{
        layoutManager = LinearLayoutManager(requireActivity())
        adapter = PostAdapter(dummyData = ArrayList<Post>(), requireActivity() as OnPostClickListener)
    }
}

Also, as @Necronet mentioned, add some mock data to see if it is actually rendering.此外,正如@Necronet 所提到的,添加一些模拟数据以查看它是否实际呈现。

UPDATE更新

Instead of passing MainActivity to Adapter , pass OnPostClickListener不要将MainActivity传递给Adapter ,而是传递OnPostClickListener

adapter = PostAdapter(dummyData = ArrayList<Post>(), requireActivity() as OnPostClickListener)

Adapter适配器

class PostAdapter(val dummyData: ArrayList<Post>, val myListener: OnPostClickListener) : RecyclerView.Adapter<PostAdapter.PostViewHolder>(){
   // you can use myListener to call methods
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM