Android Tokenized Auto-Complete, a New Splitwise Open-Source Project

gmail autocomplete in Android 4
This is what we’re going for.

For the past few months, Splitwise has been hard at work making much-needed improvements to our Android app. We released a faster, less buggy build in late August, and since then we’ve devoted nearly all our developer resources to a pristine 3.0 candidate that we can’t wait to get into your hands.

To achieve Android awesomeness for 3.0, we needed to build a Gmail-style autocomplete field for selecting friends when creating expenses. I was expecting to find this fairly easy to do with the Android SDK. Lots of apps must need this need, and I was aware of the AutoCompleteTextView and MultiAutoCompleteTextView classes. How hard could it be?

The short answer: Pretty darn hard! Hopefully, not anymore. We’ve just released an open-source version of the code on GitHub! Go grab the Splitwise TokenAutoComplete project to have your own wonderful, tokenized autocomplete view up and running in about half an hour. It works on Android versions all the way back to 2.2 (Froyo). More on my process below the fold. 

Open source package for gmail-style autocomplete tokenized widget / Chip
A screenshot of the open-source implementation we’re releasing today. Style it however you’d like.

When I started to work on the token auto-complete (also called Chips or Bubble EditText), I found the MultiAutoCompleteTextView pretty good for doing autocomplete for word completion in text, but completely inadequate for selecting a couple items from a list, like you would in the “To:” field of an email.

Our Android users certainly don’t deserve ‘completely inadequate’ auto-completion, so I took the time to really get it right by tweaking various behaviors. There are a lot of fussy details on this kind of input that you don’t even notice until you mess them up. Ketan Parmar has a great simple implementation, but it has some issues under older versions of Android. Custom list filtering is also not simple, so I adapted code from Tobias Schürg based on Alexadr’s answer on stackoverflow.

I wanted to make sure I didn’t miss any odd edge cases in different Android OS versions. I had to work around a number of bugs in Froyo and Gingerbread and there are still some details missing in Honeycomb that aren’t quite right. Please let me know if you find any bugs or places where I’m inconsistent with the Gmail app behavior.

We are proud to open-source this code, because we have lots of sympathy for the other Android developers struggling to build world-class experiences. Building great Android apps is definitely still not as easy as it could be. Not to mention that we believe Splitwise is a fairness company – contributing to open source is absolutely an extension of what we believe. I want this project to help other developers avoid the slog I had to do to get this working.

I’ve put a lot of effort in using the existing components and style attributes as much as possible, and I think the places where I did custom work have enough flexibility to let people customize them as needed.

Please let me know if you’re using this code! I’d love to hear from anyone who found this useful (or not). Or, those of you who found a different way to execute this.

28 thoughts on “Android Tokenized Auto-Complete, a New Splitwise Open-Source Project”

  1. Thank you for wonderfull example.. i am triyng to do this type customization from the last 20 days.. at last u saved my time…. but u are not showing the exatrac chips count when the to filed focus got shifted to another field… like in gmail..

  2. Thanks a lot for the code! It saved me a lot of time! I want clear the text when the user clicks on a button. I am trying to do the following: edittext.setText(“”); However the app crashes at com.tokenautocomplete.TokenCompleteTextView.onSelectionChanged(TokenCompleteTextView.java:434).
    How do I clear the textbox?

    1. Hi Shardul,

      You’re much more likely to get a useful response for technical stuff posting on the github page. Are you trying to clear the tokens or just the current completion text? there is a removeObject call you can use to clear object.

      Clearing the recent completion text is much trickier to do programatically. There are some cases where you just can’t do it – I can’t clear the text across all the version of Android that the widget supports, so I gave up on it.

  3. it will work. i am already using in one of they condition. call this method in the replaceText Method in “TokenCompleteTextView” Class. in my case when ever i am adding a token after selecting name in the matched list in the drop down. i have to check spinner selection in my case . if spinner selection is not matched my condition i am clearing the typed text using “clearComposingText();” method only.

    1. It depends heavily on the version of Android you’re testing against. I’d strongly urge you to test this behavior in 2.2, 2.3.3, 4.0.3 and 4.3/4.4. In some cases, I can’t figure out how to clear the text, so I gave up.

      1. Ok.. In my case I have TokenComplete Text view and below that i have Drop down which contains message Types(Chat, Confirm). by default message type will be selected as chat. so in the edit text i entered one token. then for i am typing for “marsh” in the edit text ,in the suggestion list clicked on Marshall Weir. in this time i will check drop down selected value if it is chat then i am clearing “marsh” text in the edit text..

      2. Here is my Code
        if (ComposeMessageActivty.selected_msg_typeitem
        .equalsIgnoreCase(“Chat”)
        && ComposeMessageActivty.selectedNames.size() == 1) {
        Editable editable = getText();
        int end = getSelectionEnd();
        int start = tokenizer.findTokenStart(editable, end);
        String original = TextUtils.substring(editable, start, end);
        if (editable != null) {
        QwertyKeyListener
        .markAsReplaced(editable, start, end, original);
        editable.replace(start, end, “”);
        }
        clearComposingText();
        Common.alertbox(
        getContext().getResources().getString(
        R.string.note_alert_label),
        getContext().getResources().getString(
        R.string.chat_message_limit), getContext());
        return;

        }

    2. That does look like it should work across all the systems. If you run into trouble, the other solution that would make sense would be to call performCompletion and then removeObject to clear out the last item.

      1. Hi Marshal,

        Thanks a lot for this library.but i am using this library with check-box listview and when user select check box then add object to edit text.
        but i also have search in this edit text.but problem is when user type some text after ad object then i am not able to remove that text.

  4. Hi Marshal,
    performCompletion – is something I was looking for! Thanks for that. However, when i perform edittext.performcompletion – it adds the first contact in the contact list.
    For example, I start typing aa[at]gmail.com – this id doesn’t exist. when I call performcompletion – it adds aalok[at]gmail.com – which is the first record in my contact list.

    What could be the right way of doing it?

    1. Hi Marshal, I found the culprit – I was setting prefix with a space. i.e. mToField.setPrefix(“To: “); The space was causing the performcompletion to take first record in the contact list. Somehow, removing the space helped me solve the problem.
      Thanks a lot again! 🙂

  5. Hi. I am using your library in my project. HOwever, I am having trouble at one place. My token contains only Person’s name. When the token is not selected, the token’s background is white and it’s text color is black. On the other hand, if the token is not selected/default, the token’s background should be black and it’s text color should be white colored. I used a selector xml to change the token’s background, however, I don’t know how to change the text’s color.

    The selector xml is working perfectly fine and the background is changing when the token and unselected, but, the text’s color remains same.

    I used below setSelected() method to change the text’s color. But it’s not working.

    @Override
    public void setSelected(boolean selected) {
    super.setSelected(selected);
    TextView tv = (TextView) findViewById(R.id.token_name);
    if(selected) {
    tv.setTextColor(Color.WHITE);
    } else {
    tv.setTextColor(Color.BLACK);
    }
    }
    Please help me out.

  6. Hi, thanks for this wonderful library. I am implementing it in one of my apps. However, I am having a trouble.

    How do you change the layout of drop down list. I want to show names and photos there. For now I am showing just names by returning their names from overridden toString method.

    @Override
    public String toString() { return mContactFirstName; }

    Thanks

    1. Hi Nitesh, you should be able to inflate any layout you want for the list by overriding the getView method of the adapter you set for the completion view.

  7. Hi Marshal..
    Here in your code where you use perason class to add a name and email.
    I wanna to use my own String to get contact name from phonebook.
    But this is not possible to show on edittext.
    Please do some help for this issue.

  8. Hi Marshal..
    Thanks for your library,its helped me a lot.but I am getting two issues.
    1.when I delete the last token by backspace I am getting a “,”(COMMA).
    2.when I insert more than 50 token..it shows like (name+49 added).when I click on the EditText,it shows the hidden tokens..when I click outside of the edit text…it takes time to collapse(performCollapse())…and my UI stops responding a while..need help.

  9. I’d like to design the token with an image and text. The image has to be loaded via a url. Do you have an example on how to do that? I’m using Picasso library but that call never occurs. It’s called in the getViewForObject(). Thanks.

      1. I’ve added that to the issues section of the github project. Also, I’ve quoted my code there for your reference. Any help is appreciated. Your library is very useful for autocompletion and probably the only one available to load data from the network with so much ease. I’ve been able to hook it up to the network to load data. The only issue I’m not able to get around is loading images from a url into the token field.

  10. Hi Marshall! I have List view with check box from my contacts. I need to select two or more contacts name, after click button “Ok” and set names to searchView separately with own background.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s