点击按钮时,使用选定的 Spinner 值更新 Firestore 中的字段 [英] Update a field in the firestore with a selected value of Spinner on hitting a button
问题描述
当我点击按钮以使用微调器值更新 firestore
中的字段时,我的应用程序崩溃.
My app crashes when I hit the button to update a field in the firestore
with spinner value.
集合名称为orders
文档名称是动态的,使用model.id
获取.
The document name is dynamic, model.id
is used to get it.
字段名称为order_status
需要为字段 order_status
更新的新值将从微调器中获取.
New value that needs to be updated for the field order_status
is to be taken from the spinner.
代码工作正常并且当我对值进行硬编码时该字段会更新,但是当我想使用 spinner
The code works fine and the field get updated when I hardcode the value, but it crashes when I want to use the selected value of spinner
以下是Logcat
kotlin.UninitializedPropertyAccessException: lateinit property binding has not been initialized
at com.trad.ui.adapters.OrderStatusListAdapter.access$getBinding$p(OrderStatusListAdapter.kt:32)
at com.trad.ui.adapters.OrderStatusListAdapter$onBindViewHolder$1.onClick(OrderStatusListAdapter.kt:84)
at android.view.View.performClick(View.java:8160)
at android.widget.TextView.performClick(TextView.java:16222)
at android.view.View.performClickInternal(View.java:8137)
at android.view.View.access$3700(View.java:888)
at android.view.View$PerformClick.run(View.java:30236)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
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)
OrdersByStatusFragment.kt
class OrdersByStatusFragment : BaseFragment() {
private lateinit var binding: OrderStatusLayoutBinding
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
return inflater.inflate(R.layout.fragment_orders_by_status, container, false)
}
override fun onResume() {
super.onResume()
getOrderStatusList()
}
private fun getOrderStatusList() {
showProgressDialog(resources.getString(R.string.please_wait))
FirestoreClass().getOrderStatusList(this@OrdersByStatusFragment)
}
fun successOrderStatusList(orderStatusList: ArrayList<OrderStatus>) {
hideProgressDialog()
if (orderStatusList.size > 0) {
rv_order_by_status.visibility = View.VISIBLE
tv_no_orders_by_status_found.visibility = View.GONE
rv_order_by_status.layoutManager = LinearLayoutManager(activity)
rv_order_by_status.setHasFixedSize(true)
val orderStatusListAdapter =
OrderStatusListAdapter(requireActivity(), orderStatusList)
rv_order_by_status.adapter = orderStatusListAdapter
} else {
rv_order_by_status.visibility = View.GONE
tv_no_orders_by_status_found.visibility = View.VISIBLE
}
}
fun successNewOrderStatus() {
Toast.makeText(requireContext(), "Success", Toast.LENGTH_SHORT).show()
}
}
OrderStatusListAdapter.kt
open class OrderStatusListAdapter(
private val context: Context,
private var list: ArrayList<OrderStatus>,
) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private lateinit var binding: OrderStatusLayoutBinding
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return MyViewHolder(OrderStatusLayoutBinding.inflate(LayoutInflater.from(parent.context), parent,false))
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val model = list[position]
if (holder is MyViewHolder) {
GlideLoader(context).loadProductPicture(
model.image,
holder.itemView.iv_order_status_item_image
)
val dateFormat = "dd MMM yyyy HH:mm"
val formatter = SimpleDateFormat(dateFormat, Locale.getDefault())
val calendar: Calendar = Calendar.getInstance()
calendar.timeInMillis = model.order_datetime
val orderDateTime = formatter.format(calendar.time)
holder.itemView.tv_order_status_order_date.text = orderDateTime
holder.itemView.tv_order_status_item_name.text = model.items[0].title
holder.itemView.tv_order_status_item_price.text = "$${model.total_amount}"
holder.itemView.tv_order_status.text = model.order_status
holder.itemView.tv_order_status_order_id.text = model.id
holder.itemView.btn_order_status_change_status.setOnClickListener {
binding.spnOrderChangeStatus.onItemSelectedListener =
object : AdapterView.OnItemSelectedListener {
override fun onItemSelected(
parent: AdapterView<*>?,
view: View?,
position: Int,
id: Long
) {
Toast.makeText(
context,
"Selected value is ${
parent?.getItemAtPosition(position).toString()
}",
Toast.LENGTH_SHORT
).show()
val newstat = parent?.getItemAtPosition(position).toString()
FirestoreClass().updateOrderStatus(model.id, newstat)
}
override fun onNothingSelected(parent: AdapterView<*>?) {
}
}
}
holder.itemView.ib_order_status_delete_product.visibility = View.GONE
holder.itemView.setOnClickListener {
val intent = Intent(context, SoldProductDetailsActivity::class.java)
intent.putExtra(Constants.EXTRA_SOLD_PRODUCT_DETAILS, model)
context.startActivity(intent)
}
}
}
override fun getItemCount(): Int {
return list.size
}
inner class MyViewHolder(private val binding : OrderStatusLayoutBinding) : RecyclerView.ViewHolder(binding.root)
}
FirestoreClass.kt
fun updateOrderStatus(
orderID: String,
newOrderStatus: String
) {
mFireStore.collection(Constants.ORDERS)
.document(orderID)
.update("order_status", newOrderStatus)
.addOnSuccessListener {
}
.addOnFailureListener {
}
}
编辑
以下是新的错误.
2021-06-09 01:24:17.550 2253-2253/com.tradaxis E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.tradaxis, PID: 2253
java.lang.NullPointerException: rv_order_by_status must not be null
at com.tradaxis.ui.fragments.OrdersByStatusFragment.successOrderStatusList(OrdersByStatusFragment.kt:76)
at com.tradaxis.firestore.FirestoreClass$getOrderStatusList$1.onSuccess(FirestoreClass.kt:935)
at com.tradaxis.firestore.FirestoreClass$getOrderStatusList$1.onSuccess(FirestoreClass.kt:22)
at com.google.android.gms.tasks.zzn.run(Unknown Source:4)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
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)
rv_order_by_status.visibility = View.VISIBLE
'fun successOrderStatusList(orderStatusList: ArrayList)' 中的代码是 OrdersByStatusFragment.kt:76
rv_order_by_status.visibility = View.VISIBLE
in 'fun successOrderStatusList(orderStatusList: ArrayList)' is the code at OrdersByStatusFragment.kt:76
fragment.successOrderStatusList(list)
是 FirestoreClass.kt:935 处的代码
fragment.successOrderStatusList(list)
in FirestoreClass.kt is the code at FirestoreClass.kt:935
class FirestoreClass {
是 FirestoreClass.kt:22 处的代码
class FirestoreClass {
is the code at FirestoreClass.kt:22
注意:在进行这些更改之前,这些代码行没有这样的错误.
NOTE: There was no such error for these lines of code before making these changes.
推荐答案
在您的 OrderStatusFragment OnCreateView 中,您没有设置绑定.你需要做这样的事情
In your OrderStatusFragment OnCreateView you aren't setting the binding. You need to do something like this
private var _binding: ResultProfileBinding? = null
// This property is only valid between onCreateView and
// onDestroyView.
private val binding get() = _binding!!
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
_binding = ResultProfileBinding.inflate(inflater, container, false)
val view = binding.root
return view
}
override fun onDestroyView() {
super.onDestroyView()
_binding = null
}
您将使用 OrderStatusLayoutFragment 而不是 ResultProfileBinding.这与 firebase 无关,但它应该可以解决您当前遇到的崩溃问题.
Instead of ResultProfileBinding you'd use your OrderStatusLayoutFragment. This is unrelated to firebase, but it should fix the crash you are currently having.
阅读更多:https://developer.android.com/topic/libraries/视图绑定
不要忘记销毁,以避免内存泄漏.
Don't forget the ondestroy, to avoid memory leaks.
这篇关于点击按钮时,使用选定的 Spinner 值更新 Firestore 中的字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!