首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >NullPointerException:尝试调用虚拟方法& RecyclerView:没有附加适配器;跳过布局,在从Firestore获取数据时出错

NullPointerException:尝试调用虚拟方法& RecyclerView:没有附加适配器;跳过布局,在从Firestore获取数据时出错
EN

Stack Overflow用户
提问于 2021-05-25 14:11:49
回答 2查看 183关注 0票数 0

我试图从Firestore中获取数据并将其显示在RecyclerView中。但是,我得到了以下错误。我在编码方面没有多少经验,但我尝试在我的项目中添加RecyclerViewfragments

我正在使用Kotlin作为语言。

在过去的三天里,我一直在试图找出问题的症结所在和解决办法,但现在我想我必须寻求像你这样的专家的帮助。

下面是我在Logcat中遇到的错误

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
16273-16273/com.example.quiz E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.example.quiz, PID: 16273
    java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.quiz/com.example.quiz.ui.activities.DashboardActivity}: android.view.InflateException: Binary XML file line #32 in com.example.quiz:layout/activity_dashboard: Binary XML file line #32 in com.example.quiz:layout/activity_dashboard: Error inflating class fragment
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3792)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3968)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8512)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
     Caused by: android.view.InflateException: Binary XML file line #32 in com.example.quiz:layout/activity_dashboard: Binary XML file line #32 in com.example.quiz:layout/activity_dashboard: Error inflating class fragment
     Caused by: android.view.InflateException: Binary XML file line #32 in com.example.quiz:layout/activity_dashboard: Error inflating class fragment
     Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void androidx.recyclerview.widget.RecyclerView.setLayoutManager(androidx.recyclerview.widget.RecyclerView$LayoutManager)' on a null object reference
        at com.example.quiz.ui.fragments.DashboardFragment.onCreateView(DashboardFragment.kt:28)
        at androidx.fragment.app.Fragment.performCreateView(Fragment.java:2963)
        at androidx.fragment.app.FragmentStateManager.createView(FragmentStateManager.java:518)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:282)
        at androidx.fragment.app.FragmentManager.executeOpsTogether(FragmentManager.java:2189)
        at androidx.fragment.app.FragmentManager.removeRedundantOperationsAndExecute(FragmentManager.java:2106)
        at androidx.fragment.app.FragmentManager.execPendingActions(FragmentManager.java:2002)
        at androidx.fragment.app.FragmentManager.dispatchStateChange(FragmentManager.java:3138)
        at androidx.fragment.app.FragmentManager.dispatchViewCreated(FragmentManager.java:3065)
        at androidx.fragment.app.Fragment.performViewCreated(Fragment.java:2988)
        at androidx.fragment.app.FragmentStateManager.ensureInflatedView(FragmentStateManager.java:392)
        at androidx.fragment.app.FragmentStateManager.moveToExpectedState(FragmentStateManager.java:281)
        at androidx.fragment.app.FragmentLayoutInflaterFactory.onCreateView(FragmentLayoutInflaterFactory.java:140)
        at androidx.fragment.app.FragmentController.onCreateView(FragmentController.java:135)
        at androidx.fragment.app.FragmentActivity.dispatchFragmentsOnCreateView(FragmentActivity.java:319)
        at androidx.fragment.app.FragmentActivity.onCreateView(FragmentActivity.java:298)
        at android.view.LayoutInflater.tryCreateView(LayoutInflater.java:1067)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:995)
        at android.view.LayoutInflater.createViewFromTag(LayoutInflater.java:959)
        at android.view.LayoutInflater.rInflate(LayoutInflater.java:1121)
        at android.view.LayoutInflater.rInflateChildren(LayoutInflater.java:1082)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:680)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:532)
        at android.view.LayoutInflater.inflate(LayoutInflater.java:479)
        at androidx.appcompat.app.AppCompatDelegateImpl.setContentView(AppCompatDelegateImpl.java:699)
2021-05-27 07:25:09.097 16273-16273/com.example.quiz E/AndroidRuntime:     at androidx.appcompat.app.AppCompatActivity.setContentView(AppCompatActivity.java:195)
        at com.example.quiz.ui.activities.DashboardActivity.onCreate(DashboardActivity.kt:15)
        at android.app.Activity.performCreate(Activity.java:8198)
        at android.app.Activity.performCreate(Activity.java:8182)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3765)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3968)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2307)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loop(Looper.java:246)
        at android.app.ActivityThread.main(ActivityThread.java:8512)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:602)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1130)
2021-05-27 07:25:09.166 16273-16273/com.example.quiz I/Process: Sending signal. PID: 16273 SIG: 9

Quiz.kt文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.example.quiz.models

import android.os.Parcelable
import kotlinx.android.parcel.Parcelize

@Parcelize
data class Quiz(
    val user_id: String = "",
    var quiz_id: String = "",
    val quiz_name: String = "",
    val num_participants: String = "",
    val num_questions: String = "",
    val duration: String = ""

) : Parcelable

DashboardActivity.kt

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.example.quiz.ui.activities

import android.os.Bundle
import androidx.core.content.ContextCompat
import androidx.navigation.findNavController
import androidx.navigation.ui.AppBarConfiguration
import androidx.navigation.ui.setupActionBarWithNavController
import androidx.navigation.ui.setupWithNavController
import com.google.android.material.bottomnavigation.BottomNavigationView
import com.example.quiz.R

class DashboardActivity : BaseActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_dashboard)
        
        supportActionBar!!.setBackgroundDrawable(
            ContextCompat.getDrawable(
                this@DashboardActivity,
                R.drawable.app_gradient_color_background
            )
        )

        val navView: BottomNavigationView = findViewById(R.id.nav_view)

        val navController = findNavController(R.id.nav_host_fragment)
        val appBarConfiguration = AppBarConfiguration(
            setOf(
                R.id.navigation_quizzes,
                R.id.navigation_dashboard
            )
        )
        setupActionBarWithNavController(navController, appBarConfiguration)

        navView.setupWithNavController(navController)
    }

    override fun onBackPressed() {
        doubleBackToExit()
    }
}

DashboardItemListAdapter.kt

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.example.quiz.ui.adapters

import android.annotation.SuppressLint
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.quiz.R
import com.example.quiz.models.Quiz
import kotlinx.android.synthetic.main.item_list_layout.view.*


open class DashboardItemsListAdapter(
    private val context: Context,
    private var list: ArrayList<Quiz>
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {


    private var onClickListener: OnClickListener? = null

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return MyViewHolder(
            LayoutInflater.from(context).inflate(
                R.layout.item_dashboard_layout,
                parent,
                false
            )
        )
    }


    @SuppressLint("SetTextI18n")
    override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
        val model = list[position]

        if (holder is MyViewHolder) {

            holder.itemView.tv_quiz_name.text = model.quiz_name
            holder.itemView.tv_participants.text = model.num_participants
            holder.itemView.tv_questions.text = model.num_questions
            holder.itemView.tv_duration.text = model.duration

            holder.itemView.setOnClickListener {
                if (onClickListener != null) {
                    onClickListener!!.onClick(position, model)
                }
            }
        }
    }

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


    fun setOnClickListener(onClickListener: OnClickListener) {
        this.onClickListener = onClickListener
    }


    interface OnClickListener {

        fun onClick(position: Int, product: Quiz)
    }


    class MyViewHolder(view: View) : RecyclerView.ViewHolder(view)
}

QuizListAdapter.kt

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.example.quiz.ui.adapters

import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.example.quiz.R
import com.example.quiz.models.Quiz
//import com.example.Quiz.utils.GlideLoader
import kotlinx.android.synthetic.main.item_list_layout.view.*

open class QuizListAdapter(
    private val context: Context,
    private val list: ArrayList<Quiz>,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
        return MyViewHolder(
            LayoutInflater.from(context).inflate(
                R.layout.item_list_layout,
                parent,
                false
            )
        )
    }

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

        val model = list[position]

        if (holder is MyViewHolder) {

            holder.itemView.tv_quiz_name.text = model.quiz_name
            holder.itemView.tv_participants.text = model.num_participants
            holder.itemView.tv_questions.text = model.num_questions
            holder.itemView.tv_duration.text = model.duration

        }

    }

    override fun getItemCount(): Int {

        return list.size
    }

    class MyViewHolder(view: View) : RecyclerView.ViewHolder(view)
}

DashboardFragment.kt

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.example.quiz.ui.fragments

import android.os.Bundle
import android.util.Log
import android.view.*
import androidx.recyclerview.widget.GridLayoutManager
import com.example.quiz.R
import com.example.quiz.firestore.FirestoreClass
import com.example.quiz.models.Quiz
import com.example.quiz.ui.adapters.DashboardItemsListAdapter
import kotlinx.android.synthetic.main.fragment_dashboard.*

class DashboardFragment : BaseFragment() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {

        return inflater.inflate(R.layout.fragment_dashboard, container, false)
    }

    override fun onResume() {
        super.onResume()

        getDashboardItemsList()
    }

    private fun getDashboardItemsList() {
        showProgressDialog("please_wait")

        FirestoreClass().getDashboardItemsList(this@DashboardFragment)
    }

    fun successDashboardItemsList(dashboardItemsList: ArrayList<Quiz>) {

        hideProgressDialog()

        for (i in dashboardItemsList) {
            Log.i("Item Title", i.quiz_name)
        }

        if (dashboardItemsList.size > 0) {

            rv_dashboard_items.visibility = View.VISIBLE
            tv_no_dashboard_items_found.visibility = View.GONE

            rv_dashboard_items.layoutManager = GridLayoutManager(activity, 1)
            rv_dashboard_items.setHasFixedSize(true)

            val adapter = DashboardItemsListAdapter(requireActivity(), dashboardItemsList)
            rv_dashboard_items.adapter = adapter

        } else {
            rv_dashboard_items.visibility = View.GONE
            tv_no_dashboard_items_found.visibility = View.VISIBLE
        }
    }
}

使用上面的代码,我的应用程序在输入用户名和密码后会崩溃,但是当我删除rv_dashboard_items.adapter = adapter时,应用程序至少不会崩溃。但是,它根本不显示来自Firestore的任何数据。

在不使用rv_dashboard_items.adapter = adapter的情况下运行应用程序时会出现以下错误

以下片段中的消息是红色的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
E/DashboardFragment: [DocumentSnapshot{key=quizzes/C8STnkYwp3cYWMxm1Y0xQWERTZq1, metadata=SnapshotMetadata{hasPendingWrites=false, isFromCache=false}, doc=Document{key=quizzes/C8STnkYwp3cYWMxm1Y0xQWERTZq1, version=SnapshotVersion(seconds=1621955183, nanos=678854000), type=FOUND_DOCUMENT, documentState=SYNCED, value=ObjectValue{internalValue=# com.google.firestore.v1.Value@1abc2d14
integer_value: 0
map_value {
  fields {
    key: "quiz_id"
    value {
      integer_value: 0
      string_value: "C8STnkYwp3cYWMxm1Y0xQWERTZq1"
    }
  }
  fields {
    key: "num_questions"
    value {
      integer_value: 0
      string_value: "10"
    }
  }
  fields {
    key: "quiz_name"
    value {
      integer_value: 0
      string_value: "Easy Quiz"
    }
  }
  fields {
    key: "duration"
    value {
      integer_value: 0
      string_value: "10"
    }
  }
  fields {
    key: "num_participants"
    value {
      integer_value: 0
      string_value: "5"
    }
  }
  fields {
    key: "user_id"
    value {
      integer_value: 0
      string_value: "C8STnkYwp3cYWMxm1Y0xQWERTZq1"
    }
  }
}}}}]

还有这条线

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
E/RecyclerView: No adapter attached; skipping layout

QuizFragment.kt

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.example.quiz.ui.fragments

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.LinearLayoutManager
import com.example.quiz.R
import com.example.quiz.firestore.FirestoreClass
import com.example.quiz.models.Quiz
import com.example.quiz.ui.adapters.QuizListAdapter
import kotlinx.android.synthetic.main.fragment_quiz.*

class QuizFragment : BaseFragment() {

    private lateinit var mRootView: View


    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        mRootView = inflater.inflate(R.layout.fragment_quiz, container, false)
        return mRootView
    }

    fun successQuizListFromFireStore(quizList: ArrayList<Quiz>) {

        hideProgressDialog()

        if (quizList.size > 0) {
            rvQuizzesFrag.visibility = View.VISIBLE
            tv_no_products_found.visibility = View.GONE

            rvQuizzesFrag.layoutManager = LinearLayoutManager(activity)
            rvQuizzesFrag.setHasFixedSize(true)
            val adapterQuizzes = QuizListAdapter(requireActivity(), quizList)
            rvQuizzesFrag.adapter = adapterQuizzes

        } else {
            rvQuizzesFrag.visibility = View.GONE
            tv_no_products_found.visibility = View.VISIBLE
        }
    }


    private fun getQuizListFromFireStore() {

        showProgressDialog("Please_wait")
        FirestoreClass().getQuizList(this)
    }

    override fun onResume() {
        super.onResume()
        getQuizListFromFireStore()
    }
}

activity_dashboard.xml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/nav_view"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="0dp"
        android:layout_marginEnd="0dp"
        android:background="@drawable/app_gradient_color_background"
        app:itemIconTint="@color/colorWhite"
        app:itemTextColor="@color/colorWhite"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:menu="@menu/bottom_nav_menu" />

    <fragment
        android:id="@+id/nav_host_fragment"
        android:name="androidx.navigation.fragment.NavHostFragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        app:defaultNavHost="true"
        app:layout_constraintBottom_toTopOf="@id/nav_view"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:navGraph="@navigation/mobile_navigation" />


</androidx.constraintlayout.widget.ConstraintLayout>

fragment_dashboard.xml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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"
    android:background="@color/white"
    tools:context=".ui.fragments.DashboardFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rv_dashboard_items"
        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" />

    <TextView
        android:id="@+id/tv_no_dashboard_items_found"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:text="no_dashboard_item_found"
        android:textAlignment="center"
        android:textSize="20sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

fragment_quiz.xml

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    <?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.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=".ui.fragments.QuizFragment">

    <androidx.recyclerview.widget.RecyclerView
        android:id="@+id/rvQuizzesFrag"
        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" />

    <TextView
        android:id="@+id/tv_no_products_found"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:text="NO QUIZZES TODAY"
        android:textAlignment="center"
        android:textSize="30sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

FirestoreClass.kt

当我超过问题中的字符限制时,代码的Import部分将从问题中删除。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package com.example.quiz.firestore


class FirestoreClass {

    private val mFireStore = FirebaseFirestore.getInstance()

    fun getDashboardItemsList(fragment: DashboardFragment) {
       
        mFireStore.collection("quizzes")
            .get() 
            .addOnSuccessListener { document ->

                Log.e(fragment.javaClass.simpleName, document.documents.toString())

                val quizList: ArrayList<Quiz> = ArrayList()

               
                for (i in document.documents) {

                    val qz = i.toObject(Quiz::class.java)!!
                    qz.quiz_id = i.id
                    quizList.add(qz)
                }

                fragment.successDashboardItemsList(quizList)
            }
            .addOnFailureListener { e ->
              
                fragment.hideProgressDialog()
                Log.e(fragment.javaClass.simpleName, "Error while getting dashboard items list.", e)
            }
    }


    fun getCurrentUserID(): String {
        // An Instance of currentUser using FirebaseAuth
        val currentUser = FirebaseAuth.getInstance().currentUser

        var currentUserID = ""
        if (currentUser != null) {
            currentUserID = currentUser.uid
        }

        return currentUserID
    }


    fun uploadProductDetails(activity: AddProductActivity, productInfo: Quiz) {

        mFireStore.collection("quizzes")
            .document()
          
            .set(productInfo, SetOptions.merge())
            .addOnSuccessListener {

              
                activity.productUploadSuccess()
            }
            .addOnFailureListener { e ->

                activity.hideProgressDialog()

                Log.e(
                    activity.javaClass.simpleName,
                    "Error while uploading the product details.",
                    e
                )
            }
    }

    fun getUserDetails(activity: Activity) {

        mFireStore.collection("users")
         
            .document(getCurrentUserID())
            .get()
            .addOnSuccessListener { document ->

                Log.i(activity.javaClass.simpleName, document.toString())

                val user = document.toObject(User::class.java)!!

                val sharedPreferences =
                    activity.getSharedPreferences(
                        Constants.MYAPP_PREFERENCES,
                        Context.MODE_PRIVATE
                    )

                val editor: SharedPreferences.Editor = sharedPreferences.edit()
                editor.putString(
                    Constants.LOGGED_IN_USERNAME,
                    "${user.firstName} ${user.lastName}"
                )
                editor.apply()

                when (activity) {
                    is LoginActivity -> {
                      
                        activity.userLoggedInSuccess(user)
                    }

                }
            }
            .addOnFailureListener { e ->
               
                when (activity) {
                    is LoginActivity -> {
                        activity.hideProgressDialog()
                    }
                }

                Log.e(
                    activity.javaClass.simpleName,
                    "Error while getting user details.",
                    e
                )
            }
    }


    fun getQuizList(fragment: Fragment) {
      
        mFireStore.collection("quizzes")
            .whereEqualTo("user_id", getCurrentUserID())
            .get() 
            .addOnSuccessListener { document ->

                Log.e("Products List", document.documents.toString())

                val productsList: ArrayList<Quiz> = ArrayList()

                for (i in document.documents) {

                    val product = i.toObject(Quiz::class.java)
                    product!!.quiz_id = i.id

                    productsList.add(product)
                }

                when (fragment) {
                    is QuizFragment -> {
                        fragment.successQuizListFromFireStore(productsList)
                    }
                }
            }
            .addOnFailureListener { e ->
               
                when (fragment) {
                    is QuizFragment -> {
                        fragment.hideProgressDialog()
                    }
                }

                Log.e("Get Product List", "Error while getting product list.", e)
            }
    }


    fun getAllQuizList(activity: Activity) {
       
        mFireStore.collection("quizzes")
            .get() 
            .addOnSuccessListener { document ->

                Log.e("Products List", document.documents.toString())

                val productsList: ArrayList<Quiz> = ArrayList()

                for (i in document.documents) {

                    val product = i.toObject(Quiz::class.java)
                    product!!.quiz_id = i.id

                    productsList.add(product)
                }

            }
            .addOnFailureListener { e ->
                Log.e("Get Product List", "Error while getting all product list.", e)
            }
    }

}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-05-25 18:02:11

在阅读了您的代码之后,我认为原因是:在使用recycleView时可能会出现一些小问题。

在您的代码中,您似乎在xml的同一个位置使用了两个xml,一个是没有数据的recycleView,另一个是异步获取数据后的recycleView。然后在获取数据的功能中控制recycleView的显示和隐藏。

但是,如果在将回收视图附加到片段后不立即初始化它,您可能会看到No adapter attached; skipping layout

解决方案:只需设置一个recycleView,并在片段/活动的初始化函数中为其设置一个空数据。DashboardItemsListAdapter(requireActivity(), listOf<Quiz>())

守则的一部分:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private lateinit var adapter: DashboardItemsListAdapter

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
    super.onViewCreated(view, savedInstanceState)
    adapter = DashboardItemsListAdapter(requestActivity(), arrayListOf<Quiz>())
}

fun successDashboardItemsList(dashboardItemsList: ArrayList<Quiz>) {
    adapter.list = dashboardItemsList
    adapter.notifyDataSetChanged()
}

我只是在这里提供我的一个想法。您不能每次调用successDashboardItemsList()时都设置一个新适配器。在调用successDashboardItemsList()之前,应该初始化适配器(可能没有数据)。每次调用successDashboardItemsList()时,重新分配Adapter对象的list字段的值。并调用Adapter对象的notifyDataSetChanged(),以便解决问题。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import android.os.Bundle
import android.util.Log
import android.view.*
import androidx.recyclerview.widget.GridLayoutManager
import com.example.quiz.R
import com.example.quiz.firestore.FirestoreClass
import com.example.quiz.models.Quiz
import com.example.quiz.ui.adapters.DashboardItemsListAdapter
import kotlinx.android.synthetic.main.fragment_dashboard.*

class DashboardFragment : BaseFragment() {

    private lateinit var adapter: DashboardItemsListAdapter

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setHasOptionsMenu(true)
    }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.fragment_dashboard, container, false)
    }



    private lateinit var recyclerView: RecyclerView

    private lateinit var textView: TextView

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        recyclerView = view.findViewById<RecyclerView>(R.id.rv_dashboard_items)
        textView = view.findViewById(R.id.tv_no_dashboard_items_found)
        adapter = DashboardItemsListAdapter(requireActivity(), arrayListOf<Quiz>())
        recyclerView.layoutManager = GridLayoutManager(requireContext(), 1)
        recyclerView.setHasFixedSize(true)
        recyclerView.adapter = adapter
    }

    override fun onResume() {
        super.onResume()

        getDashboardItemsList()
    }

    private fun getDashboardItemsList() {
        showProgressDialog("please_wait")

        FirestoreClass().getDashboardItemsList(this@DashboardFragment)
    }

    fun successDashboardItemsList(dashboardItemsList: ArrayList<Quiz>) {

        hideProgressDialog()

        for (i in dashboardItemsList) {
            Log.i("Item Title", i.quiz_name)
        }

        if (dashboardItemsList.size > 0) {

            recyclerView.visibility = View.VISIBLE
            textView.visibility = View.GONE

            adapter.list = dashboardItemsList
            adapter.notifyDataSetChanged()
        } else {
            recyclerView.visibility = View.GONE
            textView.visibility = View.VISIBLE
        }
    }
}

DashboardItemListAdapter.kt

改为:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
  override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
         return MyViewHolder(
             LayoutInflater.from(context).inflate(
                 R.layout.item_list_layout,
                 parent,
                 false
             )
         )
     }
票数 1
EN

Stack Overflow用户

发布于 2021-05-26 02:45:25

在您的DashboardItemsListAdapter中,您正在膨胀item_dashboard_layout,但是您正在为fragment_dashboard导入合成绑定。

膨胀的布局可能不包含fragment_dashboard绑定所需的视图,因此绑定返回空值。

确保在充气和视图绑定中使用相同的布局。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67696197

复制
相关文章
【字符串】字符串查找 ( Rabin-Karp 算法 )
算法题目链接 : https://www.lintcode.com/problem/13/
韩曙亮
2023/03/29
1.2K0
子字符串查找----Rabin-Karp算法(基于散列)
Rabin-Karp算法是一种基于散列的子字符串查找算法--先计算模式字符串的散列值,然后用相同的散列函数计算文本中所有可能的M个字符的子字符串的山裂纸并与模式字符串的散列值比较。如果两者相同,再继续验证两者是否匹配。 基本思想:长度为M的对应着一个R进制的M位数, 举例说明Rabin-Karp算法: 例如要在文本3141592653589793中找到模式26535,首先选择散列表大小Q(这里设置为997),采用除留余数法,散列值为26535%997 = 613,然后计算文本中所有长度为5的字符串的散列值并
SuperHeroes
2018/05/30
2.1K0
别用 KMP 了, Rabin-Karp 算法了解下?
经常有读者留言,请我讲讲那些比较经典的算法,我觉得有这个必要,主要有以下原因: 1、经典算法之所以经典,一定是因为有独特新颖的设计思想,那当然要带大家学习一波。 2、我会尽量从最简单、最基本的算法切入,带你亲手推导出来这些经典算法的设计思想,自然流畅地写出最终解法。一方面消除大多数人对算法的恐惧,另一方面可以避免很多人对算法死记硬背的错误习惯。 我之前用状态机的思路讲解了 KMP 算法,说实话 KMP 算法确实不太好理解。不过今天我来讲一讲字符串匹配的另一种经典算法:Rabin-Karp 算法,这是一个很简单优雅的算法。 本文会由浅入深地讲明白这个算法的核心思路,先从最简单的字符串转数字讲起,然后研究一道力扣题目,到最后你就会发现 Rabin-Karp 算法使用的就是滑动窗口技巧,直接套前文讲的 滑动窗口算法框架 就出来了,根本不用死记硬背。 废话不多说了,直接上干货。 首先,我问你一个很基础的问题,给你输入一个字符串形式的正整数,如何把它转化成数字的形式?很简单,下面这段代码就可以做到: string s = "8264"; int number = ; for (int i = ; i < s.size(); i++) { // 将字符转化成数字 number = * number + (s[i] - '0'); print(number); } // 打印输出: // 8 // 82 // 826 // 8264 可以看到这个算法的核心思路就是不断向最低位(个位)添加数字,同时把前面的数字整体左移一位(乘以 10)。 为什么是乘以 10?因为我们默认探讨的是十进制数。这和我们操作二进制数的时候是一个道理,左移一位就是把二进制数乘以 2,右移一位就是除以 2。 上面这个场景是不断给数字添加最低位,那如果我想删除数字的最高位,怎么做呢?比如说我想把 8264 变成 264,应该如何运算?其实也很简单,让 8264 减去 8000 就得到 264 了。 这个 8000 是怎么来的?是 8 x 10^3 算出来的。8 是最高位的数字,10 是因为我们这里是十进制数,3 是因为 8264 去掉最高位后还剩三位数。 上述内容主要探讨了如何在数字的最低位添加数字以及如何删除数字的最高位,用R表示数字的进制数,用L表示数字的位数,就可以总结出如下公式: /* 在最低位添加一个数字 */ int number = ; // number 的进制 int R = ; // 想在 number 的最低位添加的数字 int appendVal = ; // 运算,在最低位添加一位 number = R * number + appendVal; // 此时 number = 82643 /* 在最高位删除一个数字 */ int number = ; // number 的进制 int R = ; // number 最高位的数字 int removeVal = ; // 此时 number 的位数 int L = ; // 运算,删除最高位数字 number = number - removeVal * R^(L-); // 此时 number = 264 如果你能理解这两个公式,那么 Rabin-Karp 算法就没有任何难度,算法就是这样,再高大上的技巧,都是在最简单最基本的原理之上构建的。不过在讲 Rabin-Karp 算法之前,我们先来看一道简单的力扣题目。 高效寻找重复子序列 看下力扣第 187 题「重复的 DNA 序列」,我简单描述下题目: DNA 序列由四种碱基A, G, C, T组成,现在给你输入一个只包含A, G, C, T四种字符的字符串s代表一个 DNA 序列,请你在s中找出所有重复出现的长度为 10 的子字符串。 比如下面的测试用例: 输入:s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" 输出:["AAAAACCCCC","CCCCCAAAAA"] 解释:子串 "AAAAACCCCC" 和 "CCCCCAAAAA" 都重复出现了两次。 输入:s = "AAAAAAAAAAAAA" 输出:["AAAAAAAAAA"] 函数签名如下: List<String> findRepeatedDnaSequences(String s); 这道题的拍脑袋解法比较简单粗暴,我直接穷举所有长度为 10 的子串,然后借助哈希集合寻找那些重复的子串就行了,代码如下: // 暴力解法 List<String> findRepeatedDnaSequences(String s) { int n = s.length(); // 记录出现过的子串 HashSet<String> seen = new HashSet(); // 记录那些重复出现多次的子串 // 注
labuladong
2022/12/08
1K0
常用字符串匹配算法简介
字符串模式匹配是常见的算法之一,在实际生活中有较高的使用频率,特别是在当下的互联网服务中,经常用于游戏角色名检查、论坛发帖、直播弹幕、分类打标签、入侵检测等场景。字符串模式匹配又分为单模匹配和多模匹配,区别在于单模匹配是搜索一个模式串,多模式匹配是搜索多个模式串。由于无数大佬前赴后继的投入到模式匹配算法的研究中,时至今日,又有大量成熟的匹配算法,这里姜维大家简要介绍一些,可以根据自身业务需要选用。
用户1257041
2019/09/01
3K0
子字符串查找----各种算法总结
优点: 暴力查找算法:实现简单且在一般情况下工作良好(Java的String类型的indexOf()方法就是采用暴力子字符串查找算法); Knuth-Morris-Pratt算法能够保证线性级别的性能且不需要在正文中回退; Boyer-Moore算法的性能一般情况下都是亚线性级别; Rabin-Karp算法是线性级别; 缺点: 暴力查找算法所需时间可能和NM成正比; Knuth-Morris-Pratt算法和Boyer-Moore算法需要额外的内存空间; Rabin-Karp算法内循环很长(若干次算术运算,
SuperHeroes
2018/05/30
1K0
字符串匹配算法_字符串模式匹配算法
网络信息中充满大量的字符串,对信息的搜寻至关重要,因此子字符串查找(即字符串匹配)是使用频率非常高的操作:给定一段长度为N的文本和长度为M的模式字符串(N≥M),在文本中找到一个和模式串相匹配的子串。由这个问题可以延伸至统计模式串在文本中出现的次数、找出上下文(和该模式串相符的子字符串周围的文字)等更复杂的问题。
全栈程序员站长
2022/08/02
2.9K0
字符串匹配算法_字符串模式匹配算法
[数据结构拾遗]子字符串匹配常用算法总结
本专栏旨在快速了解常见的数据结构和算法。在需要使用到相应算法时,能够帮助你回忆出常用的实现方案并且知晓其优缺点和适用环境。
蛮三刀酱
2019/03/26
1.2K0
[数据结构拾遗]子字符串匹配常用算法总结
[数据结构拾遗]子字符串匹配常用算法总结
本专栏旨在快速了解常见的数据结构和算法。在需要使用到相应算法时,能够帮助你回忆出常用的实现方案并且知晓其优缺点和适用环境。
Rude3Knife的公众号
2019/08/08
9240
[数据结构拾遗]子字符串匹配常用算法总结
字符串——28. 实现 strStr()
给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回 -1 。
向着百万年薪努力的小赵
2022/12/02
3070
Miller Rabin算法详解
何为Miller Rabin算法 首先看一下度娘的解释(如果你懒得读直接跳过就可以反正也没啥乱用:joy:) Miller-Rabin算法是目前主流的基于概率的素数测试算法,在构建密码安全体系中占有重要的地位。通过比较各种素数测试算法和对Miller-Rabin算法进行的仔细研究,证明在计算机中构建密码安全体系时, Miller-Rabin算法是完成素数测试的最佳选择。通过对Miller-Rabin 算 法底层运算的优化,可以取得较以往实现更好的性能。[1]  随着信息技术的发展、网络的普及和电子商务的开
attack
2018/04/11
2.9K0
【字符串】字符串查找 ( 蛮力算法 )
算法题目链接 : https://www.lintcode.com/problem/13/
韩曙亮
2023/03/29
2.8K0
【字符串】字符串查找 ( 蛮力算法 )
字符串匹配算法_多字符串匹配
从好后缀的后缀子串中,找一个最长的且和模式串的前缀子串匹配的 {v},滑动至 {v} 对齐
全栈程序员站长
2022/09/25
1.8K0
字符串匹配算法_多字符串匹配
字符串匹配算法 -- 朴素匹配
为什么叫做朴素匹配,我理解的就是这是一种寻常想法,简单粗暴的算法。是一种暴力的算法,不考虑其时间复杂度以及效率。只要达到匹配的目的即可。
lexingsen
2022/02/24
1.9K0
字符串匹配算法 -- 朴素匹配
Golang的strings.go源码解析 - Rabin-Karp了解一下?
strings包是我们经常在处理字符串的时候要用的,这次我们来看看它其中的一些方法具体是如何实现的。我就找到其中常用的几个方法,然后针对其中比较难的部分还有应用到一些特别算法的部分进行分析。
LinkinStar
2022/09/01
2730
字符串的匹配算法_多字符串匹配
不要被事物的表面现象所迷惑,这个算法全称:Brute Force,有个拉风的中文名:暴力匹配算法。
全栈程序员站长
2022/09/25
2.2K0
字符串的匹配算法_多字符串匹配
字符串匹配---BF算法--朴素的模式匹配算法
#include<iostream> using namespace std; #include<string> //BF int BF(string& a,string& b) { //求出a串的长度 int sizeA=a.length();//返回的是字符串中字符个数 //求出b串的长度 int sizeB = b.length(); //i指向A,j指向B子串 int i=0; int j=0; //b是子串,a while (i <=sizeA-1&&j<= sizeB-1)
大忽悠爱学习
2021/03/15
2.1K0
KMP(Knuth Morris Pratt)算法的Go语言实现
有两部分组成:并且是由大到小,倒着匹配 坏前缀:普通匹配只一位一位移动,移动规则为 si(坏字符的位置) xi(坏字符在匹配字符最后出现的位置) 都没有xi=-1 移动距离等于si-xi 好后缀:坏前缀有可能产生负数,所以还要利用好后缀来进行匹配,好后缀类似坏前缀如果匹配串中有和好后缀相同的子串 ,移动到最靠后的子串的位置,如果没有相同的子串,就需要在匹配的子串中,查找和前缀子串匹配最长的子串进行移动。
ccf19881030
2020/10/28
9220
字符串匹配算法详解
愿你们都能考上自己心仪的学校,为你们的备考生涯划上一个完美的句号。做为你们的师兄有几句话想对你们说,希望这些话能对你们有一些帮助。
公众号袁厨的算法小屋
2021/01/08
1.5K0
搜索中常见数据结构与算法探究(二)
Tech    导读    本文介绍了几个常见的匹配算法,通过算法过程和算法分析介绍了各个算法的优缺点和使用场景,并为后续的搜索文章做个铺垫;读者可以通过比较几种算法的差异,进一步了解匹配算法演进过程以及解决问题的场景;KMP算法和Double-Array TireTree是其中算法思想的集大成者,希望读者重点关注。 01 前言 上文探究了数据结构和算法的一些基础和部分线性数据结构和部分简单非线性数据结构,本文我们来一起探究图论,以及一些字符串模式匹配的高级数据结构和算法。《搜索
京东技术
2022/04/02
3570
搜索中常见数据结构与算法探究(二)
【算法】快速排序与归并排序对比
【字符串】最长回文子串 ( 蛮力算法 ) 【字符串】最长回文子串 ( 中心线枚举算法 ) 【字符串】最长回文子串 ( 动态规划算法 ) ★ 【字符串】字符串查找 ( 蛮力算法 ) 【字符串】字符串查找 ( Rabin-Karp 算法 )
韩曙亮
2023/03/29
6370

相似问题

Rabin Karp字符串匹配算法

23

Karp Rabin算法

15

Karp-Rabin算法

11

Rabin-Karp算法

37

Rabin-Karp字符串匹配算法效率

14
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文