Search code examples
androidkotlinandroid-viewbinding

Android access view binding val outside onCreate activity


I have an activity that has a button. On the button click I want to update text in text view. I want to use ViewBinding instead of the normal findViewById

This is how I created the val binding

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    val binding = ActivityMainBinding.inflate(layoutInflater);
    setContentView(binding.root)

    binding.btnRoll.setOnClickListener {
        rollDice()
    }
}

Now in rollDice I want to update the text view but I'm not able to access binding which make sense because its scope is limited to onCreate() , so what is the best practice for this?

  private fun rollDice() {
       val random = Random().nextInt(6) + 1
       binding.txt_random.setText("random")
    }

Solution

  • You have two options.

    1. Store in a property

    Since the inflated content of Activity is fully bound to it's lifecycle, it's safe to keep the reference as a property

    class MainActivity : AppCompatActivity() {
      lateinit var binding: ActivityMainBinding
    
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        binding = ActivityMainBinding.inflate(layoutInflater);
        setContentView(binding.root)
    
        binding.btnRoll.setOnClickListener {
          rollDice()
        }
      }
    
      private fun rollDice() {
        val random = Random().nextInt(6) + 1
        binding.txt_random.setText("random")
      }
    }
    

    2. Pass the binding to the methods

    That's what I usually do, it avoids creating a property where it's not really a necessity

    class MainActivity : AppCompatActivity() {
    
      override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        
        val binding = ActivityMainBinding.inflate(layoutInflater);
        setContentView(binding.root)
    
        binding.btnRoll.setOnClickListener {
          rollDice(binding)
        }
      }
    
      private fun rollDice(binding: ActivityMainBinding) {
        val random = Random().nextInt(6) + 1
        binding.txt_random.setText("random")
      }
    }
    
    

    Both options are valid ways to make the binding visible to Activities methods.