0

I've recently got into Android and have been looking at examples about Inner classes but don't really understand what the use of them is. They are used often when making listeners and when making a full class is unnecessary right? Maybe someone can explain it to me in laymans terms, also what would the alternative to using an inner anonymous class in this situation be? This code:

button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

            }
        });

Thanks

user2864740
  • 60,010
  • 15
  • 145
  • 220
user254886
  • 55
  • 8
  • 3
    You could create an inner class *with* a name, and you'd generally do that if you need that class's behavior in multiple places instead of just the one spot where it's inlined. It's basically the same thing as a local variable vs. a field. – chrylis -cautiouslyoptimistic- Mar 14 '14 at 22:54
  • You could create a regular class, and instantiate it and then pass an instance to the setOnClickListener. – Elliott Frisch Mar 14 '14 at 23:04

3 Answers3

4

One alternative pattern is to make the container class itself a listener.

public class MyClass implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        // Do something when button is clicked
    }

    public void initOrSomething() {
        button.setOnClickListener(this);
    }
}

However you may run into trouble if you have more than one button that needs to behave differently.

Another way is to have different listener classes for each button

public class Button1Listener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        // Do something when button1 is clicked
    }
}

public class Button2Listener implements View.OnClickListener {
    @Override
    public void onClick(View v) {
        // Do something when button2 is clicked
    }
}


button1.setOnClickListener(new Button1Listener());
button2.setOnClickListener(new Button2Listener());

Anonymous inner classes are just a more compact representation of the second pattern.

EDIT: Variations of both patterns are possible, where contents of the View object are examined to determine which button was clicked or constructor arguments are passed to the listener class to change listener behavior etc.

anttix
  • 7,709
  • 1
  • 24
  • 25
  • No trouble - you just switch on the view's id – NickT Mar 14 '14 at 22:58
  • Sure, just examining the contents of the View object is more error prone than having different listener interface implementations for each button. – anttix Mar 14 '14 at 23:01
  • Remember also that your constructor can take one or more arguments (even though an anonymous class can't do that), and a class that implements the listener can have fields (even though an `interface` can't). If you want something that has very similar behavior but is slightly different in some details, you can use constructor arguments to cause the listener to change behavior based on how it was constructed. – ajb Mar 14 '14 at 23:01
  • @user254886 glad it helped. An "Accept Answer" would be appriciated ;) – anttix Mar 14 '14 at 23:03
0

They are used often when making listeners and when making a full class is unnecessary right?

Listeners in Android, or other interfaces in other situations. But in essence, that's about it.

what would the alternative to using an inner anonymous class in this situation be?

It would be to create a class which implements this interface and submit it as an argument. For instance:

public class MyListener
    implements View.OnClickListener
{
    // implement onClick(), etc etc
}

// In code:

button.setOnClickListener(new MyListener(...));
fge
  • 119,121
  • 33
  • 254
  • 329
0

That's quite simple: What you are doing is just creating a class. For the JVM (or dalvik in this case), it doesn't matter if the class is it's own compilation unit (a file), an inner class or an anonymous class(*). So you have three equally valid options:

Option 1 Your example:

button.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
    }
});

Option 2 named inner class:

public MyActivity extends Activity {

 static class MyListener implements View.OnClickListener {
   @Override 
   public void onClick(View v) {
    // do something 
   }
}
....

  button.setOnClickListener(new MyListener());
}

and Option 3 Different Files:

File MyListener.java

public class MyListener implements View.OnClickListener {
 @Override 
 public void onClick(View v) {
  // do something 
 }
}

File MyActivity.java

import MyListener.java
public MyActivity extends Activity {
....

  button.setOnClickListener(new MyListener());
}

Which of these options you use is completely subjective - Depending on your needs and usage, one or the other makes more sense. However, generally in UI listeners, you don't want to have any logic that is disjunct from the logic of the Activity you are programming. Hence you use the anonymous class, because all the code stays in one place and makes it decently readable.

Blitz
  • 5,521
  • 3
  • 35
  • 53