MultiAutoCompleteTextView is an editable TextView, extending AutoCompleteTextView. In a text view, when the user starts to type a text, MultiAutoCompleteTextView shows completion suggestions for the substring of the text and it is useful for the user to select the option instead of typing. This feature is very much useful in all kinds of apps like educational/commercial/entertainment apps etc., This feature is one way allows the user to select the correct term and since multiple suggestions are allowed, it makes the user’s life very simple. A sample GIF is given below to get an idea about what we are going to do in this article. Note that we are going to implement this project using the Java language.
Difference Between AutoCompleteTextView and MultiAutoCompleteTextView
An AutoCompleteTextView only offers suggestion about the whole text. But MultiAutoCompleteTextView offers multiple suggestions for the substring of the text.
Important Methods
1. setTokenizer():
The Tokenizer is set inside the method setTokenizer(). By default, we have CommaTokenizer. In this example, we are using two MultiAutoCompleteTextView instances. One(multiAutoCompleteTextViewDefault) with default CommaTokenizer.
multiAutoCompleteTextViewDefault.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
Here when the user finishes typing or selects a substring, a comma is appended at the end of the substring. For second instance(multiAutoCompleteTextViewCustom), we are using SpaceTokenizer. It is nothing but a Java class and in that we need to write the code inside 3 methods namely findTokenStart, findTokenEnd, and terminateToken.
multiAutoCompleteTextViewCustom.setTokenizer(new SpaceTokenizer());
Here when the user finishes typing or selects a substring, space is appended at the end of the substring.
2. setThreshold():
setThreshold() is used to specify the number of characters after which the dropdown with the autocomplete suggestions list would be displayed. It can be 1 or 2 or depends upon your requirement. For this example,
// For multiAutoCompleteTextViewDefault, after user types a character,
// the dropdown is shown
multiAutoCompleteTextViewDefault.setThreshold(1);
// For multiAutoCompleteTextViewCustom, after user types 2 characters,
// the dropdown is shown
multiAutoCompleteTextViewCustom.setThreshold(2);
3. setAdapter():
In order to show the substring items in the dropdown, we need to fill string array in “ArrayAdapter”.
// First instance
ArrayAdapter<String> randomArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, fewRandomSuggestedText);
multiAutoCompleteTextViewDefault.setAdapter(randomArrayAdapter);
// second instance
ArrayAdapter<String> tagArrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, fewTags);
multiAutoCompleteTextViewCustom.setAdapter(tagArrayAdapter);
Example
Step 1: Create a New Project
To create a new project in Android Studio please refer to How to Create/Start a New Project in Android Studio. Note that select Java as the programming language.
Step 2: Working with the activity_main.xml file
For this example in the activity_main.xml file add two TextViews and two MultiAutoCompleteTextViews. Below is the complete code for the activity_main.xml file. Comments are added inside the code to understand the code in more detail.
XML
<? xml version = "1.0" encoding = "utf-8" ?> <!--In linearlayout, screen is rendered and hence all the below components come line by line and provide neat layout --> < LinearLayout android:layout_width = "match_parent" android:layout_height = "match_parent" android:layout_gravity = "center" android:layout_margin = "16dp" android:orientation = "vertical" tools:context = ".MainActivity" > <!-- To indicate the user that first MultiAutoCompleteTextView is supported with comma separated this textview is introduced. It just displays Text Separated by Commas at the top --> < TextView android:id = "@+id/textView" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:gravity = "center" android:text = "Text Separated by Commas" android:textSize = "18sp" /> <!-- 1st MultiAutoCompleteTextView instance identified with multiAutoCompleteTextViewDefault and here when user starts to type, it will show relevant substrings and after user chooses it, the text is ended with "," as comma is the default tokenizer --> < MultiAutoCompleteTextView android:id = "@+id/multiAutoCompleteTextViewDefault" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_margin = "20dp" android:ems = "10" android:hint = "Enter Search Terms here" /> < TextView android:layout_width = "match_parent" android:layout_height = "wrap_content" android:gravity = "center" android:text = "Text Separated by Custom Token" android:textSize = "18sp" /> <!-- 2nd MultiAutoCompleteTextView instance identified with multiAutoCompleteTextViewCustom and here when user starts to type, it will show relevant substrings and after user chooses it, the text is ended with " " as code is done to have space as separator --> < MultiAutoCompleteTextView android:id = "@+id/multiAutoCompleteTextViewCustom" android:layout_width = "match_parent" android:layout_height = "wrap_content" android:layout_margin = "20dp" android:ems = "10" android:hint = "Add your necessary tags here" /> </ LinearLayout > |
The UI looks like the following:
Step 3: Working with the Java files
- Below is the complete code for the MainActivity.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.os.Bundle; import android.widget.ArrayAdapter; import android.widget.MultiAutoCompleteTextView; import androidx.appcompat.app.AppCompatActivity; public class MainActivity extends AppCompatActivity { // Defining two MultiAutoCompleteTextView // This is to recognize comma separated. MultiAutoCompleteTextView multiAutoCompleteTextViewDefault; // This is the second one and required for custom features MultiAutoCompleteTextView multiAutoCompleteTextViewCustom; // As a sample, few text are given below which can be populated in dropdown, when user starts typing // For example, when user types "a", text whichever starting with "a" will be displayed in dropdown // As we are using two MultiAutoCompleteTextView components, using two string array separately String[] fewRandomSuggestedText = { "a" , "ant" , "apple" , "asp" , "android" , "animation" , "adobe" , "chrome" , "chromium" , "firefox" , "freeware" , "fedora" }; String[] fewTags = { "Java" , "JavaScript" , "Spring" , "Java EE" , "Java 8" , "Java 9" , "Java 10" , "MongoDB" , "MarshMallow" , "NoSQL" , "NativeApp" , "SQL" , "SQLite" }; @Override protected void onCreate(Bundle savedInstanceState) { super .onCreate(savedInstanceState); setContentView(R.layout.activity_main); multiAutoCompleteTextViewDefault = findViewById(R.id.multiAutoCompleteTextViewDefault); multiAutoCompleteTextViewCustom = findViewById(R.id.multiAutoCompleteTextViewCustom); // In order to show the substring options in a dropdown, we need ArrayAdapter // and here it is using simple_list_item_1 ArrayAdapter<String> randomArrayAdapter = new ArrayAdapter<>( this , android.R.layout.simple_list_item_1, fewRandomSuggestedText); multiAutoCompleteTextViewDefault.setAdapter(randomArrayAdapter); // setThreshold() is used to specify the number of characters after which // the dropdown with the autocomplete suggestions list would be displayed. // For multiAutoCompleteTextViewDefault, after 1 character, the dropdown shows substring multiAutoCompleteTextViewDefault.setThreshold( 1 ); // Default CommaTokenizer is used here multiAutoCompleteTextViewDefault.setTokenizer( new MultiAutoCompleteTextView.CommaTokenizer()); ArrayAdapter<String> tagArrayAdapter = new ArrayAdapter<>( this , android.R.layout.simple_list_item_1, fewTags); multiAutoCompleteTextViewCustom.setAdapter(tagArrayAdapter); // For multiAutoCompleteTextViewCustom, after 2 characters, the dropdown shows substring multiAutoCompleteTextViewCustom.setThreshold( 2 ); // As multiAutoCompleteTextViewCustom is customized , we are using SpaceTokenizer // which is written as a separate java class to handle space // SpaceTokenizer can be customized as per our needs, here for this example, // after user types 2 character // the substring of the text is shown in the dropdown and once selected, // a space is appended at the // end of the substring. So for customized MultiAutoCompleteTextView, // we need to write code like SpaceTokenizer // It has 3 methods namely findTokenStart,findTokenEnd and terminateToken multiAutoCompleteTextViewCustom.setTokenizer( new SpaceTokenizer()); } } |
- For 2nd instance of MultiAutoCompleteTextViewActivity, here used space tokenizer and only comma tokenizer is default and if we are using other tokenizers, need to write the code in java and it should have 3 methods implemented namely findTokenStart, findTokenEnd, and terminateToken.
- Now create another Java file (app > java > your package name > New > Java Class) and named it as SpaceTokenizer. Below is the complete code for the SpaceTokenizer.java file. Comments are added inside the code to understand the code in more detail.
Java
import android.text.SpannableString; import android.text.Spanned; import android.text.TextUtils; import android.widget.MultiAutoCompleteTextView; // As this java class implements MultiAutoCompleteTextView.Tokenizer, // we should write 3 methods i.e. findTokenStart,findTokenEnd and terminateToken public class SpaceTokenizer implements MultiAutoCompleteTextView.Tokenizer { private int i; // Returns the start of the token that ends at offset cursor within text. public int findTokenStart(CharSequence inputText, int cursor) { int idx = cursor; while (idx > 0 && inputText.charAt(idx - 1 ) != ' ' ) { idx--; } while (idx < cursor && inputText.charAt(idx) == ' ' ) { idx++; } return idx; } // Returns the end of the token (minus trailing punctuation) that // begins at offset cursor within text. public int findTokenEnd(CharSequence inputText, int cursor) { int idx = cursor; int length = inputText.length(); while (idx < length) { if (inputText.charAt(i) == ' ' ) { return idx; } else { idx++; } } return length; } // Returns text, modified, if necessary, to ensure that it ends with a token terminator // (for example a space or comma). public CharSequence terminateToken(CharSequence inputText) { int idx = inputText.length(); while (idx > 0 && inputText.charAt(idx - 1 ) == ' ' ) { idx--; } if (idx > 0 && inputText.charAt(idx - 1 ) == ' ' ) { return inputText; } else { if (inputText instanceof Spanned) { SpannableString sp = new SpannableString(inputText + " " ); TextUtils.copySpansFrom((Spanned) inputText, 0 , inputText.length(), Object. class , sp, 0 ); return sp; } else { return inputText + " " ; } } } } |
Run On Emulator
Conclusion
In many apps, there are necessities to have MultiAutoCompleteTextView which will help to provide valuable information and makes users’ lives easier to avoid selecting irrelevant information. While collecting requirements, the user has to key in all the necessary text in the java file so that in the dropdown, necessary suggested text can appear.