【问题标题】:Blank screen with RecyclerView No adapter attachedRecyclerView 的空白屏幕未连接适配器
【发布时间】:2019-11-12 19:21:00
【问题描述】:

我想在 recyclerview 中解析 JSON。应用程序编译正常,但输出空白/空白屏幕

BlogAdapter.kt

class BlogAdapter(private val blogList: List<Blog>) : RecyclerView.Adapter<BlogAdapter.ViewHolder>() {


    override fun getItemCount()= blogList.size

    private var mContext: Context? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {

        this.mContext=parent.context;

        return ViewHolder(
            LayoutInflater.from(parent.context).inflate(
                R.layout.character_item,
                parent,
                false
            )
        )
    }

    override fun onBindViewHolder(holder: ViewHolder, position: Int) {

        val mBlog = this.blogList[position]

        if (mBlog.img != null) {
            Glide.with(mContext!!)
                .load(mBlog.img)
                .into(holder.ivThumbnail)
        }
        if (mBlog.name != null) {
            holder.tvTitle.text = mBlog.name
            println("Log: Kabe "+mBlog.name)
        }
    }

    class ViewHolder(itemView:View):RecyclerView.ViewHolder(itemView){
        val ivThumbnail:ImageView = itemView.findViewById(R.id.ivThumbnail);
        val tvTitle:TextView = itemView.findViewById(R.id.tvTitle);
    }
}

MainActivity.kt

class MainActivity : AppCompatActivity() {

    var mainViewModel: MainViewModel? = null
    var mBlogAdapter: BlogAdapter? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
        getPopularBlog()
        swipe_refresh.setOnRefreshListener { getPopularBlog() }
    }

    private fun getPopularBlog() {
        swipe_refresh.isRefreshing = false
        mainViewModel!!.allBlog.observe(this, Observer {  charactersList ->
            prepareRecyclerView(charactersList)
        })

    }

    private fun prepareRecyclerView(blogList: List<Blog>) {

        mBlogAdapter = BlogAdapter(blogList)
        if (this.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
            blogRecyclerView.layoutManager = LinearLayoutManager(this)
        } else {
            blogRecyclerView.layoutManager = GridLayoutManager(this, 4)
        }
        blogRecyclerView.itemAnimator = DefaultItemAnimator()
        blogRecyclerView.adapter = mBlogAdapter

    }
}

我的 Json 文件如下所示:

[
  {
    "id": 1,
    "name": "potter",
    "img": "https://images.example.com/potter.jpg"
},
{ …}
]

我根据本教程创建了它:https://itnext.io/kotlin-wrapping-your-head-around-livedata-mutablelivedata-coroutine-networking-and-viewmodel-b552c3a74eec

有什么建议

编辑:

class BlogRepository() {

    private var character = mutableListOf<ABCCharacters>()
    private var mutableLiveData = MutableLiveData<List<ABCCharacters>>()
    val completableJob = Job()
    private val coroutineScope = CoroutineScope(Dispatchers.IO + completableJob)

    private val thisApiCorService by lazy {
        RestApiService.createCorService()
    }

    fun getMutableLiveData():MutableLiveData<List<ABCCharacters>> {
        coroutineScope.launch {
            val request = thisApiCorService.getPopularBlog()
            withContext(Dispatchers.Main) {
                try {

                    val response = request.await()
                    val mBlogWrapper = response;
                    if (/*mBlogWrapper != null &&*/ mBlogWrapper.isNotEmpty()) {
                        character = mBlogWrapper as MutableList<ABCCharacters>
                        mutableLiveData.value = character
                    }

                } catch (e: HttpException) {
                    // Log exception //

                } catch (e: Throwable) {
                    // Log error //)
                }
            }
        }
        return mutableLiveData;
    }
}

【问题讨论】:

  • 检查下面的答案。
  • 我在您发布的代码中看不到任何实际更新您的mainViewModel 中的allBlog 可观察值的内容,因此它可能永远不会发出任何值。

标签: android kotlin android-recyclerview retrofit2 kotlin-coroutines


【解决方案1】:

您在设置RecyclerView 小部件时忘记调用notifyDataSetChanged。在完整的方法调用下方,使其工作。

private fun prepareRecyclerView(blogList: List<Blog>) {

    mBlogAdapter = BlogAdapter(blogList)
    if (this.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
        blogRecyclerView.layoutManager = LinearLayoutManager(this)
    } else {
        blogRecyclerView.layoutManager = GridLayoutManager(this, 4)
    }
    blogRecyclerView.itemAnimator = DefaultItemAnimator()
    blogRecyclerView.adapter = mBlogAdapter
    mBlogAdapter.notifyDataSetChanged()

}

【讨论】:

    【解决方案2】:

    尝试使用以下实现:

    class MainActivity : AppCompatActivity() {
    
        lateinit var mainViewModel: MainViewModel
        var mBlogAdapter: BlogAdapter? = null
        var blogList: List<Blog> = arrayListOf()
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_main)
    
            mainViewModel = ViewModelProvider(this).get(MainViewModel::class.java)
    
            // init your RV here 
            prepareRecyclerView()
            getPopularBlog()
            swipe_refresh.setOnRefreshListener { mainViewModel.getAllBlog() }
        }
    
        private fun getPopularBlog() {
            swipe_refresh.isRefreshing = false
            mainViewModel.getAllBlog().observe(this, Observer {  charactersList ->
               blogList = charactersList
               mBlogAdapter?.notifyDataSetChanged()
            })
        }
    
        private fun prepareRecyclerView() {
    
            mBlogAdapter = BlogAdapter(blogList)
            if (this.resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
                blogRecyclerView.layoutManager = LinearLayoutManager(this)
            } else {
                blogRecyclerView.layoutManager = GridLayoutManager(this, 4)
            }
            blogRecyclerView.itemAnimator = DefaultItemAnimator()
            blogRecyclerView.adapter = mBlogAdapter
    
        }
    }
    

    如下修改您的视图模型:

    class MainViewModel() : ViewModel() {
    
        val characterRepository= BlogRepository()
    
        fun getAllBlog(): MutableLiveData<List<ABCCharacters>> {
            return characterRepository.getMutableLiveData()
        }
    
        override fun onCleared() {
            super.onCleared()
            characterRepository.completableJob.cancel()
        }
    }
    

    【讨论】:

    • 我已经按照你的修改了,但是结果一样
    • 我也附加了存储库类。我使用 List 正确吗?
    猜你喜欢
    • 2018-02-04
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多