Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/natario1/autocomplete

Simple yet powerful autocomplete behavior for EditTexts, to avoid working with MultiAutoCompleteTextView APIs.
https://github.com/natario1/autocomplete

android android-ui autocomplete autocompletetextview edittext popup

Last synced: 3 days ago
JSON representation

Simple yet powerful autocomplete behavior for EditTexts, to avoid working with MultiAutoCompleteTextView APIs.

Awesome Lists containing this project

README

        

[![Build Status](https://github.com/natario1/Autocomplete/workflows/Build/badge.svg?event=push)](https://github.com/natario1/Autocomplete/actions)
[![Release](https://img.shields.io/github/release/natario1/Autocomplete.svg)](https://github.com/natario1/Autocomplete/releases)
[![Issues](https://img.shields.io/github/issues-raw/natario1/Autocomplete.svg)](https://github.com/natario1/Autocomplete/issues)

*Need support, consulting, or have any other business-related question? Feel free to get in touch.*

*Like the project, make profit from it, or simply want to thank back? Please consider [sponsoring me](https://github.com/sponsors/natario1)!*

# Autocomplete

Simple yet powerful autocomplete behavior for `EditText`s, to avoid working with
`MultiAutoCompleteTextView` APIs.

```kotlin
implementation("com.otaliastudios:autocomplete:1.1.0")
```

To see it in action, take a look at the sample app in the `sample` module.

- [Usage](#usage)
- [AutocompletePolicy](#autocompletepolicy)
- [AutocompletePresenter](#autocompletepresenter)
- [RecyclerViewPresenter](#recyclerviewpresenter)
- [AutocompleteCallback](#autocompletecallback)
- [Contributing](#contributing)



## Usage

`Autocomplete` let's you add autocomplete behavior to any `EditText` of your choice. The workflow is
as follows:

- User types stuff into the edit text
- `AutocompletePolicy` detects if typed text should trigger the autocomplete popup
- If yes, the popup is shown
- `AutocompletePolicy` extracts the **query** string from text. For instance, if text is *Look at
this @john*, you might want to look for *john* users in your database
- The query string is passed to `AutocompletePresenter`, that shows a list of items for that query
- When some item is clicked, `AutocompleteCallback` is notified and tells whether the popup should be
dismissed or not.

These are the base components of the library. You will build an `Autocomplete` instance passing
each component you need, and that's it.

```java
Autocomplete.on(editText)
.with(autocompletePolicy)
.with(autocompleteCallback)
.with(autocompletePresenter)
.with(popupBackground)
.with(popupElevation)
.build();
```

### AutocompletePolicy

This is an interface that controls when to show/hide the popup. For simple cases (single autocompletion,
with just one result, similar to `AutocompleteTextView`) you can leave this unspecified. The library will
fallback to `Autocomplete.SimplePolicy`:

```java
public class SimplePolicy implements AutocompletePolicy {
@Override
public boolean shouldShowPopup(Spannable text, int cursorPos) {
return text.length() > 0;
}

@Override
public boolean shouldDismissPopup(Spannable text, int cursorPos) {
return text.length() == 0;
}

@Override
public CharSequence getQuery(Spannable text) {
return text;
}

@Override
public void onDismiss(Spannable text) {}
}
```

For more complex situations, you can go implementing the methods:

- `shouldShowPopup(Spannable, int)`: called to understand whether the popup should be shown. For
instance, you might want to trigger the popup only when the hashtag character '#' is typed.
- `shouldDismissPopup(Spannable, int)`: whether the popup should be hidden. The typical implementation
would simply be to return `!shouldShowPopup()`, but that is up to you.
- `getQuery(Spannable)`: called to understand which part of the text should be passed to presenters.
For instance, user might have typed *@john* but you want to query for *john* of course.
- `onDismiss(Spannable)`: this is the moment you should clear any span you have added to the text.

For the typical case of `#hashtags`, `@usernames` or whatever is triggered by a certain character,
the library provides the `CharPolicy` class. It works as multi-autocomplete as well (e.g. for texts
like *you should see this @john @pete*).

```java
Autocomplete.on(editText)
.with(new CharPolicy('#'))
.with(autocompletePresenter)
.build();
```

### AutocompletePresenter

The presenter controls the display of items and their filtering when a query is selected.
It is recommended to extend `RecyclerViewPresenter`, which shows a `RecyclerView` list.
For more complex needs, look at the base `AutocompletePresenter` class and its comments.

**Note**: starting from **1.1.0**, if the view returned by `AutocompletePresenter` has 0 height, this is read as a
no-data signal and the popup will be dismissed. Not doing so would cause drawing artifacts, by
leaving the popup in a weird state.

If you are performing asynchronous loading, make sure to give some height to your view,
for example by returning a 'loading' item from your adapter, or adding vertical padding.

#### RecyclerViewPresenter

This automatically inflates a `RecyclerView` into the popup. Some relevant callbacks to be overriden:

- `instantiateAdapter()`: you should provide an adapter for the recycler here.
- `instantiateLayoutManager()`: same for the layout manager. Defaults to vertical `LinearLayoutManager`.
Complex managers might lead to UI inconsistencies.
- `getPopupDimensions()`: return dimensions for the popup (width, height, maxWidth, maxHeight).
- `onViewShown()`: you can perform further initialization on the recycler. The list now is about to be requested.
- `onQuery(CharSequence)`: we have a query from the edit text, as returned by `AutocompletePolicy`.
This is the time to display a list of results corresponding to this filter.
- `onViewHidden()`: release resources here if needed.

When a list item is clicked, please ensure you are calling `dispatchClick(item)` to dispatch the
click event to the `AutocompleteCallback`, if present.

### AutocompleteCallback

```java
public interface AutocompleteCallback {
boolean onPopupItemClicked(Editable editable, T item);
void onPopupVisibilityChanged(boolean shown);
}
```

`AutocompleteCallback` controls what happens when either the popup visibility changes, or when an
item is selected. Typically at this point you might want to insert a `String` related to that item
into the `EditText`.

This should be done by acting on the `Editable` interface that you should already know, using
methods like `editable.insert()` or `editable.replace()`.

## Contributing

You are welcome to contribute with issues, PRs or suggestions.