Home > Software engineering >  Textview data is not being updated when called inside from function in ListView Adapter
Textview data is not being updated when called inside from function in ListView Adapter

Time:12-10

Textview data is not being updated when called inside from function in ListView Adapter. Please help in setting binding.tvQ.text

class CustomPizzaListAdapter (private val context: Context, private val pizzaItemList: ArrayList<PizzaItemList>) : BaseAdapter() {
    private lateinit var binding: CustomPizzaItemListLayoutBinding


    override fun getCount(): Int {
        return pizzaItemList.size
    }

    override fun getItem(position: Int): Any {
        return position
    }

    override fun getItemId(position: Int): Long {
        return position.toLong()
    }

    @SuppressLint("ViewHolder")
    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        binding = CustomPizzaItemListLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)

        val current = pizzaItemList[position]
        Picasso.get().load(current.img).into(binding.imgPizza)
        binding.tvPizzaTitle.setText(current.Name)
        binding.tvPizzaDesc.setText(current.Desc)
        setPrice(binding.rgSize.checkedRadioButtonId, position)

        val mPosition = position
        binding.rgSize.setOnCheckedChangeListener { group, checkedId ->
            setPrice(checkedId, mPosition)
        }

        binding.btnPlusQ.setOnClickListener {
            binding.tvQ.text = (binding.tvQ.text.toString().toInt()   1).toString()
            Toast.makeText(context, binding.tvQ.text, Toast.LENGTH_LONG).show()
            setPrice(binding.rgSize.checkedRadioButtonId, mPosition)
        }

        binding.btnMinusQ.setOnClickListener {
            if(binding.tvQ.text.toString().toInt() > 0){
                binding.tvQ.text = (binding.tvQ.text.toString().toInt() - 1).toString()
                Toast.makeText(context, binding.tvQ.text, Toast.LENGTH_LONG).show()
                setPrice(binding.rgSize.checkedRadioButtonId, mPosition)
            }
        }

        return binding.root
    }

    private fun setPrice(checkedId: Int, position: Int) {
        val current = pizzaItemList[position]
        val price: Float
        when (checkedId) {
            binding.rgSmall.id -> {
                price = binding.tvQ.text.toString().toInt() * current.smPrice!!
                binding.tvPrice.text = "Price Small $$price"
                Toast.makeText(context, "Price Small $price", Toast.LENGTH_SHORT).show()
            }
            binding.rgMedium.id -> {
                price = binding.tvQ.text.toString().toInt() * current.mPrice!!
                binding.tvPrice.text = "Price Medium $$price"
                Toast.makeText(context, "Price Medium $price", Toast.LENGTH_SHORT).show()
            }
            binding.rgLarge.id -> {
                price = binding.tvQ.text.toString().toInt() * current.lgPrice!!
                binding.tvPrice.text = "Price Large $$price"
                Toast.makeText(context, "Price Large $price", Toast.LENGTH_SHORT).show()
            }
            else -> {
                Toast.makeText(context,"Wrong",Toast.LENGTH_LONG).show()
            }
        }
    }
}

When i try to gettext from textview it returns right updated data of textview in toast but the toast is not being updated. Tried searching how to update view but nothing worked.

CodePudding user response:

You should not have this binding property:

private lateinit var binding: CustomPizzaItemListLayoutBinding

You are setting it every time getView() is called, so it will always be the binding of the view that most recently scrolled onto the screen or is about to scroll onto the screen. Every view in the list will be updating the views in this latest binding when they are clicked.

Instead, make the binding another parameter of your setPrice function. Keep binding as a local variable in getView(), not a property.

You should also be using convertView when it's not null so your views can be recycled. This helps keep animation smooth while scrolling. So change your code to the following:

override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
    val binding = if (convertView == null) {
        CustomPizzaItemListLayoutBinding.inflate(LayoutInflater.from(parent.context), parent, false)
    } else {
        CustomPizzaItemListLayoutBinding.bind(convertView)
    }

    val current = pizzaItemList[position]
    Picasso.get().load(current.img).into(binding.imgPizza)
    binding.tvPizzaTitle.setText(current.Name)
    binding.tvPizzaDesc.setText(current.Desc)
    setPrice(binding.rgSize.checkedRadioButtonId, position, binding)

    binding.rgSize.setOnCheckedChangeListener { group, checkedId ->
        setPrice(checkedId, position, binding)
    }

    binding.btnPlusQ.setOnClickListener {
        binding.tvQ.text = (binding.tvQ.text.toString().toInt()   1).toString()
        Toast.makeText(context, binding.tvQ.text, Toast.LENGTH_LONG).show()
        setPrice(binding.rgSize.checkedRadioButtonId, position, binding)
    }

    binding.btnMinusQ.setOnClickListener {
        if(binding.tvQ.text.toString().toInt() > 0){
            binding.tvQ.text = (binding.tvQ.text.toString().toInt() - 1).toString()
            Toast.makeText(context, binding.tvQ.text, Toast.LENGTH_LONG).show()
            setPrice(binding.rgSize.checkedRadioButtonId, position, binding)
        }
    }

    return binding.root
}
private fun setPrice(checkedId: Int, position: Int, binding: CustomPizzaItemListLayoutBinding) {
    //...
}

By the way, I don't know where your override fun getItem(position: Int): Any function comes from. It's not part of the Android BaseAdapter class. But it looks like it's doing the wrong thing. Shouldn't it be returning a PizzaItemList item, not the position that's passed in?

  • Related