android 正在从使用活动迁移到片段,正在获取E/RecyclerView:未连接适配器;跳过之前在MainActivity onCreate中工作的布局

dtcbnfnu  于 2022-12-31  发布在  Android
关注(0)|答案(1)|浏览(85)

我正在Kotlin中构建一个简单的电影应用程序(练习面试的现场编码),从这个教程:Build a Movie App using Retrofit and MVVM Architecture with Kotlin。一切都发生在主活动onCreate中,我想移动功能以使用片段。我目前收到错误"E/RecyclerView:未连接适配器;正在跳过布局""。
我已经看过许多类似的职位没有成功。这里是我的代码下面。所有的日志调用正在发生,除非指出。我会更新问题,如果需要更多的信息。
适配器:

package com.example.interviewpracticemvvm.adapter

import android.content.ContentValues.TAG
import android.util.Log
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.example.interviewpracticemvvm.databinding.MovieLayoutBinding
import com.example.interviewpracticemvvm.model.Result

class MovieAdapter : RecyclerView.Adapter<MovieAdapter.ViewHolder>() {
    private var movieList = ArrayList<Result>()

    fun setMovieList(movieList: List<Result>) {
        this.movieList = movieList as ArrayList<Result>
        notifyDataSetChanged()
        Log.d(TAG, "setMovieList called in adapter")
    }

    class ViewHolder(val binding: MovieLayoutBinding) : RecyclerView.ViewHolder(binding.root) {}

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
        return ViewHolder(
            MovieLayoutBinding.inflate(
                LayoutInflater.from(
                    parent.context
                )
            )
        )
        Log.d(TAG, "onCreateViewHolder called") //Not being called

    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
        Glide.with(holder.itemView)
            .load("https://image.tmdb.org/t/p/w500" + movieList[position].poster_path)
            .into(holder.binding.movieImage)
        holder.binding.movieName.text = movieList[position].title
        Log.d(TAG, "onBindViewHolder called") // Not being called

    }

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

片段:

package com.example.interviewpracticemvvm

import android.content.ContentValues.TAG
import android.os.Bundle
import android.util.Log
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.GridLayoutManager
import com.example.interviewpracticemvvm.adapter.MovieAdapter
import com.example.interviewpracticemvvm.databinding.FragmentMovieListBinding
import com.example.interviewpracticemvvm.viewmodel.MovieViewModel

/**
 * A simple [Fragment] subclass.
 * Use the [MovieListFragment.newInstance] factory method to
 * create an instance of this fragment.
 */
class MovieListFragment : Fragment() {
    private lateinit var binding: FragmentMovieListBinding
    private lateinit var viewModel: MovieViewModel
    private lateinit var movieAdapter: MovieAdapter

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        // Inflate the layout for this fragment
        Log.d(TAG,"onCreateView: called")

        binding = DataBindingUtil.inflate(
            inflater, R.layout.fragment_movie_list, container, false
        )
        return inflater.inflate(R.layout.fragment_movie_list, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        Log.d(TAG,"attaching Adapter")
        prepareRecyclerView()
        Log.d(TAG,"prepareRecyclerView called")

        viewModel = ViewModelProvider(this)[MovieViewModel::class.java]
        viewModel.getPopularMovies()
        Log.d(TAG,"getPopularMovies called")

        viewModel.observeMovieLiveData().observe(viewLifecycleOwner, Observer { movieList ->
            movieAdapter.setMovieList(movieList)
            Log.d(TAG,"movieAdapter.setMovieList(movieList) called")

        })
    }

    private fun prepareRecyclerView() {
        movieAdapter = MovieAdapter()
        binding.rvMovies.apply {
            layoutManager = GridLayoutManager(activity, 2) //Tried "context"; appCompatActivity used in MainActivity wouldn't work

            adapter = movieAdapter
        }
        Log.d(TAG,"adapter attached")

    }
}

视图模型:

package com.example.interviewpracticemvvm.viewmodel

import android.util.Log
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.example.interviewpracticemvvm.RetrofitInstance
import com.example.interviewpracticemvvm.model.Movies
import com.example.interviewpracticemvvm.model.Result
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Response

class MovieViewModel : ViewModel() {
    private var movieLiveData = MutableLiveData<List<Result>>()
    fun getPopularMovies() {
        RetrofitInstance.api.getPopularMovies("69d66957eebff9666ea46bd464773cf0")
            .enqueue(object : Callback<Movies> {
                override fun onResponse(call: Call<Movies>, response: Response<Movies>) {
                    if (response.body() != null) {
                        movieLiveData.value = response.body()!!.results
                    }
                }

                override fun onFailure(call: Call<Movies>, t: Throwable) {
                    Log.d("TAG", t.message.toString())
                }
            })
    }

    fun observeMovieLiveData() : LiveData<List<Result>> {
        return movieLiveData
    }
}

片段XML:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto">

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MovieListFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_movies"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        tools:listitem="@layout/movie_layout"/>

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

我在使用数据绑定和safeargs时遇到了一系列的错误。我还没有找到一个帖子指出一个明显的问题。这个错误看起来不够具体,它可能是由项目中的许多事情引起的。

g2ieeal7

g2ieeal71#

只要通过requireContext()而不是activity,并尝试如下,我希望您的问题解决。

private fun prepareRecyclerView() {
    movieAdapter = MovieAdapter()
    binding.rvMovies.apply {
        layoutManager = GridLayoutManager(requireContext(), 2) //Tried "context"; appCompatActivity used in MainActivity wouldn't work
        adapter = movieAdapter
    }
    Log.d(TAG,"adapter attached")

}

相关问题