In between of EditText how to use autocomplete android - android

I know how to use EditText in android and how to use AutoComplete EditText in android. But AutoComplete EditText is used like dropdown list where user type a character and suggestions will be displayed and user clicks on one of the suggestions. If there is no suggestion then it won't display any text.
My requirement is like, Consider there is an EditText. User can type anything they want, but when the word starts from special character like for example "#" then the api will hit and display suggestions.
Complete Example:
"My Name is James Bond and I am #And"
In above example when user type this sentence at the end "#And" it will show the auto suggestion from hitting the API(should display Android) and user can select this suggested word from list.
Is there any way to achieve this??
Please Do help me.
Thank You.

Android provides MultiAutoCompleteTextView. Use this widget instead of EditText and override its tokenizer.
MultiAutoCompleteTextView myautocomplete = (MultiAutoCompleteTextView) findViewById(R.id.multy);
ArrayAdapter adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, array_for_autocomplete);
myautocomplete.setAdapter(adapter);
myautocomplete.setTokenizer(new MultiAutoCompleteTextView.Tokenizer() {
#Override
public int findTokenStart(CharSequence text, int cursor) {
int i = cursor;
while (i > 0 && text.charAt(i - 1) != '#') {
i--;
}
while (i < cursor && text.charAt(i) == ' ') {
i++;
}
return i;
}
#Override
public int findTokenEnd(CharSequence text, int cursor) {
int i = cursor;
int len = text.length();
while (i < len) {
if (text.charAt(i) == ',') {
return i;
} else {
i++;
}
}
return len;
}
#Override
public CharSequence terminateToken(CharSequence text) {
int i = text.length();
while (i > 0 && text.charAt(i - 1) == ' ') {
i--;
}
if (i > 0 && text.charAt(i - 1) == ',') {
return text;
} else {
if (text instanceof Spanned) {
SpannableString sp = new SpannableString(text + ", ");
TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
Object.class, sp, 0);
return sp;
} else {
return text + ", ";
}
}
}
});
Documentation : http://developer.android.com/reference/android/widget/MultiAutoCompleteTextView.html

Related

MultiAutoCompleteTextView doesn't accept blank spaces

My problem is that when I suggest sentences in MultiAutoCompleteTextView, when I press spacebar, the suggestions disappear.
Example:
Suggested words:
THE ROCK THE BALL THERMAL
If I write "THE", all sentences are displayed, but if I write "THE " (with blank space) the suggestions are dismissed.
I want that if you write "THE ", the elements "THE ROCK" and "THE BALL" are displayed in suggested words.
Thanks.
You should implement MultiAutoCompleteTextView.Tokenizer and create a spaceTokenizer as below. Then set multiAutoCompleteTextView.setTokenizer(new SpaceTokenizer());
public class SpaceTokenizer implements MultiAutoCompleteTextView.Tokenizer {
public int findTokenStart(CharSequence text, int cursor) {
int i = cursor;
while (i > 0 && text.charAt(i - 1) != ' ') {
i--;
}
while (i < cursor && text.charAt(i) == ' ') {
i++;
}
return i;
}
public int findTokenEnd(CharSequence text, int cursor) {
int i = cursor;
int len = text.length();
while (i < len) {
if (text.charAt(i) == ' ') {
return i;
} else {
i++;
}
}
return len;
}
public CharSequence terminateToken(CharSequence text) {
int i = text.length();
while (i > 0 && text.charAt(i - 1) == ' ') {
i--;
}
if (i > 0 && text.charAt(i - 1) == ' ') {
return text;
} else {
if (text instanceof Spanned) {
SpannableString sp = new SpannableString(text + " ");
TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
Object.class, sp, 0);
return sp;
} else {
return text + " ";
}
}
}
}
Have a look at this post:
https://groups.google.com/forum/#!topic/android-developers/OrsN2xRpDmA
I just ran into a similar problem and wrote a simple multi word derivation. It defaults to a "," separator but you can set it whatever you like using the "setSeparator" method.
or
this stack-overflow answer might be helpful cause it experiences the same problem:
AutoCompleteTextView backed by CursorLoader

How to set two adapter for AutocompleteTextview with respect to if conditions

i have two adpters in my app with separate listview
one is for user and another one is for groups
i want set the adapter to the textview when the conditon exists like when the user types a token '#' the user adapter should be set and when the user types a token '#' the channel adapter(for populating list of groups) should be set
my adapters:
final ChannelAdapter customadapter1 = new ChannelAdapter(getActivity(), R.layout.all_cahnnel_list_item, joinOtherChannelList);
final UserAdapter customadapter = new UserAdapter(getActivity(), R.layout.all_user_list_item, userArrayList);
inputMessageView = (MultiAutoCompleteTextView) view.findViewById(R.id.message_input);
inputMessageView.setThreshold(0);
inputMessageView.setTokenizer(new MultiAutoCompleteTextView.Tokenizer() {
#Override
public CharSequence terminateToken(CharSequence text) {
int i = text.length();
while (i > 0 && text.charAt(i - 1) == ' ') {
i--;
}
if (i > 0 && text.charAt(i - 1) == ' ') {
return text;
} else {
if (text instanceof Spanned) {
SpannableString sp = new SpannableString(text + " ");
TextUtils.copySpansFrom((Spanned) text, 0, text.length(), Object.class, sp, 0);
return sp;
} else {
return text + " ";
}
}
}
#Override
public int findTokenStart(CharSequence text, int cursor) {
int i = cursor;
while (((i > 0 && text.charAt(i - 1) != '#') && (i > 0 && text.charAt(i - 1) != '#'))) {
i--;
}//Check if token really started with #, else we don't have a valid token
if (text.charAt(i - 1) != '#') {
inputMessageView.setAdapter(customadapter);
return cursor:
} else if (i < 1 || text.charAt(i - 1) != '#') {
inputMessageView.setAdapter(customadapter1);
return cursor;
}
return i;
}
#Override
public int findTokenEnd(CharSequence text, int cursor) {
int i = cursor;
int len = text.length();
while (i < len) {
if (text.charAt(i) == ' ') {
return i;
} else {
i++;
}
}
return len;
}
});
My problem is when i use if condition alone its working for custom adapter one. But when i use if and else if to set both adapter not even single adapter is working i mean its not displaying anything in the text view
Your conditions aren't same.
if (text.charAt(i - 1) != '#') {
inputMessageView.setAdapter(customadapter)
return cursor;
} else if (i < 1 || text.charAt(i - 1) != '#') {
inputMessageView.setAdapter(customadapter2);
return cursor;
}
If , as you said, works on one if conditions then it should work, because else if part doesn't gets executed. Try using logs and try printing the logs.

How to show dropdown only when inserting # character on MultiAutoCompleteTextView in android

I have a MultiAutoCompleteTextView. It works fine. But I want to show suggestion dropdown only when user type # on it (like tagging user in facebook app). I have no idea how to do it. Here is my code :
mChatbox = (MultiAutoCompleteTextView) findViewById(R.id.chatbox);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line, userList);
mChatBox.setAdapter(adapter);
mChatBox.setTokenizer(new SpaceTokenizer());
public class SpaceTokenizer implements MultiAutoCompleteTextView.Tokenizer {
public int findTokenStart(CharSequence text, int cursor) {
int i = cursor;
while (i > 0 && text.charAt(i - 1) != ' ') {
i--;
}
while (i < cursor && text.charAt(i) == ' ') {
i++;
}
return i;
}
public int findTokenEnd(CharSequence text, int cursor) {
int i = cursor;
int len = text.length();
while (i < len) {
if (text.charAt(i) == ' ') {
return i;
} else {
i++;
}
}
return len;
}
public CharSequence terminateToken(CharSequence text) {
int i = text.length();
while (i > 0 && text.charAt(i - 1) == ' ') {
i--;
}
if (i > 0 && text.charAt(i - 1) == ' ') {
return text;
} else {
if (text instanceof Spanned) {
SpannableString sp = new SpannableString(text + " ");
TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
Object.class, sp, 0);
return sp;
} else {
return text + " ";
}
}
}
Create a custom Text view extending MultiAutoCompleteTextView -> override enoughToFilter() -> set the threshold to 0 (the bold variable in the below given code) :
public boolean enoughToFilter() {
Editable text = getText();
int end = getSelectionEnd();
if (end < 0 || mTokenizer == null) {
return false;
}
int start = mTokenizer.findTokenStart(text, end);
if (end - start >= mThreshold && start != -1) {
return true;
} else {
return false;
}
}
Using this code you'll see the auto suggested list on press of #
If you want to detect your string starts with '#' for mention (tag) someone or '#' for hashTag, then do query or filter with it, you could follow this code belows:
#Override
public void onTextChanged(CharSequence s, int start, int before, final int count) {
if (s.length() > 0) {
// Todo: query mentions
Matcher mentionMatcher = Pattern.compile("#([A-Za-z0-9_-]+)").matcher(s.toString());
// while matching
while (mentionMatcher.find()) {
yourSearchText = s.toString().substring(mentionMatcher.start() + 1, mentionMatcher.end());
// do query with yourSearchText below
}
}
}
It references from the link Multiautocompletetextview, Show autocomplete drop down only when user presses a key after '#' key (like mention in FB app) please scroll down to find #Phuong Sala answer.
I got a solution by myself. I create custom view which extends MultiAutoCompleteTextView and override performFiltering in it. Check if first char is "#", then filter the next chars after it. Otherwise, replace chars with "*" to avoid filtering. Here is my code.
#Override
protected void performFiltering(CharSequence text, int start, int end, int keyCode) {
if (text.charAt(start) == '#') {
start = start + 1;
} else {
text = text.subSequence(0, start);
for (int i = start; i < end; i++) {
text = text + "*";
}
}
super.performFiltering(text, start, end, keyCode);
}

MultiAutoCompleteTextView strings getting "," after selecting string from drop down?

i integrated MultiAutoCompleteTextView in to my dictionary app so now after integrating it.
i got a problem like this as show in second screen shot...
so now i don't want that ","
as show in second screen shots after !
i am getting "," like this
!,
plz help me
thank q
String[] str={"!","\"","#","$","$1","%","'","+",",","/"};
MultiAutoCompleteTextView mt=(MultiAutoCompleteTextView)findViewById(R.id.searchEditText);
mt.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
ArrayAdapter<String> adp=new ArrayAdapter<String>(this,android.R.layout.simple_dropdown_item_1line,str);
mt.setThreshold(1);
mt.setAdapter(adp);
The comma is coming from CommaTokenizer() called in this line mt.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
To remove the comma you need to implement your own Tokenizer. This is an example:
public class SpaceTokenizer implements Tokenizer {
public int findTokenStart(CharSequence text, int cursor) {
int i = cursor;
while (i > 0 && text.charAt(i - 1) != ' ') {
i--;
}
while (i < cursor && text.charAt(i) == ' ') {
i++;
}
return i;
}
public int findTokenEnd(CharSequence text, int cursor) {
int i = cursor;
int len = text.length();
while (i < len) {
if (text.charAt(i) == ' ') {
return i;
} else {
i++;
}
}
return len;
}
public CharSequence terminateToken(CharSequence text) {
int i = text.length();
while (i > 0 && text.charAt(i - 1) == ' ') {
i--;
}
if (i > 0 && text.charAt(i - 1) == ' ') {
return text;
} else {
if (text instanceof Spanned) {
SpannableString sp = new SpannableString(text + " ");
TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
Object.class, sp, 0);
return sp;
} else {
return text + " ";
}
}
}
}
PS: I copied the code from this answer

More than one delimiter for MultiAutoCompleteTextView?

I am using a MultiAutoCompleteTextView which shows suggestions for user input. It only works when the items are separated by one or more spaces, but doesn't when a new line (i.e. button "enter" is pressed) is the delimiter.
The code so far (I think I got it from stackoverflow some time ago):
public class SpaceTokenizer implements Tokenizer {
#Override
public int findTokenStart(CharSequence text, int cursor) {
int i = cursor;
while (i > 0 && text.charAt(i - 1) != ' ') {
i--;
}
while (i < cursor && text.charAt(i) == ' ') {
i++;
}
return i;
}
#Override
public int findTokenEnd(CharSequence text, int cursor) {
int i = cursor;
int len = text.length();
while (i < len) {
if (text.charAt(i) == ' ') {
return i;
} else {
i++;
}
}
return len;
}
#Override
public CharSequence terminateToken(CharSequence text) {
int i = text.length();
while (i > 0 && text.charAt(i - 1) == ' ') {
i--;
}
if (i > 0 && text.charAt(i - 1) == ' ') {
return text;
} else {
if (text instanceof Spanned) {
SpannableString sp = new SpannableString(text + " ");
TextUtils.copySpansFrom((Spanned) text, 0, text.length(),
Object.class, sp, 0);
return sp;
} else {
return text + " ";
}
}
}
}
I tried to implement something like "... || text.charAt(i) == '\n' ..." where I thought appropriate, but that didn't work.
So I would be very thankful for suggestions!
The answer to my question can be found here:
Android and the CommaTokenizer

Categories

Resources