private void init ( ) { if ( initialized ) return ; // Initialise variables setTokenizer ( new CharacterTokenizer ( Arrays . asList ( ' ' , ' ' ) , "," ) ) ; Editable text = getText ( ) ; assert null != text ; spanWatcher = new TokenSpanWatcher ( ) ; textWatcher = new TokenTextWatcher ( ) ; hiddenContent = null ; countSpan = new CountSpan ( ) ; // Initialise TextChangedListeners addListeners ( ) ; setTextIsSelectable ( false ) ; setLongClickable ( false ) ; //In theory, get the soft keyboard to not supply suggestions. very unreliable setInputType ( getInputType ( ) | InputType . TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType . TYPE_TEXT_FLAG_AUTO_COMPLETE ) ; setHorizontallyScrolling ( false ) ; // Listen to IME action keys setOnEditorActionListener ( this ) ; // Initialise the text filter (listens for the split chars) setFilters ( new InputFilter [ ] { new InputFilter ( ) { @ Override public CharSequence filter ( CharSequence source , int start , int end , Spanned dest , int destinationStart , int destinationEnd ) { if ( internalEditInProgress ) { return null ; } // Token limit check if ( tokenLimit != - 1 && getObjects ( ) . size ( ) == tokenLimit ) { return "" ; } //Detect split characters, remove them and complete the current token instead if ( tokenizer . containsTokenTerminator ( source ) ) { //Only perform completion if we don't allow free form text, or if there's enough //content to believe this should be a token if ( preventFreeFormText || currentCompletionText ( ) . length ( ) > 0 ) { performCompletion ( ) ; return "" ; } } //We need to not do anything when we would delete the prefix if ( destinationStart < prefix . length ( ) ) { //when setText is called, which should only be called during restoring, //destinationStart and destinationEnd are 0. If not checked, it will clear out //the prefix. //This is why we need to return null in this if condition to preserve state. if ( destinationStart == 0 && destinationEnd == 0 ) { return null ; } else if ( destinationEnd <= prefix . length ( ) ) { //Don't do anything return prefix . subSequence ( destinationStart , destinationEnd ) ; } else { //Delete everything up to the prefix return prefix . subSequence ( destinationStart , prefix . length ( ) ) ; } } return null ; } } } ) ; initialized = true ; }
Initialise the variables and various listeners