简体   繁体   中英

Android Kotlin RecyclerView in Fragment is not working

I'm very new in Kotlin and Android programming. I tried to create a Fragment which populates a Recycler view, but somehow I get the following error: E/RecyclerView: No adapter attached; skipping layout E/RecyclerView: No adapter attached; skipping layout I don't really understand why I get this, since I binded everything. If somebody can explain what I'm doing wrong I would really appreciate it. My code is the following:

My class:

data class Movie(val id:Int, val posterPath:String, val vote:Double, val language:String,val releaseDate:String, val title:String) {}

My fragment:

class MovelistScreen : Fragment(R.layout.fragment_movelist_screen) {

    @ExperimentalStdlibApi
    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {

// View created, can be accessed
//        val args = arguments ?: throw IllegalArgumentException("Use new instance method")
//        val argValue = args.getString(ARG_NAME)

        val binding = FragmentMovelistScreenBinding.inflate(layoutInflater)
        val lst : List<Movie> = buildList {
            add(Movie(id=1,posterPath="/asdasd",vote=7.3,language="Eng",releaseDate="2017",title="Test1"))
            add(Movie(id=2,posterPath="/asdasd",vote=6.3,language="Hun",releaseDate="2013",title="Test2"))
        }

        val listAdapter = MovieListAdapter()
        binding.itemList.adapter=listAdapter
        listAdapter.submitList(lst)
    }
    companion object {
        private const val ARG_NAME = "test_argument"
        fun newInstance(testArg: String): DetailpageFragment = DetailpageFragment().apply {
            arguments = Bundle().apply { putString(ARG_NAME, testArg) }
        }
    }
}

My adapter

class MovieListAdapter : ListAdapter<Movie, MovieViewHolder>(diffUtil) {
    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MovieViewHolder {
        val layoutInflater: LayoutInflater = LayoutInflater.from(parent.context)
        return MovieViewHolder(MovieItemBinding.inflate(layoutInflater,parent,false))
    }

    override fun onBindViewHolder(holder: MovieViewHolder, position: Int) {
        val item:Movie=getItem(position)
        val binding:MovieItemBinding = holder.binding

        binding.movieTitle.text=item.title
        binding.releaseYear.text=item.releaseDate
        binding.language.text=item.language
        binding.ratingtext.text=item.vote.toString()
        binding.movieImage.load("https://i.postimg.cc/VLbN4hkz/the-hobbit-the-desolation-of-smaug.jpg")
    }
}


private val diffUtil : DiffUtil.ItemCallback<Movie> = object : DiffUtil.ItemCallback<Movie>() {
    override fun areItemsTheSame(oldItem: Movie, newItem: Movie): Boolean = oldItem.id == newItem.id
    override fun areContentsTheSame(oldItem: Movie, newItem: Movie): Boolean = oldItem == newItem
}

class MovieViewHolder(val binding: MovieItemBinding):RecyclerView.ViewHolder(binding.root)

fragment_movelist_screen.xml

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

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/item_list"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layoutManager="androidx.recyclerview.widget.LinearLayoutManager"
        android:orientation="vertical"
        android:padding="16dp">
    </androidx.recyclerview.widget.RecyclerView>

</androidx.constraintlayout.widget.ConstraintLayout>

mainactivity.xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <fragment
        android:id="@+id/fragmentmovielist"
        android:name="com.example.ubbassignment2.MovelistScreen"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:layout="@layout/fragment_detailpage" />
</FrameLayout>

You're creating a new view and binding in onViewCreated and setting adapter to it (that view will be garbage collected) you should inflate your view in onCreateView and set the adapter to that recycler view instead of your temporary one.

Fragment:

override fun onCreateView(...): View {
    val binding = FragmentMovelistScreenBinding.inflate(layoutInflater)
    val lst : List<Movie> = buildList {
        add(Movie(id=1,posterPath="/asdasd",vote=7.3,language="Eng",releaseDate="2017",title="Test1"))
        add(Movie(id=2,posterPath="/asdasd",vote=6.3,language="Hun",releaseDate="2013",title="Test2"))
    }

    val listAdapter = MovieListAdapter()
    binding.itemList.adapter=listAdapter
    listAdapter.submitList(lst)
  
    return binding.root
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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