What's the right way to extend EditText to giv

2019-03-18 18:57发布

问题:

I'm wondering if it's possible to add functionality to EditText such that when I include my newly extended field in the layout xml, I don't have to then add any code to the Activity class to get it to behave in specific ways.

For example, I'd like to make a EditPhone field which is just an EditText that has the added feature of listening for key events and modifying the field to include parenthesis and dashes in their appropriate locations.

At the moment, I'm always having to include the listener code and attach it to the view, manually. But obviously the class has a ton of default behavior that is wrapped up in it (for example, it brings up the keyboard when you click it). So, I'm guessing it shouldn't be all that tough, but I'm not clear on what the steps would be to accomplish this.

And to be clear, I don't need help with the Phone specific feature described above (I have that all worked out), I'm trying to understand how to extend View in a way that it takes on additional functionality by default, so as not to have to clutter my Activities with the same code over and over.

回答1:

Actually there is nothing complicated about that. Usually you would apply a InputFilter to your EditText in your code and this would do the job. But if you see a pattern in that and want a EditText which always behaves that way you could create a custom widget that way:

public class PhoneEditText extends EditText {

    public PhoneEditText(Context context) {
        super(context);
        init();
    }

    public PhoneEditText(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public PhoneEditText(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init();
    }

    private void init() {
            // set your input filter here
    }
}

In XML layout you would simply use the full path to your custom class instead EditText:

<my.package.path.to.PhoneEditText
   attribute="value (all EditText attributes will work as they did before)" />