Open sourcing Spyglass - a flexible library for implementing mentions on Android

February 13, 2015

Today, I am excited to announce the first release of Spyglass, an open-source Android library from LinkedIn. Spyglass is a flexible library that provides customizable widgets in order to simplify the implementation of mentions in your apps. A mention is a tappable annotation in a text field that corresponds to the name of an individual or entity. It supports Android versions as far back as Gingerbread (API level 9).

Background

Spyglass originated out of a desire to better connect our members by allowing them to mention one another in updates, posts, shares, and comments. The original implementation of the library was built using Android’s MultiAutoCompleteTextView. Besides being a mouthful to say, this implementation fell short for us in a few key areas. Specifically, it limited how we could design the mentions experience. It forced us to use a Popup to display the list, and it severely restricted access to it by only exposing a few public helper methods to control it. Unfortunately, this made it both difficult to customize and hard to test. For our needs, it was much easier to build our own custom widgets on top of an EditText. Hence, Spyglass was born.

Spyglass in the current LinkedIn app

Architecture

Spyglass is divided into three, customizable layers: tokenization, suggestions, and mentions. Together, these layers form the core update lifecycle of a Spyglass-powered widget.

Tokenization

After the user types a character, Spyglass will use a tokenizer to determine which part of the inputted text it should be considering and whether it could be a valid mention. The default implementation requires that the user types at least three characters before generating and displaying suggestions. However, this behavior is completely customizable. By default, Spyglass provides a highly-configurable default implementation, the WordTokenizer, that allows you to tweak its behavior to specifically fit your needs. For more information about configuration options, see the WordTokenizer.Configuration class. If you need more customization, you may also create your own tokenizer via the Tokenizer interface.

Suggestions

Once the tokenizer has generated a valid token, Spyglass must now determine which suggestions to display based upon that token. To accomplish this, Spyglass will notify a listener within your app, indicating that your app should now gather new suggestions. Once your app has gathered any suggestions, it will add them to the widget. Note that suggestions can be added at any time from any data source and the same token may query multiple data sources. With suggestions in hand, Spyglass will then use SuggestionsListBuilder, a separate interface defined within your app, to determine the order of the suggestions and how they should be displayed.

Mentions

After a suggestion has been tapped, Spyglass will insert a new mention into the text box. As with the other two layers, the mentions layer offers a decent default implementation with easy customization. For example, you can easily tweak how your mentions appear (i.e. highlight and text colors) and change how they behave. One particularly useful feature is the ability to do multi-stage deletions. We use this extensively in the LinkedIn app to allow users to delete only the last name of a mentioned member.

UI Components

Spyglass includes two custom widgets. The first widget is the MentionsEditText, a subclass of EditText with enhanced functionality for tokenizing the user’s input and displaying mentions. Note that you must handle displaying the suggestions yourself (typically within a ListView, a GridView, or more recently, a RecyclerView). Alternatively, you may use our second custom view, the RichEditorView, which is built on top of the MentionsEditText and automatically displays suggestions in an embedded ListView.

Sample Usage

The following example demonstrates a simple Android activity using the RichEditorView to implement a basic mentions-enabled text box.

https://gist.github.com/nhibner/2082adbc995622b70dbc.js

Here is the corresponding layout file referenced in the above code.

https://gist.github.com/nhibner/ff2a25783c45d6a48fd7.js

Several more examples can be seen within our sample app here.

Testing

We use the Robolectric framework coupled with Mockito for our unit tests. You can run them via the gradle clean test command.

Looking Forward

Today represents the first public release of Spyglass. We hope that you will find it useful and we welcome any contributions (feature requests, bug reports, pull requests, etc.). With that in mind, this is just the tip of the iceberg. Stay tuned in the coming months for future open source contributions to mobile development from LinkedIn!

Acknowledgements

I’d like to thank Shoulong Li for his excellent contributions to the code and design of the library and Spandana Patolla for her thorough testing.

Topics