将Firestore与Fragment和ViewModel一起使用时,Android应用程序崩溃



我有一个应用程序,它在MainActivity的片段中显示产品列表。使用ViewModel通过Repository从Firestore数据库读取项目列表。

主要行动:

class MainActivity : AppCompatActivity() {
private val model: ProductViewModel by lazy {
ViewModelProvider(this).get(ProductViewModel::class.java)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
supportFragmentManager.beginTransaction().replace(R.id.fragment, ProductListFragment())
.commit()
...

ProductListFragment:

class ProductListFragment : Fragment() {
private val model: ProductViewModel by lazy {
ViewModelProvider(activity as ViewModelStoreOwner).get(ProductViewModel::class.java)
}
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
val listView =
inflater.inflate(R.layout.product_list_fragment, container, false) as RecyclerView
listView.layoutManager = LinearLayoutManager(context, LinearLayoutManager.VERTICAL, false)
model.products.observe(viewLifecycleOwner, Observer { productList ->
listView.adapter = ProductListAdapter(productList)    // THIS LINE IS PART OF THE ERROR
})
return listView
}
private fun selectItem(product: Product) {
model.select(product)
fragmentManager?.beginTransaction()?.replace(R.id.fragment, ProductDetailsFragment())
?.commit()
}

private inner class ProductListAdapter(var productList: List<Product>) :
RecyclerView.Adapter<ProductListAdapter.ViewHolder>() {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.product_list_item, parent, false)
return ViewHolder(view)
}
override fun getItemCount(): Int {
return productList.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
val product = productList[position]
holder.productName.text = product.title
holder.itemView.setOnClickListener {
selectItem(product)
}
}
private inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) {
val productName: TextView = view.findViewById(R.id.productName)
}
}
}

ProductViewModel.kt:

class ProductViewModel : ViewModel() {
val products: LiveData<List<Product>> by lazy {
MutableLiveData<List<Product>>().also {
val productList = arrayListOf<Product>()
Repository.getAllProducts()?.addOnSuccessListener {products ->
products.forEach { product ->
productList.add(product.toObject(Product::class.java))
}
it.value = productList  // THIS LINE IS CAUSING AN ERROR
}
}
}
...

Repository.kt:

object Repository {
private val db = FirebaseFirestore.getInstance()
private val productCollection: CollectionReference?
get() {
val user = Authenticator.user
if (user != null) {
return db.collection(USERS).document(user.uid).collection(COLLECTION)
}
return null
}
fun getAllProducts(): Task<QuerySnapshot>? {
return productCollection?.get()
}
...

这是我得到的错误:

java.lang.NullPointerException: Attempt to invoke virtual method 'boolean androidx.recyclerview.widget.RecyclerView$ViewHolder.shouldIgnore()' on a null object reference
at androidx.recyclerview.widget.RecyclerView$LayoutManager.removeAndRecycleAllViews(RecyclerView.java:10340)
at androidx.recyclerview.widget.RecyclerView.removeAndRecycleViews(RecyclerView.java:1179)
at androidx.recyclerview.widget.RecyclerView.setAdapterInternal(RecyclerView.java:1202)
at androidx.recyclerview.widget.RecyclerView.setAdapter(RecyclerView.java:1161)
at .ProductListFragment$onCreateView$1.onChanged(ProductListFragment.kt:35)
at .ProductListFragment$onCreateView$1.onChanged(ProductListFragment.kt:22)
at androidx.lifecycle.LiveData.considerNotify(LiveData.java:131)
at androidx.lifecycle.LiveData.dispatchingValue(LiveData.java:149)
at androidx.lifecycle.LiveData.setValue(LiveData.java:307)
at androidx.lifecycle.MutableLiveData.setValue(MutableLiveData.java:50)
at .ProductViewModel$products$2$1$1.onSuccess(ProductViewModel.kt:17)
at .ProductViewModel$products$2$1$1.onSuccess(ProductViewModel.kt:9)
at com.google.android.gms.tasks.zzn.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6682)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1520)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1410)

数据库有三个用于该集合的条目,但是Repository传递给onSuccess函数的值是一个空列表(而不是null(。我有两个问题:

  1. 为什么存储库会返回一个空列表而不是这三个项目
  2. 造成坠机的NPE是从哪里来的

viemodelrecyclerview调用onViewCreated而不是onCreateView

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
//view model and recyclerview
}

//活动!!

ViewModelProvider(activity!!.get(ProductViewModel::class.java)

相关内容

  • 没有找到相关文章

最新更新