Nick Robertson
Nick Robertson

Reputation: 1047

non-final variable inside an inner class

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?

Upvotes: 4

Views: 1402

Answers (6)

Firstborn
Firstborn

Reputation: 71

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

detectLocationAndShowPopUp((ImageView) arg0);

Upvotes: 4

Emanuel Moecklin
Emanuel Moecklin

Reputation: 28866

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;
    }
});

Upvotes: 9

Andy
Andy

Reputation: 5228

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;
    }
}};

Upvotes: 1

micha
micha

Reputation: 49612

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;
    }
  }
}

Upvotes: 2

codeMagic
codeMagic

Reputation: 44571

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

Upvotes: 2

Swayam
Swayam

Reputation: 16364

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);
}

}

Upvotes: 2

Related Questions