scope of a variable - java

How can I get the value of a method parameter "myInteger" in this code.
public void myMethod(int myInteger) {
View.OnClickListener myClearHandler = new View.OnClickListener() {
public void onClick(View v) {
//***How can I get the value of "myInteger" here?***
}
};
}

Assuming you're just trying to read it, you just need to make it final:
public void myMethod(final int myInteger) {
View.OnClickListener myClearHandler = new View.OnClickListener() {
public void onClick(View v) {
int foo = myInteger;
}
};
}
In Java, only final parameters and local variables can be accessed within anonymous inner classes.

I am guessing the language should support closures and all you need to do in this case is use the variable myInteger in your onClick listener and you should be fine.. This works in fine in many languages I am not sure about Java though.
public void myMethod(final int myInteger) {
View.OnClickListener myClearHandler = new View.OnClickListener() {
public void onClick(View v) {
int myInteger = myInteger * 100;
}
};
}
AS posted by John Skeet: the final keyword is important here.

You Cannot refer to a non-final variable myInteger inside an inner class
defined in a different method
You might be getting this error, so for that you have to declare it as final like this
final int myInteger

Related

Variable is accessed from within inner class inside another inner class

I'm having an inner class within another inner class, in which I'm trying to use final variable outside both inner classes. Here's the code:
final View v = inflater.inflate(R.layout.fragment_floor_plan, container, false); //final variable
final Button button0 = v.findViewById(R.id.button21);
button0.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final PhotoView photoView = v.findViewById(R.id.photo_view); //works fine here
photoView.setAlpha(0f);
System.out.println(photoView.isZoomable());
System.out.println(photoView.VISIBLE);
photoView1.animate().alpha(0f).setDuration(250);
photoView.animate().alpha(1f).setDuration(250);
photoView.bringToFront();
photoView.setOnScaleChangeListener(new OnScaleChangedListener() {
#Override
public void onScaleChange(float scaleFactor, float focusX, float focusY) {
if (photoView.getScale() <= photoView.getMinimumScale() + 0.1f) {
LinearLayout linearLayout = v.findViewById(R.id.linearLayout); //doesn't work here
linearLayout.bringToFront();
}
}
}
}
});
How to get it to work inside OnScaleChangedListener?
Now that I look at it, your problem might be that the View v is being passed as a parameter to the onClick method of the OnClickListener, and the code below might be trying to access instead of your top-level View variable.
My recommendation would be to refactor your variable names so that you are referring to the correct variable. If the passed-in View is the one you actually want to use, it should be declared as final in the method signature:
public void onClick(final View v) {
If the variable in the enclosing scope of the nested anonymous class is declared final or effectively final, you should just be able to access it from within any level of nested inner anonymous classes.
To ensure this I made a little example and tried it out myself:
import java.util.function.*;
public class Main {
public static void main(String[] args) {
final int test = 11;
Runnable runnable = new Runnable() {
public void run() {
Runnable runnable = new Runnable() {
public void run() {
System.out.println(test);
}
};
runnable.run();
}
};
runnable.run();
}
}
As you can see the second runnable is nested within another runnable, and running the code accesses the integer test and prints it as it should.

Variable 'i' is accessed from within inner class, needs to be declared final

I'm trying to send value to another activity intent.putExtra("doctor",String.valueOf(items.get(i)));
but it gives error. That's "Variable 'i' is accessed from within inner class, needs to be declared final". The code is running in the for loop so I can't give final value because it's iterator.
How can we solve it?
Part of code
for (int i = 0; i < c; i++) {
items.add(options[i]);
spinnerDialog=new SpinnerDialog(NewActivity.this,items,"Search","Close");// With No Animation
spinnerDialog=new SpinnerDialog(NewActivity.this,items,"Search",R.style.DialogAnimations_SmileWindow,"Close");// With Animation
spinnerDialog.setCancellable(true); // for cancellable
spinnerDialog.setShowKeyboard(false);// for open keyboard by default
spinnerDialog.bindOnSpinerListener(new OnSpinerItemClick() {
#Override
public void onClick(String item, int position) {
Intent intent = new Intent(NewActivity.this,PrescriptionActivity.class);
intent.putExtra("doctor",String.valueOf(items.get(i)));
NewActivity.this.startActivity(intent);
}
});
findViewById(R.id.show).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
spinnerDialog.showSpinerDialog();
}
});
}
The variables used in the anonymous classes implementations (or lambda expressions) must be effectively final, or else the undefined behavior would happen.
I suppose that you want to handle on click action the item at the position obtained from the method using the int position, not from the outer loop. Do the following:
spinnerDialog.bindOnSpinerListener(new OnSpinerItemClick() {
#Override
public void onClick(String item, int position) {
Intent intent = new Intent(NewActivity.this,PrescriptionActivity.class);
intent.putExtra("doctor",String.valueOf(items.get(position))); // here
NewActivity.this.startActivity(intent);
}
});

using variable in another class

Iam creating an android app that has many classes inside the main Java package. The MainActivity class implements Button onClick Listener and do some coding with assigning values to variable x inside the method when button is clicked, now I have class#2 use the same variable x in some other coding. I want the onClick method when it is called to send the variable x value to class#2
MainActivityCalss {
hi.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
int x = 1;
}
});
}
Class2 {
Method() {
y = x + 1;
}
}
Creating a new Java class to hold all global variables is a very good idea.
public class GlovalVariable{
public String x;
public int y;
// Generate getter/setter methods for all the variables defined here.
}
By creating this you will manage a variables very easily. If you want to rename the variable which is used through out the class, this method will make it very easy.
Define "x" in other class and set it using setter method, and where ever you get it through getter.
public class value {
public static int x;
public static void set(int value) {
x = value;
}
public static int get() {
return x;
}
}
And in onclicklistener of mainactivity.
hi.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
value.set(1);
}
});
In class2
Method() {
y = value.get()+1;
}

access to variable within inner class in Android

i'm trying to generate a set of buttons whith data from the database. But on click i'm facing the following eror
Variable 'i' is accessed from within the inner class, needs to be declared final,
Since the value of i is changes as loop goes on i cannot set it as final,
footnoteBtns[i].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
footnote = myDbHelper.getFootnote(chapterNumber, translationList.get(i).get("transNo"));
Popup();
}
});
You could add an additional variable that is final and set to i:
final int j = i;
And then use that one inside the overridden onClick method.
The reason why you have to do this, is that onClick is called at another point of time and not directly inside the for loop -> asynchronous. Therefore, you need to make sure that it is clear which value should be used in that later called method. That's why the variable needs to be final.
In general it very weird approach to put setOnClickListener in a loop, but in your case you can solve it with following code:
for( int i = 0; i < N; i++) {
final int p = i;
footnoteBtns[p].setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
footnote = myDbHelper.getFootnote(chapterNumber, translationList.get(p).get("transNo"));
popup();
}
});
}
Try this in place of current code:
class MyOnClickListener extends View.OnClickListener {
private int myi;
public MyOnClickListener(int i) {
myi = i;
}
#Override
public void onClick(View v) {
footnote = myDbHelper.getFootnote(chapterNumber, translationList.get(myi).get("transNo"));
Popup();
}
};
footnoteBtns[i].setOnClickListener(new MyOnClickListener(i));

Access variables from onclicklistener android

The the problem is how to use variables inside onclick method, example:
String number = "555 12345";
callbutton.setOnClickListener(new onClickListener(){
#Override
public void onClick(View view) {
Intent phoneCallIntent = new Intent(Intent.ACTION_CALL);
phoneCallIntent.setData(Uri.parse(number));
startActivity(phoneCallIntent);
}
});
I tried this solution and failed. Making custom class for onclicklistener.
String number = "555 12345";
bt.setOnClickListener(new CallButtonClickListener(number){});
public class CallButtonClickListener implements OnClickListener
{
String num;
public CallButtonClickListener(String number) {
this.num = number;
}
#Override
public void onClick(View v)
{
Intent phoneCallIntent = new Intent(Intent.ACTION_CALL);
phoneCallIntent.setData(Uri.parse(num));
startActivity(phoneCallIntent);
}
};
}
How can I pass the string to onclick? I can't define the string inside onclick because I have to use it multiple times.
Make it final:
final String number = "555 12345";
Also the second solution seems alright also as you're passing a copy of the reference. What't wrong with it?
Use final variable or declare them outside onCreate() method

Categories

Resources