Здравствуйте, и заранее спасибо за помощь. Хочу сразу сказать что большая часть этого кода не моя. Я лишь учусь Котлину и поэтому скачал небольшой проект с Гитхаба и пытаюсь разбираться в нём, дописывая что-то своё.
В вопросе будет много кода, но я попытался сократить его вырезав импорты.
Вот кратко мой вопрос:
Ниже можно увидеть скриншот формы. Как видно, на экране присутствует несколько кнопок и все из них работают по схожему принципу: добавляют продукт или удаляют, принимая в качестве аргумента сам продукт. К сожалению, я не пойму как реализовать работу кнопки "Заказать". По сути мне просто нужна заглушка выводящая тост "Заказ оформлен". Но каждая кнопка на этой форме должна принимать в качестве аргумента продукт. Пытаясь просто выполнить функцию с тостом, по аналогии с тем что есть в нижеследующих файлах с кодом я получаю ошибку.
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.Button.setOnClickListener(android.view.View$OnClickListener)' on a null object reference.
Вот сама форма:
fragment_cart.xml - код формы.
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".ui.cart.CartFragment"
android:orientation="vertical"
android:background="#000000">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginHorizontal="@dimen/_16sdp"
android:layout_marginBottom="@dimen/_8sdp">
<Button
android:id="@+id/btn_order"
android:layout_width="wrap_content"
android:layout_height="@dimen/_48sdp"
android:layout_alignParentBottom="true"
android:background="@drawable/bg_button_green"
android:clickable="true"
android:focusable="true"
android:text="Заказать"
android:textAllCaps="false"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</LinearLayout>
Ниже я привожу код логики работы кнопок, а также модель продукта.
CartFragment.kt
class CartFragment : Fragment(R.layout.fragment_cart) {
private val viewModel: CartViewModel by viewModel()
private val cartAdapter: CartAdapter by lazy {
CartAdapter(object : OnTotalChange{
override fun onTotalChange(total: Int) {
val dec = DecimalFormat("#,###")
val priceRupiah = dec.format(total)
tv_total_price.text = "$priceRupiah руб"
}
})
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
observeCart()
setListCart()
viewModel.loadDataCart()
}
private fun observeCart() {
viewModel.cartProduct.observe(viewLifecycleOwner, {
cartAdapter.setDataAdapter(it)
})
}
private fun setListCart() {
rv_cart.setHasFixedSize(true)
rv_cart.adapter = cartAdapter
cartAdapter.onClickListener = object : OnClickItemAddRemove {
override fun onClick(productEntity: ProductEntity) {
val intent = Intent(activity, DetailProductActivity::class.java)
intent.putExtra(Constant.DATA, productEntity)
startActivity(intent)
}
override fun onClickAdd(productEntity: ProductEntity) {
addQtyProduct(productEntity)
}
override fun onClickSubstract(productEntity: ProductEntity) {
substractQtyProduct(productEntity)
}
override fun onClickRemove(productEntity: ProductEntity) {
removeFromCart(productEntity)
}
<b> override fun onClickOrderCreate(productEntity: ProductEntity) {
orderCreate(productEntity)
}</b>
}
}
private fun addQtyProduct(productEntity: ProductEntity) {
viewModel.addProduct(productEntity)
viewModel.loadDataCart()
}
private fun substractQtyProduct(productEntity: ProductEntity) {
viewModel.subtractProduct(productEntity)
viewModel.loadDataCart()
}
private fun removeFromCart(productEntity: ProductEntity) {
viewModel.removeProduct(productEntity, ProductSavedType.CART)
Toast.makeText(activity, "Продукт удалён", Toast.LENGTH_SHORT).show()
viewModel.loadDataCart()
}
<b> private fun orderCreate(productEntity: ProductEntity) {
Toast.makeText(activity, "Заказ офомрлен", Toast.LENGTH_SHORT).show()
}</b>
}
OnClickItem.kt
interface OnClickItem {
fun onClick(productEntity: ProductEntity)
}
interface OnClickItemAndAdd {
fun onClick(productEntity: ProductEntity)
fun onClickAdd(productEntity: ProductEntity)
}
interface OnClickItemAddRemove {
fun onClick(productEntity: ProductEntity)
fun onClickAdd(productEntity: ProductEntity)
fun onClickSubstract(productEntity: ProductEntity)
fun onClickRemove(productEntity: ProductEntity)
<b> fun onClickOrderCreate(productEntity: ProductEntity)</b>
}
interface myOnClick {
}
CartAdapter.kt
class CartAdapter(val listener : OnTotalChange): RecyclerView.Adapter<CartAdapter.CartViewHolder>() {
private var list: MutableList<ProductEntity> = mutableListOf()
var onClickListener: OnClickItemAddRemove? =null
var myOnClickListener: myOnClick? =null
inner class CartViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
@SuppressLint("SetTextI18n")
fun bind(productEntity: ProductEntity) {
val price = productEntity.priceToQty
val dec = DecimalFormat("#,###")
val priceRupiah = dec.format(price)
itemView.setOnClickListener {
onClickListener?.onClick(productEntity)
}
itemView.btn_delete_cart.setOnClickListener {
onClickListener?.onClickRemove(productEntity)
}
itemView.btn_min_cart.setOnClickListener {
onClickListener?.onClickSubstract(productEntity)
}
itemView.btn_plus_cart.setOnClickListener {
onClickListener?.onClickAdd(productEntity)
}
<b> itemView.btn_order.setOnClickListener {
onClickListener?.onClickOrderCreate(productEntity)
}</b>
Glide.with(itemView)
.load(productEntity.picture)
.transition(DrawableTransitionOptions.withCrossFade())
.fitCenter()
.into(itemView.iv_picture_cart)
itemView.tv_name_cart.text = productEntity.name
itemView.tv_description_cart.text = productEntity.description
itemView.tv_price_cart.text = "$priceRupiah руб"
itemView.tv_value_cart.text = productEntity.qty.toString()
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CartViewHolder {
val view: View =
LayoutInflater.from(parent.context).inflate(R.layout.item_cart, parent, false)
return CartViewHolder(view)
}
override fun onBindViewHolder(holder: CartViewHolder, position: Int) {
holder.bind(list[position])
}
override fun getItemCount(): Int {
return list.size
}
fun setDataAdapter(data: List<ProductEntity>) {
list.clear()
list.addAll(data)
notifyDataSetChanged()
val total = list.sumBy{it.priceToQty}
listener.onTotalChange(total)
}
}
ProductEntity.kt - модель продукта.
@Parcelize
@Entity(tableName = "product")
data class ProductEntity(
@PrimaryKey(autoGenerate = true)
@ColumnInfo(name="pk")
val pk: Int = 0,
@ColumnInfo(name="id")
val id: Int = 0,
@ColumnInfo(name= "name")
val name: String = "",
@ColumnInfo(name= "picture")
val picture: Int = 0,
@ColumnInfo(name= "description")
val description: String = "",
@ColumnInfo(name= "price")
val price: Int = 0,
@ColumnInfo(name= "qty")
val qty: Int = 0,
@ColumnInfo(name = "type")
val type: Int = ProductSavedType.FAV
): Parcelable{
val priceToQty get() = qty * price
}