2

I know the topic sounds like a dupplicate, but I am not trying to debug this issue here but to get around it.

What my program is supposed to do is : For every file there is in a folder, create a new button. If you click on this button, put in the intent extra the name of the folder you've just entered.

 File directory = new File(prefs.getString("path",null));
 File[] files = directory.listFiles();
        for (File file :files){
            if(file.isDirectory()) {
                buttons.add(new Button(this));
                Button button = buttons.get(buttons.size() - 1);
                String fileName = file.getName();

                button.setText(fileName);
                button.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View v) {
                        Intent intent = new Intent(currentActivity, EOChoiceActivity.class);
                        intent.putExtra("fileExtension",fileName);
                        startActivity(intent);
                    }
                });
                layout.addView(button);
            }
        }

Now the problem I have is that the "fileName" variable needs to be put in final, due to Java giving the pointer of the object and not the value itself. But if I do so, only the last fileName selected will be sent for any button.

Thomas
  • 337
  • 2
  • 8

2 Answers2

4

You can just go ahead and make fileName final. I know you think that this will cause problems, but it won't.

the "fileName" variable needs to be put in final, due to Java giving the pointer of the object and not the value itself. But if I do so, only the last fileName selected will be sent for any button.

On each iteration through the loop, you're declaring a different String instance. Each one will be final, but they will not be "shared" across loop iterations.

I made a tiny app that iterated over an array of Strings, doing something very similar to your code. Despite declaring my String as final, each button still toasts a different name when I click it.

for (int i = 0; i < names.length; i++) {
    final String name = names[i];

    Button button = new Button(this);
    button.setText(name);
    button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Toast.makeText(MainActivity.this, name, Toast.LENGTH_SHORT).show();
        }
    });

    root.addView(button);
}
Ben P.
  • 52,661
  • 6
  • 95
  • 123
  • I went with the idea that declaring a variable final does the same as making the variable global to the class as it was suggested in another topic similar, this is where I got confused. Thank you for your explanation. – Thomas Nov 10 '17 at 07:48
2

No need to declare fileName final.

Because you are setting fileName as text to Button. So use getText using v parameter of onClick to get file name on Button click.like

...
intent.putExtra("fileExtension",((Buttton)v).getText().toString());
...

Or you can also do it using setTag()/getTag() method's of button Button.

ρяσѕρєя K
  • 132,198
  • 53
  • 198
  • 213