Android: Autocomplete TextView Similar To The Facebook App
First make your EditText into a MultiAutoCompleteTextView. A MultiAutoCompleteTextView allows you to replace certain parts of the text, for example text after '@'.
The you can do something like this:
final MultiAutoCompleteTextView inputEditText = (MultiAutoCompleteTextView) dialog.findViewById(R.id.MyEditText);
String[] COUNTRIES = new String[] { "Belgium", "France", "Italy", "Germany", "Spain" };
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, COUNTRIES);
inputEditText.setAdapter(adapter);
inputEditText.setThreshold(1); //Set number of characters before the dropdown should be shown
//Create a new Tokenizer which will get text after '@' and terminate on ' '
inputEditText.setTokenizer(new 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--;
}
//Check if token really started with @, else we don't have a valid token
if (i < 1 || text.charAt(i - 1) != '@') {
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;
}
});
One "problem" with this is that the popup will appear under the EditText view. To move it up and place it under the text that is currently written you can do something like this:
inputEditText.addTextChangedListener(new TextWatcher() {
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
Layout layout = inputEditText.getLayout();
int pos = inputEditText.getSelectionStart();
int line = layout.getLineForOffset(pos);
int baseline = layout.getLineBaseline(line);
int bottom = inputEditText.getHeight();
inputEditText.setDropDownVerticalOffset(baseline - bottom);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void afterTextChanged(Editable s) {
}
});
Note: This does not currently take care of the dropdown position in the case that there are more lines in the edittext than the edittext can show.
Android AutoCompleteTextView with '@' mentions filtering like twitter and facebook
I ended up using the spyglass library from linkedin which does exactly what I was looking for. It provides a MentionsEditText (that can be customised). I also used a ListPopupWindow to show the suggestions in a list (like an AutoCompleteTextView).
Here is the link...
https://github.com/linkedin/Spyglass
Custom AutoCompletevView like facebook comments field in android
You have to make custom autocompleteview by extending class.. and code mentioned in your question to be changed.
public class CustomAutoComplete extends AutoCompleteTextView {
private String previous = "";
private String seperator = "@";
boolean isState = false;
public CustomAutoComplete(final Context context, final AttributeSet attrs,
final int defStyle) {
super(context, attrs, defStyle);
this.setThreshold(1);
}
public CustomAutoComplete(final Context context, final AttributeSet attrs) {
super(context, attrs);
this.setThreshold(1);
}
public CustomAutoComplete(final Context context) {
super(context);
this.setThreshold(1);
}
/**
* This method filters out the existing text till the separator and launched
* the filtering process again
*/
@Override
protected void performFiltering(final CharSequence text, final int keyCode) {
String filterText = text.toString().trim();
String lastchar = filterText.substring(filterText.length() - 1,
filterText.length());
if (filterText.length() == 1) {
if (lastchar.equals(seperator)) {
isState = true;
} else {
isState = false;
}
}
previous = filterText.substring(0,
filterText.lastIndexOf(getSeperator()) + 1);
filterText = filterText.substring(filterText
.lastIndexOf(getSeperator()) + 1);
if ((lastchar.equals(seperator)) || isState) {
super.performFiltering(filterText, keyCode);
isState = true;
}
}
/**
* After a selection, capture the new value and append to the existing text
*/
@Override
protected void replaceText(final CharSequence text) {
isState = false;
super.replaceText(previous + text);// + getSeperator());
}
public String getSeperator() {
return seperator;
}
public void setSeperator(final String seperator) {
this.seperator = seperator;
}
}
Hope this will help you...
How do I get MultiAutoCompleteTextView tokenizer similar to Facebook app?
Found the solution....
Add this textwatcher to the multiautocompletetextview
private TextWatcher textWather = new TextWatcher() {
int noOfCharAdded=0;int noOfCharDeleted=0;
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
startIdx=start;
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,int after) {
noOfCharAdded=after;
noOfCharDeleted=count;
}
@Override
public void afterTextChanged(Editable s) {
Editable buffer = s;
int start = multiContentText.getSelectionStart()<0?0:multiContentText.getSelectionStart();
int end = multiContentText.getSelectionEnd()<0?0:multiContentText.getSelectionEnd();
if(noOfCharAdded==0 && noOfCharDeleted==1){ //if space is deleted
if (start == end && delPrevText) {
ImageSpan link[] = buffer.getSpans(start, end,ImageSpan.class);
if (link.length > 0) {
buffer.replace(buffer.getSpanStart(link[0]),buffer.getSpanEnd(link[0]),"");
buffer.removeSpan(link[0]);
}
}
delPrevText=true;
multiContentText.setSelection(multiContentText.getText().length());
}
else if(noOfCharAdded==0 && noOfCharDeleted>1){//if the whole word is deleted
if(buffer.length()>0){
if(start<buffer.length()){
delPrevText=false;
if(buffer.charAt(start)==' '){
buffer.replace(start,start+1,"");
}
}
}
}
}
};
search friends like facebook
Try this Simple Code: (Without Using AutoCompleteTextView)
XML:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".SOF_AutoList" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<EditText
android:id="@+id/editText1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Name" >
<requestFocus />
</EditText>
</LinearLayout>
<ListView
android:id="@+id/listView1"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
</ListView>
</LinearLayout>
Java Activity Class:
public class SOF_AutoList extends Activity
{
private ListView listview;
private EditText edttxt;
private ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_sof__auto_list);
ArrayList<String> data = new ArrayList<String>();
for(int i=0;i<10;i++)
{
if(i==0 || i==1 || i==3)
{
data.add("Apple "+(i+1));
}
else if(i==4 || i==5)
{
data.add("Banana "+(i+1));
}
else
{
data.add("CArrot "+(i+1));
}
}
listview = (ListView)findViewById(R.id.listView1);
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, android.R.id.text1,data);
listview.setAdapter(adapter);
edttxt = (EditText)findViewById(R.id.editText1);
edttxt.addTextChangedListener(new TextWatcher()
{
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
// TODO Auto-generated method stub
adapter.getFilter().filter(s);
}
@Override
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
@Override
public void afterTextChanged(Editable s) {
// TODO Auto-generated method stub
}
});
}
}
Android AutoCompleteTextView with Style ExposedDropDownMenu
You can use the color state list resource to change the border color for focused, hovered, or unfocused mode.
Create a color
resource directory under res
, and add an XML file, named border_stroke.xml
. The path of this XML would be res/color/border_stroke.xml
Now, place a selector
in border_stroke.xml
with color values of all modes
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:color="@color/black" android:state_focused="true" />
<item android:color="@color/blue" android:state_hovered="true" />
<item android:color="@color/green" android:state_enabled="false" />
<item android:color="@color/pink" /> <!--unfocused-->
</selector>
Set this border_stroke
as color value of boxStrokeColor
attribute
<com.google.android.material.textfield.TextInputLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:boxStrokeColor="@color/border_stroke"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
...
>
Android - Using AutoCompleteTextView to detect a word next to `@`
In the end, I used a Tokenizer
as found in SO, but I forgot where I found it, sorry!
Here's the code :
multiAutoCompleteTextView.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--;
}
//Check if token really started with @, else we don't have a valid token
if (i < 1 || text.charAt(i - 1) != '@') {
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;
}
});
Related Topics
How to Implement a Gcm Hello World for Android Using Android Studio
Android: How to Get Current Opened Application Name on Screen
Gradle 0.9.+/0.9.2 Error: Unable to Load Class 'Com.Android.Builder.Testing.Api.Deviceprovider'
Broadcast Receiver Not Working in Ics If the App Is Not Started Atleast Once
How to Change Images on Imageview After Some Interval
Why Is My Field 'Null' After Injection? How to Inject My Object
Android SQLite Selection Args[] with Int Values
How to Create Custom Shape Button with Selector in Android
Out of Memory Exception Due to Large Bitmap Size
Embed Activity Feed of a Public Facebook Page Without Forcing User to Login/Allow
Getactionview() of My Menuitem Return Null
Okhttp Response Callbacks on the Main Thread
Change Expandable Indicator in Expandablelistview
How to Implement Google Maps Search by Address in Android
Download and Extract Zip File in Android
Android Studio Image Asset Launcher Icon Background Color