1

i have a newbie question. Can someone explain what type of java syntax is in code like this. I've googled and but I dont seem to understand how is this an implementation of TextWatcher in anonymus class, (or something like that). All implementations I've seen so far had a keyword implements in a class definiton but this one does not. Any explanations are welcome (I know what this code does and how do I use it, the understanding of syntax is my problem.) If you could rewrite it in a equivalent way would also be great. Thanks

mObjectOfEditText.addTextChangedListener(new TextWatcher() {
                public void onTextChanged(parameters) {}

            public void beforeTextChanged(parameters) {}

            public void afterTextChanged(parameters) {}
        });
potato
  • 4,479
  • 7
  • 42
  • 99
  • have you checked this http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html – nobalG Oct 14 '14 at 13:24

4 Answers4

1

When you implement an interface (or extend a class) with an anonymous class, you don't give a name to that class, so there's no place where you can write X implements Y (since there is no X). That's what anonymous means. This is exactly what happens in your example.

addTextChangedListener expects an instance that implements TextWatcher. In the example, the implementation appears inline, as an anonymous class, that implements all the methods of that interface.

Your example can be replaced with equivalent code using a regular class that implements that interface :

public class TextWatcherImpl implements TextWatcher 
{
    public void onTextChanged(parameters) {}

    public void beforeTextChanged(parameters) {}

    public void afterTextChanged(parameters) {}
}

Then, you can use that class this way :

TextWatcherImpl impl = new TextWatcherImpl ();
mObjectOfEditText.addTextChangedListener(impl);
Eran
  • 387,369
  • 54
  • 702
  • 768
1

I think in 99% of the cases you want to update a String as the user types. This totally works fine:

String string;

mObjectOfEditText.addTextChangedListener(new TextWatcher() {
        public void onTextChanged(...) {}

        public void beforeTextChanged(...) {}

        public void afterTextChanged(Editable e) {
            string = e.toString();
        }
});

But instead of writing empty onTextChangeds and beforeTextChangeds over and over again you could create an abstract class:

abstract class LightTextWatcher implements TextWatcher {
    @Override public final void beforeTextChanged(...) {}
    @Override public final void onTextChanged(...) {} 
}
...
mObjectOfEditText.addTextChangedListener(new LightTextWatcher() {
    public void afterTextChanged(Editable e) {
        string = e.toString();
    }
});

Now if you have many TextViews (or EditTexts which are TextViews) you have a lot less verbose code with the second variant.

KeksArmee
  • 1,349
  • 14
  • 21
0

see this answer and this example, actually you do it like this :

  EditText myTextBox = (EditText) findViewById(R.id.myTextBox);
  myTextBox.addTextChangedListener(new TextWatcher() {

  public void afterTextChanged(Editable s) {
     }

 public void beforeTextChanged(CharSequence s, int start, 
    int count, int after) {
     }

  public void onTextChanged(CharSequence s, int start, 
    int before, int count) {
    TextView myOutputBox = (TextView) findViewById(R.id.myOutputBox);
    myOutputBox.setText(s);
     }
  });
Community
  • 1
  • 1
Syed Raza Mehdi
  • 4,067
  • 1
  • 31
  • 47
0

1. Basic

TextWatcher tw = new TextWatcher();

2. Child class:

private class MyTextWatcher extends/implements TextWatcher() {

    @Override
    public void beforeTextChanged(parameters) {
        ...
    }

}

TextWatcher tw = new MyTextWatcher();

3. With anonymous class:

public class Main {

final StringBuilder sb = ...;
TextWatcher tw = new TextWatcher() {

    {
        sb.append("TW: ");
    }

    @Override
    public void beforeTextChanged(parameters) {
        ... sb ... Main.this ...
    }

};

So an anonymous class does not need a name and is defined at its declaration. Also newly introduced public methods or fields still will not be accessible, as the instance variable is of the base class/interface. The anonymous class can use effectively final local variables, fields and this of the surrounding class (Main.this here). (The variable must be effectively final because a new variable sb is made in the class, as the variable scope/life-time of sb will vary. And the language designers found it better to let those two variables always hold the same value.)

Above an initializer block is used { ... } as a replacement for a constructor.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138