I know how to use ViewBinding to get the Button View object on Android Studio. But, I am curious about the best way to code setOnclickListerner on my Android App. In my case, I wrote my Kotlin code as below:
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnCameraCTA.setOnClickListener(this::openCamera)
binding.btnHeroesCTA.setOnClickListener(this::openHeroesApp)
binding.btnMoviesCTA.setOnClickListener(this::openMoviesApp)
}
private fun openCamera(view: View?) {
val isCameraFeatureExist = checkCamera()
if (isCameraFeatureExist) {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivity(takePictureIntent)
} else {
Toast.makeText(view?.context, "Your device doesn't have any camera", Toast.LENGTH_SHORT).show()
}
}
private fun checkCamera(): Boolean {
return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
}
private fun openHeroesApp(view: View?) {
val heroesIntent = Intent(view?.context, HeroesActivity::class.java)
startActivity(heroesIntent)
}
private fun openMoviesApp(view: View?) {
val moviesIntent = Intent(view?.context, MoviesActivity::class.java)
startActivity(moviesIntent)
}
}
But, we also can write those codes using View.OnClickListener with when expression as below:
class MainActivity : AppCompatActivity(), View.OnClickListener {
private lateinit var binding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.btnCameraCTA.setOnClickListener(this)
binding.btnHeroesCTA.setOnClickListener(this)
binding.btnMoviesCTA.setOnClickListener(this)
}
private fun checkCamera(): Boolean {
return packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)
}
override fun onClick(v: View?) {
when (v?.id) {
R.id.btnCameraCTA -> {
val isCameraFeatureExist = checkCamera()
if (isCameraFeatureExist) {
val takePictureIntent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
startActivity(takePictureIntent)
} else {
Toast.makeText(this@MainActivity, "Your device doesn't have any camera", Toast.LENGTH_SHORT).show()
}
}
R.id.btnHeroesCTA -> {
val heroesIntent = Intent(this@MainActivity, HeroesActivity::class.java)
startActivity(heroesIntent)
}
R.id.btnMoviesCTA -> {
val moviesIntent = Intent(this@MainActivity, MoviesActivity::class.java)
startActivity(moviesIntent)
}
}
}
}
Can anybody tell me which one is the better way? and why is that? Thank you
CodePudding user response:
There is no big differences between these two. In fact they both implement View.OnClickListener
interface. In your first code, take this for example:
binding.btnCameraCTA.setOnClickListener(this::openCamera)
View.OnClickListener
interface has setOnClickListener
method which gets v: View?
as input and returns Unit
. As your this::openCamera
method has exact same input and output as setOnClickListener
method, you can use it instead of an object that implements it.
It means deciding to use which one, will be based on your own preferences and code styles.
CodePudding user response:
I think using separate functions is more appropriate in terms of code readability. I prefer the first one. Besides, using MVVM pattern and two-way data binding will reduce your code complexity. You may want to look at the links below in order.
Good Luck!
https://developer.android.com/jetpack/guide https://developer.android.com/topic/libraries/architecture/viewmodel https://developer.android.com/topic/libraries/data-binding/two-way