繁体   English   中英

java.lang.IllegalStateException: view...findViewById(R.id.dog_image) 不能是 null

[英]java.lang.IllegalStateException: view!!.findViewById(R.id.dog_image) must not be null

我正在使用 Android Studio 和 Kotlin。 我正在尝试创建一个 RecyclerView 和一个适配器。

尝试使用 RecyclerView 时出现以下错误。 它说 dog_image 是 null 但我不明白为什么。

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.dogglers, PID: 26356
    java.lang.IllegalStateException: view!!.findViewById(R.id.dog_image) must not be null
        at com.example.dogglers.adapter.DogCardAdapter$DogCardViewHolder.<init>(DogCardAdapter.kt:50)
        at com.example.dogglers.adapter.DogCardAdapter.onCreateViewHolder(DogCardAdapter.kt:90)
        at com.example.dogglers.adapter.DogCardAdapter.onCreateViewHolder(DogCardAdapter.kt:34)
        at androidx.recyclerview.widget.RecyclerView$Adapter.createViewHolder(RecyclerView.java:7078)
        at androidx.recyclerview.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline(RecyclerView.java:6235)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6118)
        at androidx.recyclerview.widget.RecyclerView$Recycler.getViewForPosition(RecyclerView.java:6114)
        at androidx.recyclerview.widget.LinearLayoutManager$LayoutState.next(LinearLayoutManager.java:2303)
        at androidx.recyclerview.widget.LinearLayoutManager.layoutChunk(LinearLayoutManager.java:1627)
        at androidx.recyclerview.widget.LinearLayoutManager.fill(LinearLayoutManager.java:1587)
        at androidx.recyclerview.widget.LinearLayoutManager.onLayoutChildren(LinearLayoutManager.java:665)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayoutStep2(RecyclerView.java:4134)
        at androidx.recyclerview.widget.RecyclerView.dispatchLayout(RecyclerView.java:3851)
        at androidx.recyclerview.widget.RecyclerView.onLayout(RecyclerView.java:4404)
        at android.view.View.layout(View.java:20871)
        at android.view.ViewGroup.layout(ViewGroup.java:6268)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:20871)
        at android.view.ViewGroup.layout(ViewGroup.java:6268)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:20871)
        at android.view.ViewGroup.layout(ViewGroup.java:6268)
        at androidx.appcompat.widget.ActionBarOverlayLayout.onLayout(ActionBarOverlayLayout.java:530)
        at android.view.View.layout(View.java:20871)
        at android.view.ViewGroup.layout(ViewGroup.java:6268)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at android.view.View.layout(View.java:20871)
        at android.view.ViewGroup.layout(ViewGroup.java:6268)
        at android.widget.LinearLayout.setChildFrame(LinearLayout.java:1812)
        at android.widget.LinearLayout.layoutVertical(LinearLayout.java:1656)
        at android.widget.LinearLayout.onLayout(LinearLayout.java:1565)
        at android.view.View.layout(View.java:20871)
        at android.view.ViewGroup.layout(ViewGroup.java:6268)
        at android.widget.FrameLayout.layoutChildren(FrameLayout.java:323)
        at android.widget.FrameLayout.onLayout(FrameLayout.java:261)
        at com.android.internal.policy.DecorView.onLayout(DecorView.java:758)
        at android.view.View.layout(View.java:20871)
        at android.view.ViewGroup.layout(ViewGroup.java:6268)
        at android.view.ViewRootImpl.performLayout(ViewRootImpl.java:2972)
        at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2487)
        at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1580)
        at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7634)
        at android.view.Choreographer$CallbackRecord.run(Choreographer.java:958)
        at android.view.Choreographer.doCallbacks(Choreographer.java:770)
        at android.view.Choreographer.doFrame(Choreographer.java:702)
        at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:944)
        at android.os.Handler.handleCallback(Handler.java:873)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:201)
        at android.app.ActivityThread.main(ActivityThread.java:6831)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:927)


错误在这里(适配器):

/*
* Copyright (C) 2021 The Android Open Source Project.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.dogglers.adapter

import android.content.Context
import android.util.Log
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.dogglers.model.Dog
import com.example.dogglers.data.DataSource.dogs as list_dogs
import com.example.dogglers.R

/**
 * Adapter to inflate the appropriate list item layout and populate the view with information
 * from the appropriate data source
 */
class DogCardAdapter(
    private val context: Context?,
    private val layout: Int
): RecyclerView.Adapter<DogCardAdapter.DogCardViewHolder>() {

    // TODO: Initialize the data using the List found in data/DataSource
    private val dogs: List<Dog> = list_dogs


    /**
     * Initialize view elements
     */
    class DogCardViewHolder(view: View?): RecyclerView.ViewHolder(view!!) {
        // TODO: Declare and initialize all of the list item UI components


        val imageView: ImageView = view!!.findViewById(R.id.dog_image)

        val dogNameTextView: TextView = view!!.findViewById(R.id.dog_name)
        val dogAgeTextView: TextView = view!!.findViewById(R.id.dog_age)
        val dogHobbiesTextView: TextView = view!!.findViewById(R.id.dog_hobbies)




    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DogCardViewHolder {
        // TODO: Use a conditional to determine the layout type and set it accordingly.
        //  if the layout variable is Layout.GRID the grid list item should be used. Otherwise the
        //  the vertical/horizontal list item should be used.
        var adapterLayout =LayoutInflater.from(parent.context)
            .inflate(R.layout.activity_grid_list, parent, false)

        when(layout){
            1->{

                adapterLayout =LayoutInflater.from(parent.context)
                    .inflate(R.layout.activity_vertical_list, parent, false)

            }

            2->{
                adapterLayout =LayoutInflater.from(parent.context)
                    .inflate(R.layout.activity_horizontal_list, parent, false)
            }

        }

        // TODO Inflate the layout

        // TODO: Null should not be passed into the view holder. This should be updated to reflect
        //  the inflated layout.

        return DogCardViewHolder(adapterLayout)
    }

    override fun getItemCount(): Int {
        return dogs.size
    }// TODO: return the size of the data set instead of 0

    override fun onBindViewHolder(holder: DogCardViewHolder, position: Int) {
        // TODO: Get the data at the current position
        // TODO: Set the image resource for the current dog
        // TODO: Set the text for the current dog's name
        // TODO: Set the text for the current dog's age
        val resources = context?.resources
        val dog = dogs[position]
        holder.imageView.setImageResource(dog.imageResourceId)
        holder.dogNameTextView.text=dog.name
        holder.dogAgeTextView.text=dog.age

        // TODO: Set the text for the current dog's hobbies by passing the hobbies to the
        //  R.string.dog_hobbies string constant.
        //  Passing an argument to the string resource looks like:
        //  resources?.getString(R.string.dog_hobbies, dog.hobbies)

        holder.dogHobbiesTextView.text=resources?.getString(R.string.dog_hobbies, dog.hobbies)

    }
}


dog_image id 位于以下 XML 档案中。 不知道为什么是null:

文件 grid_list_item

文件vertical_horizontal_list_item

我想知道如何改进这个问题

dog_image 应该存在于每个可以在 onCreateViewHolder 中膨胀的布局下,含义:activity_grid_list activity_vertical_list activity_horizontal_list

如果您将其添加到这些布局中,代码将运行。

但我认为这不是您要寻找的,如果我理解正确,您想将列表作为适配器项进行膨胀,这意味着您应该有另一个适配器来处理这些列表的项,并且该适配器应该使 dog_image 膨胀。

该教程明确指出

onCreateViewHolder()中,您想要扩展grid_list_itemvertical_horizontal_list_item ntal_list_item 布局。

在您的代码中,首先您要膨胀activity_grid_list ,然后用activity_vertical_listactivity_horizontal_list ntal_list 覆盖它。

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): DogCardViewHolder {
        // TODO: Use a conditional to determine the layout type and set it accordingly.
        //  if the layout variable is Layout.GRID the grid list item should be used. Otherwise the
        //  the vertical/horizontal list item should be used.

        when(layout){
            Layout.GRID->{
                adapterLayout = LayoutInflater.from(parent.context)
                    .inflate(R.layout.grid_list_item, parent, false)
            }
            // use this, or "else->"
            Layout.VERTICAL, Layout.HORIZONTAL->{
                adapterLayout = LayoutInflater.from(parent.context)
                    .inflate(R.layout. vertical_horizontal_list_item, parent, false)
            }

        }

        // TODO Inflate the layout

        // TODO: Null should not be passed into the view holder. This should be updated to reflect
        //  the inflated layout.

        return DogCardViewHolder(adapterLayout)
    }

暂无
暂无

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

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