views:

111

answers:

2

Hi I have a multiplechoice dialog on my activity. I have a boolean array to keep track of which items are selected from the dialog. So I want each time an item is clicked to make the corresponding place on my array true. The array is being created in the onCreateDialog before the return.

public Dialog onCreateDialog(int id) {
  userlistlocal=getuserlist(username);
  boolean[] usernamechecked=new boolean[userlistlocal.length/3];
  Arrays.fill(usernamechecked,false);         
  return new AlertDialog.Builder(Newevent.this)
        .setIcon(R.drawable.ic_menu_invite)
        .setTitle("Add People")
        .setMultiChoiceItems(userselectionlistlocal,
                null,new DialogInterface.OnMultiChoiceClickListener() {


                    public void onClick(DialogInterface dialog, int whichButton,
                            boolean isChecked) { 

                        /* User clicked on a check box do some stuff */
                     usernamechecked[whichButton]=isChecked;<-------HERE
                    }
                })
        .setPositiveButton("Ok", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {

                /* User clicked Yes so do some stuff */
            }
        })
        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int whichButton) {

                /* User clicked No so do some stuff */
            }
        })
       .create();

 }

But when I put in the onClick method my boolean array it says it has to be final(Cannot refer to a non-final variable usernamechecked inside an inner class defined in a different method). I dont know what to do

A: 

You cannot access your array if it is not declared final. But if it is declared final you have to consider, that you can't modificate it anymore.

A method to resolve this problem is to define the OnMultiChoiceClickListener not as an anonymous inner class. For example you could define it as a inner class in the same class or even as a separate class.

Roflcoptr
defining a variable final **does not** make it immutable. final means that the variable can only be assigned once, in the case of basic types (int,float,etc) this does mean the value can not change, in the case of a reference it means the reference can not be unbound and reassigned. Since usernamechecked is a reference to an array declaring it final means you can't change what object the variable references but the object the reference points to (an array in this case) can still have its contents changed.
Mark
You are right!I was the thinking the meaning final as it is for basic types.Indeed it works fine changing the values inside the array true and false know that I defined my boolean array final.Thanks alot. I come across more and more of scope problems as my project gets more complicated and my small java experience makes things pretty hard...
spagi
thats interesting, i wasn't expecting it to work with simply defining the method variable final, i assumed it would get garbage collected after the scope of onCreateDialog completed. Looks like the compiler maintains a reference to the variable inside the anonymous class automatically. Personally i would still store it as a class member somewhere, 6 months from now it would make it much easier to read and understand whats going on.
Mark
A: 

you defined usernamechecked inside the onCreateDialog method, it only exists inside the scope of this method. You should define it as a member of your activity class or of the inner class. Since its size is dependent on a call to getuserlist, which i assume is a method of your activity class, i would add it as a member of your activity class although this is up to you.

Define usernamechecked as a member of your activity class as:

private boolean usernamechecked[];

I'd also move

userlistlocal=getuserlist(username);
usernamechecked=new boolean[userlistlocal.length/3];
Arrays.fill(usernamechecked,false); 

to your onCreate Method (or some other initialization method) if possible as it looks like it has nothing to do with the dialog creation but this is just a style / maintainability issue.

Mark
If I define it as a member of the activity class without a size(which I dont know until I execute the getuserlist()) am I able to define its size after I run getuserlist()?This is the problem I have with all the arrays that await the getuserlist to return values, because until then I dont know the size that they should be.So I am forced to define them in the onCreate for example and other methods cant use them...Is there something I can do like define it first like you told me in the activity class and then inside the onCreate define its size?
spagi
yea thats exactly what i'm saying you should do. Notice that i changed the line "boolean[] usernamechecked=new boolean[userlistlocal.length/3];" to "userlistlocal=getuserlist(username);" so its not defining a new variable but rather assigning a new array to the class member that was previously defined. This does mean that you need to make sure that the variable has been assigned before its ever used. The safest way to do this is to check if (usernamechecked != null) before using it and if it is null to call an initialization routine containing the code to initialize it.
Mark