MRefaat
MRefaat

Reputation: 535

Cannot refer to a non-final variable l inside an inner class defined in a different method

I'm trying to set an OnClickListener to some elements in my Android app, these elements are dynamically defined and are not given ids, but they are put in a LinearLayouts which exists in an List of LinearLayouts, so I set the OnClickListener as follows:

    List<LinearLayout> inner_ver = setElemets(1);

       for (LinearLayout l: inner_ver){
                l.getChildAt(0).setOnClickListener(new OnClickListener() { // here's the syntax error
                @Override
                public void onClick(View v) {
                    l.getChildAt(1).setBackgroundResource(R.drawable.home_curtopen);
                }
            });
        }

but I got the syntax error mentioned in the title with l and I can't just declare it as final cause then it assigns the changes only to the last element in the List.

Upvotes: 1

Views: 271

Answers (3)

zapl
zapl

Reputation: 63955

You could add final to your for loop

List<LinearLayout> inner_ver = setElemets(1);

   for (final LinearLayout l: inner_ver){
            l.getChildAt(0).setOnClickListener(new OnClickListener() { // here's the syntax error
            @Override
            public void onClick(View v) {
                l.getChildAt(1).setBackgroundResource(R.drawable.home_curtopen);
            }
        });
    }

Why for(final Type name : Iterable) works is explained in

How does "final int i" work inside of a Java for loop?

Upvotes: 1

FD_
FD_

Reputation: 12919

You could also create your own OnClickListener class:

class MyOnClickListener implements OnClickListener{
    private LinearLayout layout;

    public MyOnClickListener(LinearLayout layout){
        this.layout = layout;
    }

    @Override
    public void onClick(View v) {
        layout.getChildAt(1).setBackgroundResource(R.drawable.home_curtopen);
    }

}

Then change your loop to:

for (LinearLayout l: inner_ver){
    l.getChildAt(0).setOnClickListener(new MyOnClickListener(l));
}

Upvotes: 3

Greg Ennis
Greg Ennis

Reputation: 15379

Split into a separate method:

    for (LinearLayout l: inner_ver){
        assignListener(l);
    }

public void assignListener(final LinearLayout l) {
    l.getChildAt(0).setOnClickListener(new View.OnClickListener() { 
        @Override
        public void onClick(View v) {
            l.getChildAt(1).setBackgroundResource(R.drawable.home_curtopen);
        }
    });
}

Upvotes: 4

Related Questions