NullPointerException when binding Views in RecyclerView.Adapter

对着背影说爱祢 提交于 2019-12-31 03:04:19

问题


Why do I get a NullPointerException in my ViewHolder's bindItems() method?

I've highlighted the line where I get the NullPointerException. The blogpost_author ID exists, as you can see in the XML, so what's the problem here? How is findViewById<TextView>(R.id.blogpost_author) returning null?

Adapter and ViewHolder code:

class BlogPostAdapter(val blogList: ArrayList<BlogPost>) : RecyclerView.Adapter<BlogPostAdapter.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) : BlogPostAdapter.ViewHolder {
        val v = LayoutInflater.from(parent.context).inflate(R.layout.blog_post_list, parent, false)
        return ViewHolder(v)
    }

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

    override fun onBindViewHolder(holder: BlogPostAdapter.ViewHolder, position: Int) {
        holder.bindItems(blogList[position])
    }

    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
        fun bindItems(blogPost: BlogPost) {
            val blogPostAuthor = itemView.findViewById<TextView>(R.id.blogpost_author) // THIS LINE - NULL POINTER EXCEPTION
            val blogPostTitle = itemView.findViewById<TextView>(R.id.blogpost_title)
            blogPostAuthor.text = blogPost.author
            blogPostTitle.text = blogPost.title
        }
    }
}

Activity code:

class BlogPostListActivity : AppCompatActivity() {

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

        // Get the RecyclerView from XML itself
        val recyclerView = findViewById<RecyclerView>(R.id.recyclerview)

        // Add a layout manager - What does a layout manager do?
        recyclerView.layoutManager = LinearLayoutManager(this, LinearLayout.VERTICAL, false)

        // Create an array list to store blogposts using the the data class blogPost
        val blogPosts = ArrayList<BlogPost>()

        // Add some dummy data to the list
        blogPosts.add(BlogPost(123, "First Blog Post", "John"))
        blogPosts.add(BlogPost(456, "Second Blog Post", "Bob"))
        blogPosts.add(BlogPost(789, "Third Blog Post", "Mary"))

        // Create an adapter
        val adapter = BlogPostAdapter(blogPosts)

        // Add the adapter to the recyclerview
        recyclerView.adapter = adapter
    }
}

Kotlin data class:

data class BlogPost(val id: Int, val title: String, val author: String)

XML for RecyclerView:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.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"
    tools:context="com.topzap.android.kotlinlistapptest.BlogPostListActivity">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/recyclerview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:layout_editor_absoluteX="8dp"
        tools:layout_editor_absoluteY="8dp"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintBottom_toBottomOf="parent"/>
</android.support.constraint.ConstraintLayout>

XML for CardView layout:

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

    <android.support.v7.widget.CardView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

        <TextView
            android:id="@+id/blogpost_author"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="AuthorPlaceHolder"
            android:textAppearance="@style/Base.TextAppearance.AppCompat.Large"
            />

        <TextView
            android:id="@+id/blogpost_title"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:padding="5dp"
            android:text="TitlePlaceHolder"
            android:textAppearance="@style/Base.TextAppearance.AppCompat.Medium"
            />
        </LinearLayout>
    </android.support.v7.widget.CardView>
</LinearLayout>

回答1:


You may be inflating the wrong layout within your RecyclerView.

This line within your onCreateViewHolder method:

val v = LayoutInflater.from(parent.context).inflate(R.layout.blog_post_list, parent, false)

You are inflating the blog_post_list.xml, which I'm assuming is the wrong layout file due to the fact you're also inflating that layout within your BlogPostListActivity here:

setContentView(R.layout.blog_post_list)

So when this line is called:

val blogPostAuthor = itemView.findViewById<TextView>(R.id.blogpost_author)

It is looking for the id 'blogpost_author' within R.layout.blog_post_list and as you can see there is no blogpost_author TextView within that layout so it returns null.

To sort it out, it should be straight forward and just change the layout resource that you're assigning to each ViewHolder within your onCreateViewHolder method with the correct layout for your CardView layout.

Which means the line should read something like:

val v = LayoutInflater.from(parent.context).inflate(R.layout.your_card_layout, parent, false)


来源:https://stackoverflow.com/questions/46525690/nullpointerexception-when-binding-views-in-recyclerview-adapter

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!