4

I try to create dynamically a ImageView and I want to pass this imageView as a parameter to a method into the listener.

            ImageView imageView1 = new ImageView(LookActivity.this);

            imageView1.setOnTouchListener(new OnTouchListener() {

                    @Override
                    public boolean onTouch(View arg0, MotionEvent arg1) {
                        detectLocationAndShowPopUp(imageView1);
                        return true;
                    }
                })

But I'm taking the following error:
Cannot refer to a non-final variable imageView1 inside an inner class defined in a different method.

I don't want to declare the imageView as final. How can I overcome this problem?

Nick Robertson
  • 1,047
  • 4
  • 18
  • 41
  • http://stackoverflow.com/questions/1299837/cannot-refer-to-a-non-final-variable-inside-an-inner-class-defined-in-a-differen – Nermeen Feb 22 '13 at 16:01

6 Answers6

9

You can make a copy of imageView1 and then use the copy inside the listener:

ImageView imageView1 = new ImageView(LookActivity.this);
final ImageView imageView2 = imageView1;

imageView1.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {
        detectLocationAndShowPopUp(imageView2);
        return true;
    }
});

After Sam's comment I change my code to:

ImageView imageView1 = new ImageView(LookActivity.this);

imageView1.setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View view, MotionEvent event) {
        detectLocationAndShowPopUp((ImageView) view);
        return true;
    }
});
Emanuel Moecklin
  • 28,488
  • 11
  • 69
  • 85
  • 2
    This is a great general answer. But for those that don't know Android, `arg0` is a reference to `imageView1` simply cast it to an ImageView if necessary. – Sam Feb 22 '13 at 16:08
4

Since this is Android, arg0 will be your image when you touch it. Use:

detectLocationAndShowPopUp((ImageView) arg0);
Sam
  • 86,580
  • 20
  • 181
  • 179
Firstborn
  • 71
  • 2
  • 2
    Welcome to StackOverflow! I improved your answer a little by adding a code sample and using the markup tools. I also gave you an upvote since this answer is correct. You can improve your answer again with some of the advice in [ask] by clicking "[edit]". – Sam Feb 22 '13 at 16:19
  • Whoops! I meant to like to [answer]... :) – Sam Feb 22 '13 at 17:46
2

Create ImageView imageView1 as a global class variable.

And initialize it inside the function as you are doing, without declaring it again.

Something like

MyClass extends ...
{
....
ImageView imageView1;
.
.
.
.
.
myFucntion()
{
imageView1 = new ImageView(LookActivity.this);
}

}
Swayam
  • 16,294
  • 14
  • 64
  • 102
2

Don't define the ImageView in a method. Make it a member variable declared under your class definition

codeMagic
  • 44,549
  • 13
  • 77
  • 93
2

Your are using an anonymous class and not an inner class (like the title says). In anonymous classes you can only refer to final "variables".

If you don't want to add final to imageView and dont want to use another final variable you can use an inner class:

public class YourActivity extends ... {
  public void yourMethod() {
    ImageView imageView1 = new ImageView(LookActivity.this);
    imageView1.setOnTouchListener(new MyListener(imageView1));
  }

  private class MyListener extends OnTouchListener {
    private ImageView imageView;

    public MyListener(ImageView iv) {
      this.imageView = iv;
    }

    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {
     detectLocationAndShowPopUp(imageView);
     return true;
    }
  }
}
micha
  • 47,774
  • 16
  • 73
  • 80
1

Idea one: Use another final variable.

ImageView imageView1 = new ImageView(LookActivity.this);
final ImageView finalImageView = imageView1;
imageView1.setOnTouchListener(new OnTouchListener() {
  @Override
  public boolean onTouch(View arg0, MotionEvent arg1) {
    detectLocationAndShowPopUp(finalImageView);
    return true;
  }
})

Idea two: Use an anonymous subclass of ImageView, then use the ImageView.this reference.

ImageView imageView1 = new ImageView(LookActivity.this) {{
  setOnTouchListener(new OnTouchListener() {
    @Override
    public boolean onTouch(View arg0, MotionEvent arg1) {
      detectLocationAndShowPopUp(ImageView.this);
      return true;
    }
}};
Andy
  • 5,108
  • 3
  • 26
  • 37