I'm developing a solution that passes the one activity for other activity after the user clicks in an ImageButton. I have 6 images and all images
are having the same onClick event and I need to distinguish different ImageButton's clicks which is which for passing for the second activity.
I tried the solution below, but the line with idImageButton.tag.toString() doesn't work.
file.kt
fun onclickImage(view: View){
val idImageButton:ImageButton = view as ImageButton
val pokemonName:String = idImageButton.tag.toString()
val myIntent = Intent(this, Details::class.java)
myIntent.putExtra("pokemon", pokemonName)
startActivity(myIntent)
}
You can get view id with casting to ImageButton
when(view.id) {
R.id.btnFirst -> {}
R.id.btnSecond -> {}
//so on
}
val button:ImageButton
val id = button.id
You have to checked the id of the view to distinguish them. For Example if the id of the ImageButton for which you want to move to the second activity is pokemon, then try like this.
fun onclickImage(view: View) {
if(view.id == R.id.pokemon) {
val myIntent = Intent(this, Details::class.java)
myIntent.putExtra("pokemon", "Pokemon")
startActivity(myIntent)
}
}
If you also want to do it by tag you have to set tag in either xml or code. Then you can check it with tag
<ImageButton
android:id="#+id/pokemon"
android:tag="Pokemon"
android:onClick="onclickImage"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Then check tag and take decision.
fun onclickImage(view: View) {
val pokemonName = view.tag.toString()
if(pokemonName.equals("Pokemon", true)) {
val myIntent = Intent(this, Details::class.java)
myIntent.putExtra("pokemon", pokemonName)
startActivity(myIntent)
}
}
Related
I tried to show a random imageView out of 2(one,two) with this
binding.imageView.setImageResource(oneandtwo[random.nextInt(oneandtwo.size)]) it works fine
and
i wanted to increase score when i clicked on imageView
but score increases independent to that, sometimes increases when i clicked on imageView2 and sometimes imageView, i want to increase score when i only clicked on imageView. i couldnt figure out. Thanks in advance.
var score = 0
val oneandtwo: IntArray = intArrayOf(
R.drawable.ic_baseline_looks_one_24,
R.drawable.ic_baseline_looks_two_24
)
binding.imageView.setOnClickListener{
val random = Random
binding.imageView.setImageResource(oneandtwo[random.nextInt(oneandtwo.size)])
if (oneandtwo[random.nextInt(oneandtwo.size)]==(R.drawable.ic_baseline_looks_one_24)){
score++
binding.textView.text = score.toString()
}
}
The number you gave in the image and the number you checked in the if block may not match and will not give the result you want. If you change code like this. Probably your problem will be solved.
binding.imageView.setOnClickListener{
val random = Random().nextInt(oneandtwo.size)
binding.imageView.setImageResource(oneandtwo[random])
if (oneandtwo[random]==(R.drawable.ic_baseline_looks_one_24)){
score++
binding.textView.text = score.toString()
}
}
What you are doing is checking the resourceId of the newly generated image, not the one you just clicked. That's why it not giving the result you want ,i.e, increment on the click of imageView and not on click of imageView2. Try below code. it should work
var score = 0
val oneandtwo: IntArray = intArrayOf(R.drawable.ic_baseline_looks_one_24,R.drawable.ic_baseline_looks_two_24)
/*Initalize the initial image and tag either here or in xml file*/
val random = Random().nextInt(oneandtwo.size)
binding.imageView.setImageResource(oneandtwo[random])
binding.imageView.Tag = oneandtwo[random]
binding.imageView.setOnClickListener{
val imageTag = binding.imageView.Tag
if (imageTag == (R.drawable.ic_baseline_looks_one_24)) {
score++
binding.textView.text = score.toString()
}
val random = Random().nextInt(oneandtwo.size)
binding.imageView.setImageResource(oneandtwo[random])
binding.imageView.Tag = oneandtwo[random]
}
You've got two problems that both the answers cover - if clicking a particular image is meant to give you points, you have to check the image before you change it. And if you're using random items, you need to pick one and keep a reference to it. This:
binding.imageView.setImageResource(oneandtwo[random.nextInt(oneandtwo.size)])
if (oneandtwo[random.nextInt(oneandtwo.size)]==(R.drawable.ic_baseline_looks_one_24))
picks two completely independent numbers which may not match - and they're supposed to be referencing the same item, right? Get your random thing once, use it twice
RahulK's answer should work but here's another way you could do it, with an explicit listener object so you can throw a state variable in there:
binding.imageView.setOnClickListener(object : View.OnClickListener {
// keep track of whether the current image adds to the score when clicked
var givesPoints = false
override fun onClick(view: View) {
// first, we just got clicked, so add to the score if appropriate
if (givesPoints) score++
// you can just call random() on a collection to get a random element from it
val resId = oneAndTwo.random()
// set the image - might be better to do (view as ImageView).setImageResource
// so it sets it on -whatever was clicked- so it's easier to reuse
binding.imageView.setImageResource(resId)
// now set whether this new image gives points or not
givesPoints = resId == R.drawable.ic_baseline_looks_one_24
}
})
So this way, every time you set a new image, the listener knows whether to give points for it next time it's clicked
I don't know how you have this set up, you're only initialising things when the image is clicked so if you need to set them up beforehand (so you can have an image displayed that you an click for points) you probably want everything in a separate function you can call when clicked and during setup:
/** Assigns a random picture to this ImageView - returns true if it's a point-scoring pic */
fun assignRandomPic(imageView: Imageview): Boolean {
val resId = oneAndTwo.random()
imageView.setImageResource(resId)
return resId == R.drawable.ic_baseline_looks_one_24
}
// set an initial image, storing whether it scores points
val scoreMe = assignRandomPic(binding.imageView)
binding.imageView.setOnClickListener(object : View.OnClickListener {
// initialise this as appropriate for the image we just set up
var givesPoints = scoreMe
override fun onClick(view: View) {
if (givesPoints) score++
// set a new pic and store its point-scoring state
givesPoints = assignRandomPic(view as ImageView)
}
})
or you could just do var givesPoints = assignRandomPic(binding.imageView) and init the image inside the click listener, whatever feels better
I currently want to have a button that when I press it another button flashes as if it has been pressed at the same time and activates the function of the other button. My current code is as such:
fun onTwo(view: View) {
button1.callOnClick()
button1.isPressed = true
}
However the issue I am facing is that it freezes button1 as if it is pressed until it is pressed again. Anyone have a solution for this?
You could add listener in one of the button to check for clicks and then use that event to trigger click event in another button, like this:
val button1 = findViewById(R.id.btn1ID) as Button
button1.setOnClickListener {
val button2 = findViewById(R.id.btn2ID) as Button
button2.performClick()
}
Replace R.id.btn1ID and R.id.btn2ID with their respective id(a).
Reference: performClick()
You could also create a utility function to use it without making redundant variables like this:
#Suppress("UNCHECKED_CAST")
fun Activity.findButtonById(#IdRes res : Int) : Button =
findViewById(res) as Button
// and then in your create method of activity:
findButtonById(R.id.btn1ID).setOnClickListener {
findButtonById(R.id.btn2ID).performClick()
}
Try performClick() method like below:
fun onTwo(view: View)
{
button1.performClick()
}
I ended up fixing this issue using coroutines in the end as such:
fun onTwo(view: View){
GlobalScope.async{
delay(100)
button1.isPressed = false
GlobalScope.cancel()
}
button1.setPressed(true)
button1.performClick()
}
I have a simple button in my recyclerview, when clicked the first time it should make the text editable, when clicked the second time, it should confirm the change. The problem I'm having is that I have the two onClickListeners set up, but they refer to each other, and the bottom one can always resolve the top one, but the top one can't resolve the bottom one.
Recyclerview: bindIngredient
fun bindIngredient(ingredient: ListIngredientsQuery.Item, clickListener: RecyclerViewClickListener) {
val ocl1 = View.OnClickListener{
//Text Editable
view.ingEditText.setText(view.ingNameTV.text.toString())
view.ingNameTV.visibility = View.GONE
view.ingEditText.visibility = View.VISIBLE
view.ingEditButton.text = "Confirm"
view.ingEditButton.setOnClickListener(ocl2)
}
var ocl2 = View.OnClickListener {
//Text Not Editable
view.ingNameTV.text = view.ingEditText.text
view.ingEditText.visibility = View.GONE
view.ingNameTV.visibility = View.VISIBLE
view.ingEditButton.setOnClickListener(ocl1)
clickListener.onConfirmSelect(ingredient)
}
this.ingredient = ingredient
view.ingNameTV.text = ingredient.name()
view.ingEditButton.setOnClickListener(ocl1)
view.veganSpinner.setSelection(Vegan.valueOf(ingredient.vegan().toString()).ordinal, false)
view.gfSpinner.setSelection(GlutenFree.valueOf(ingredient.glutenfree().toString()).ordinal, false)
}
In this example the line
view.ingEditButton.setOnClickListener(ocl2)
errors because ocl2 is unresolved. If I switch the order of the two onClickListeners being declared and initialized, the line
view.ingEditButton.setOnClickListener(ocl1)
errors because ocl1 is resolved. I take this to mean that it won't look further down to find what it needs, it'll only rely on objects that have already been initialized.
Is there a way to fix this? Is there a better way to do this? I'm tempted to just put two buttons in the same spot, give them each their own onclicklistener and swap their visibility, but this seems like a waste of resources.
You need to declare your objects before you use them.
fun bindIngredient(ingredient: ListIngredientsQuery.Item, clickListener: RecyclerViewClickListener) {
val ocl1: View.OnClickListener
val ocl2: View.OnClickListener
ocl1 = View.OnClickListener{
//Text Editable
view.ingEditText.setText(view.ingNameTV.text.toString())
view.ingNameTV.visibility = View.GONE
view.ingEditText.visibility = View.VISIBLE
view.ingEditButton.text = "Confirm"
view.ingEditButton.setOnClickListener(ocl2)
}
ocl2 = View.OnClickListener {
//Text Not Editable
view.ingNameTV.text = view.ingEditText.text
view.ingEditText.visibility = View.GONE
view.ingNameTV.visibility = View.VISIBLE
view.ingEditButton.setOnClickListener(ocl1)
clickListener.onConfirmSelect(ingredient)
}
this.ingredient = ingredient
view.ingNameTV.text = ingredient.name()
view.ingEditButton.setOnClickListener(ocl1)
view.veganSpinner.setSelection(Vegan.valueOf(ingredient.vegan().toString()).ordinal, false)
view.gfSpinner.setSelection(GlutenFree.valueOf(ingredient.glutenfree().toString()).ordinal, false)
}
However, it would be better if you just used one OnClickListener. You can simply save which state you are in, and when the button is clicked, you just check which state you are in, perform your action, and then change the state. This way you don't have to worry about switching your listeners, which can get messy.
I'm trying to use Kotlin and Anko's DSL to create an alert dialog that lets a user pick an image, and then loads it into an ImageView. Right now I'm just trying go get the ImageView to work, so I have the button click to load a preselected image from a URL using Picasso.
When I click the button in the alert dialog, I get this error:
kotlin.TypeCastException: null cannot be cast to non-null type
android.widget.ImageView
I'm guessing for some reason the ImageView isn't being loaded through findViewById. Does anyone know why this might be? I'm guessing Anko's DSL has some weird behavior I don't know about.
fab.setOnClickListener { view ->
alert {
title = "New Post"
customView {
verticalLayout {
val subject = editText {
hint = "Subject"
}
imageView {
id = R.id.picked_image
}
linearLayout {
gravity = Gravity.CENTER
button("Choose Photo") {
onClick {
Picasso.with(this#MainActivity)
.load("http://SomeUrl/image.jpg")
.into(findViewById(R.id.picked_image) as ImageView)
}
}
button("Choose Image") {}
}
positiveButton("Post") { }
negativeButton("Cancel") {}
}
}
}.show()
You can get a reference to the ImageView like this and avoid having to deal with IDs altogether:
val iv = imageView()
...
onClick {
Picasso.with(this#MainActivity)
.load("http://SomeUrl/image.jpg")
.into(iv)
}
...
I'm having a Floating Action Button listener with AlertDiaolog inside. And I want to use my buttons from XML. And if I want to write an onClickListener() for them.
So in Java I have to initialize it like:
butAdd = (Button)dialog.findViewById(R.id.btn_add)
butAdd.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Some code
}
But when I trying to use:
var butAdd = dialog?.findViewById(R.id.btn_add) as Button;
in Kotlin it's incorrect
So any suggestions how to fix it? What'is wrong with listeners?
Here is my code of Floating Action Button:
fab?.setOnClickListener {
diaolg = AlertDialog.Builder(this#Cards)
val linearlayout = getLayoutInflater().inflate(R.layout.add_password, null)
diaolg?.setView(linearlayout)
?.setTitle("Add a new password")
?.setCancelable(true)
var login = findViewById(R.id.login) as EditText
var password = findViewById(R.id.password) as EditText
var title = findViewById(R.id.title) as EditText
var butAdd = diaolg?.findViewById(R.id.btn_add) as Button
var butCancel = diaolg?.findViewById(R.id.btn_cancel) as Button
butAdd.setOnClickListener(View.OnClickListener {
fun onClick(v:View){
}
})
butCancel.setOnClickListener(View.OnClickListener {
fun onClick(v:View){
}
})
diaolg?.create()
diaolg?.show()
}
please find id by using
var butAdd = linearlayout.findViewById<Button>(R.id.btn_add) as Button;
Whatever class you're in has no findViewById method.
You have to findViewById on the inflated layout, so:
var login = linearLayout.findViewById(R.id.login) as EditText
Also, I dont think you need to have the ? on the dialog, it cannot be null.
Also, I would make your views vals instead of vars.
import this line in your Activity
<Button
android:id="#+id/btn_submit"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="submit" />
import this line in your Activity
// Using R.layout.activity_main from the main source set
//activity_main is your layout file name
import kotlinx.android.synthetic.main.activity_main.*
btn_submit.setOnClickListener {
Toast.makeText(this, "hello", Toast.LENGTH_LONG).show();
}
Its work for me.