1

I have the following error in android studio, And the problem is when adding products because if there is no product, it opens the shopping bag, but when adding one and wanting to re-enter it, it closes and when you want to enter the shopping bag purchases the application closes.

I would really like to receive help from you since I am not very expert in this application and I have very little time to deliver it, I will attach images and a video of the error with the application executed

ShoppingBagAdapter

class ShoppingBagAdapter(val context: Activity, val products: ArrayList): RecyclerView.Adapter<ShoppingBagAdapter.ShoppingBagViewHolder>() {

val sharedPref = SharedPref(context)
val TAG = "ShoppingBag"


init {
    (context as ClientShoppingBagActivity).setTotal(getTotal())
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShoppingBagViewHolder {
    val view = LayoutInflater.from(parent.context).inflate(R.layout.cardview_shopping_bag, parent, false)
    return ShoppingBagViewHolder(view)
}

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


override fun onBindViewHolder(holder: ShoppingBagViewHolder, position: Int) {

    val product = products[position] // CADA UNA DE LAS CATEGORIAS

    holder.textViewName.text = product.name
    holder.textViewCounter.text = "${product.quantity}"
    holder.textViewPrice.text = "${product.price * product.quantity!!}"
    Glide.with(context).load(product.image1).into(holder.imageViewProduct)

    holder.imageViewAdd.setOnClickListener { addItem(product, holder) }
    holder.imageViewRemove.setOnClickListener { removeItem(product, holder) }
    holder.imageViewDelete.setOnClickListener { deleteItem(position) }

// holder.itemView.setOnClickListener { goToDetail(product) } }

private fun getTotal(): Double {
    var total = 0.0

    for (p in products) {
        total = total + (p.quantity!! * p.price)
    }
    return total
}

private fun getIndexOf(idProduct: String): Int {
    var pos = 0

    for (p in products) {
        if (p.id == idProduct) {
            return pos
        }
        pos++
    }

    return -1
}

private fun deleteItem(position: Int) {
    products.removeAt(position)
    notifyItemRemoved(position)
    notifyItemRangeRemoved(position, products.size)
    sharedPref.save("order", products)
    (context as ClientShoppingBagActivity).setTotal(getTotal())
}


private fun addItem(product: Product, holder: ShoppingBagViewHolder) {

    val index = getIndexOf(product.id!!)
    product.quantity = product.quantity!! + 1
    products[index].quantity = product.quantity

    holder.textViewCounter.text = "${product.quantity}"
    holder.textViewPrice.text = "${product.quantity!! * product.price}$"

    sharedPref.save("order", products)
    (context as ClientShoppingBagActivity).setTotal(getTotal())
}

private fun removeItem(product: Product, holder: ShoppingBagViewHolder) {

    if (product.quantity!! > 1) {

        val index = getIndexOf(product.id!!)
        product.quantity = product.quantity!! - 1
        products[index].quantity = product.quantity

        holder.textViewCounter.text = "${product.quantity}"
        holder.textViewPrice.text = "${product.quantity!! * product.price}$"

        sharedPref.save("order", products)
        (context as ClientShoppingBagActivity).setTotal(getTotal())

    }

}

private fun goToDetail(product: Product) {
    val i = Intent(context, ClientProductsDetailActivity::class.java)
    i.putExtra("product", product.toJson())
    context.startActivity(i)
}

class ShoppingBagViewHolder(view: View): RecyclerView.ViewHolder(view) {

    val textViewName: TextView
    val textViewPrice: TextView
    val textViewCounter: TextView
    val imageViewProduct: ImageView
    val imageViewAdd: ImageView
    val imageViewRemove: ImageView
    val imageViewDelete: ImageView

    init {
        textViewName = view.findViewById(R.id.textview_name)
        textViewPrice = view.findViewById(R.id.textview_price)
        textViewCounter = view.findViewById(R.id.textview_counter)
        imageViewProduct = view.findViewById(R.id.imageview_product)
        imageViewAdd = view.findViewById(R.id.imageview_add)
        imageViewRemove = view.findViewById(R.id.imageview_remove)
        imageViewDelete = view.findViewById(R.id.imageview_delete)
    }

}

ClientShoppingBagActivity

class ClientShoppingBagActivity : AppCompatActivity() {

var recyclerViewShoppingBag:  RecyclerView? = null
var textViewTotal: TextView? = null
var buttomNext: Button? = null
var toolbar: Toolbar? = null


var adapter: ShoppingBagAdapter? = null
var sharedPref: SharedPref? = null
var gson = Gson()
var selectedProducts = ArrayList<Product>()

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

    sharedPref = SharedPref(this)

    recyclerViewShoppingBag = findViewById(R.id.recyclerview_shopping_bag)
    textViewTotal = findViewById(R.id.textview_total)
    buttomNext = findViewById(R.id.btn_next)
    toolbar = findViewById(R.id.toolbar)
    toolbar?.setTitleTextColor(ContextCompat.getColor(this, R.color.white))
    toolbar?.title = "Tu orden"

    setSupportActionBar(toolbar)
    supportActionBar?.setDisplayHomeAsUpEnabled(true)

    recyclerViewShoppingBag?.layoutManager = LinearLayoutManager(this)

    getProductsFromSharedPref()

    buttomNext?.setOnClickListener{goToAddressList() }

}

private fun goToAddressList(){
    val i = Intent(this, ClientAddressListActivity::class.java)
    startActivity(i)
}

fun setTotal(total: Double){
    textViewTotal?.text = "${total}$"
}

private fun getProductsFromSharedPref() {

    if (!sharedPref?.getData("order").isNullOrBlank()) { // EXISTE UNA ORDEN EN SHARED PREF
        val type = object : TypeToken<ArrayList<Product>>() {}.type
        selectedProducts = gson.fromJson(sharedPref?.getData("order"), type)

        adapter = ShoppingBagAdapter(this, selectedProducts)
        recyclerViewShoppingBag?.adapter = adapter
    }
}

link of the video where the application is running so you can see where the error is https://youtu.be/iUNCo5aCLLY

here is a more explicit video about the problem in question, I really hope you can help me https://youtu.be/T262TUQxRVw

and now I will proceed to attach the images so that you can see the full description of the error, although I can see them below as well

image 1 where is the complete error

in this image I specify the error line

in this image I specify the other line of the error

in this image I specify the other line of the error

in this image I specify the other line of the error

full error description

2022-05-16 16:28:46.508 6163-6163/com.blader.domicilios E/AndroidRuntime: FATAL EXCEPTION: main Process: com.blader.domicilios, PID: 6163 java.lang.RuntimeException: Unable to start activity ComponentInfo{com.blader.domicilios/com.blader.domicilios.activities.client.shopping_bag.ClientShoppingBagActivity}: java.lang.NullPointerException at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601) 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:2066) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:223) at android.app.ActivityThread.main(ActivityThread.java:7656) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) Caused by: java.lang.NullPointerException at com.blader.domicilios.adapters.ShoppingBagAdapter.getTotal(ShoppingBagAdapter.kt:57) at com.blader.domicilios.adapters.ShoppingBagAdapter.(ShoppingBagAdapter.kt:25) at com.blader.domicilios.activities.client.shopping_bag.ClientShoppingBagActivity.getProductsFromSharedPref(ClientShoppingBagActivity.kt:73) at com.blader.domicilios.activities.client.shopping_bag.ClientShoppingBagActivity.onCreate(ClientShoppingBagActivity.kt:52) at android.app.Activity.performCreate(Activity.java:8000) at android.app.Activity.performCreate(Activity.java:7984) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)  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:2066)  at android.os.Handler.dispatchMessage(Handler.java:106)  at android.os.Looper.loop(Looper.java:223)  at android.app.ActivityThread.main(ActivityThread.java:7656)  at java.lang.reflect.Method.invoke(Native Method) 


I really hope you can help me as I am very worried about not being able to deliver my work on time, and I really have very little time.**

BLADERVAN GAMER
  • 21
  • 1
  • 1
  • 5

2 Answers2

1

You haven't posted the full stacktrace so I'm just guessing, but I assume it's this line:

total = total + (p.quantity!! * p.price)

quantity is a nullable type, and you're supposed to null-check those to make sure they're not null before you do anything with them. !! is always a bad sign, it means "I promise this will never be null", and my guess is quantity is null and that's why it's crashing. (This is why you should always handle nulls and never use !! unless you absolutely know what you're doing and why you need it)

You can probably fix it with this:

private fun getTotal(): Double {
    var total = 0.0

    for (p in products) {
        if (p.quantity != null) total += p.quantity * p.price
    }
    return total
}

Or if you like:

private fun getTotal(): Double =
    products.sumByDouble { p -> (p.quantity ?: 0) * p.price }

I've no idea if there are any other issues with your app obviously, but that should hopefully stop you getting that particular NullPointerException

cactustictacs
  • 17,935
  • 2
  • 14
  • 25
  • Yes, bro, you were right, the line was written that way, but now the problem has been transferred to two other variables, and I would like to thank you since you are the only one who was willing to help me, I will post a screenshot of where he moved right away. error and if you need me to record a video please let me know that I will be very attentive – BLADERVAN GAMER May 17 '22 at 01:16
  • bro and regarding this expression !! the same android studio recommends me to use it and the truth as I am a beginner the truth is I don't know much – BLADERVAN GAMER May 17 '22 at 01:17
  • bro i posted an answer so you can see where the bug moved to now – BLADERVAN GAMER May 17 '22 at 01:29
  • @BLADERVANGAMER you'll have to post another question with any new problems and see if someone can help, I need to sleep - and post the stacktrace text (all of it) instead of screenshots, or people will just ignore them, they're a pain to read. And AS isn't recommending you use `!!`, it's *suggesting it* as a way to fix the error (that you haven't null-checked a thing that can be null, before you try to use it in a dangerous way). It's not a solution unless you *know for sure* that value will never be null, and usually that means it shouldn't be nullable at all – cactustictacs May 17 '22 at 01:32
0

This is where the error is now, the application closes when I try to add a product again, I will attach screenshots again here I select where the error marks, so that you can see which is the line that sends me the error, once thanks for helping me

enter image description here

code where it sends me the error again****

import android.app.Activity
import android.content.Intent
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.RecyclerView
import com.blader.domicilios.R
import com.blader.domicilios.activities.client.products.detail.ClientProductsDetailActivity
import com.blader.domicilios.activities.client.shopping_bag.ClientShoppingBagActivity
import com.blader.domicilios.models.Product
import com.blader.domicilios.utils.SharedPref
import com.bumptech.glide.Glide

class ShoppingBagAdapter(val context: Activity, val products: ArrayList<Product>): RecyclerView.Adapter<ShoppingBagAdapter.ShoppingBagViewHolder>() {

    val sharedPref = SharedPref(context)
    val TAG = "ShoppingBag"


    init {
        (context as ClientShoppingBagActivity).setTotal(getTotal())
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ShoppingBagViewHolder {
        val view = LayoutInflater.from(parent.context).inflate(R.layout.cardview_shopping_bag, parent, false)
        return ShoppingBagViewHolder(view)
    }

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


    override fun onBindViewHolder(holder: ShoppingBagViewHolder, position: Int) {

        val product = products[position] // CADA UNA DE LAS CATEGORIAS

        holder.textViewName.text = product.name
        holder.textViewCounter.text = "${product.quantity}"
        holder.textViewPrice.text = "${product.price * product.quantity!!}"
        Glide.with(context).load(product.image1).into(holder.imageViewProduct)

        holder.imageViewAdd.setOnClickListener { addItem(product, holder) }
        holder.imageViewRemove.setOnClickListener { removeItem(product, holder) }
        holder.imageViewDelete.setOnClickListener { deleteItem(position) }
//        holder.itemView.setOnClickListener { goToDetail(product) }
    }

    private fun getTotal(): Double =
        products.sumByDouble { p -> (p.quantity ?: 0) * p.price }

    private fun getIndexOf(idProduct: String): Int {
        var pos = 0

        for (p in products) {
            if (p.id == idProduct) {
                return pos
            }
            pos++
        }

        return -1
    }

    private fun deleteItem(position: Int) {
        products.removeAt(position)
        notifyItemRemoved(position)
        notifyItemRangeRemoved(position, products.size)
        sharedPref.save("order", products)
        (context as ClientShoppingBagActivity).setTotal(getTotal())
    }


    private fun addItem(product: Product, holder: ShoppingBagViewHolder) {

        val index = getIndexOf(product.id!!)
        product.quantity = product.quantity!! + 1
        products[index].quantity = product.quantity

        holder.textViewCounter.text = "${product.quantity}"
        holder.textViewPrice.text = "${product.quantity!! * product.price}$"

        sharedPref.save("order", products)
        (context as ClientShoppingBagActivity).setTotal(getTotal())
    }

    private fun removeItem(product: Product, holder: ShoppingBagViewHolder) {

        if (product.quantity!! > 1) {

            val index = getIndexOf(product.id!!)
            product.quantity = product.quantity!! - 1
            products[index].quantity = product.quantity

            holder.textViewCounter.text = "${product.quantity}"
            holder.textViewPrice.text = "${product.quantity!! * product.price}$"

            sharedPref.save("order", products)
            (context as ClientShoppingBagActivity).setTotal(getTotal())

        }

    }

    private fun goToDetail(product: Product) {
        val i = Intent(context, ClientProductsDetailActivity::class.java)
        i.putExtra("product", product.toJson())
        context.startActivity(i)
    }

    class ShoppingBagViewHolder(view: View): RecyclerView.ViewHolder(view) {

        val textViewName: TextView
        val textViewPrice: TextView
        val textViewCounter: TextView
        val imageViewProduct: ImageView
        val imageViewAdd: ImageView
        val imageViewRemove: ImageView
        val imageViewDelete: ImageView

        init {
            textViewName = view.findViewById(R.id.textview_name)
            textViewPrice = view.findViewById(R.id.textview_price)
            textViewCounter = view.findViewById(R.id.textview_counter)
            imageViewProduct = view.findViewById(R.id.imageview_product)
            imageViewAdd = view.findViewById(R.id.imageview_add)
            imageViewRemove = view.findViewById(R.id.imageview_remove)
            imageViewDelete = view.findViewById(R.id.imageview_delete)
        }

    }
BLADERVAN GAMER
  • 21
  • 1
  • 1
  • 5
  • It's the exact same problem man - you're trying to multiply ``price`` by ``null`` again. And don't post screenshots, you've cut off the most important part (that tells you where the error is) - I only know because it's the ``quantity!!`` thing again – cactustictacs May 17 '22 at 01:33
  • yes bro I just took into account, I already solved that part and I would like to thank you – BLADERVAN GAMER May 17 '22 at 01:57
  • una pregunta como haria para operar en este caso, ya que me sale el mismo error y creo que es lo ultimo que me toca arreg ****productPrice = product?.price!! * product?.quantity!!**** – BLADERVAN GAMER May 17 '22 at 02:02
  • el problema es que no es posible multiplicar por *null*, y `quantity` puede ser null. Pues primero hay que verificar que no es null (`if (product.quantity != null)`) o usar el "elvis" `?:` operador por proveer una alternativa valor (`(product.quantity ?: 0)`). Null safety es un concepto muy importante, tienes que entenderlo: https://kotlinlang.org/docs/null-safety.html (perdone por el español) – cactustictacs May 17 '22 at 18:22