问题
I have implemented AutoCompleteTextView
as follows:
MainActivity.java
...
public static String[] myData=new String[]{"Africa (AF)","America (AFM)","Apple (AMP)"};
text=(AutoCompleteTextView)v.findViewById(R.id.first_state);
ArrayAdapter adapter = new ArrayAdapter(getActivity(),R.layout.autocompletetextview_row,R.id.textViewItem,myData);
text.setAdapter(adapter);
text.setThreshold(1);
text.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View view, int position, long rowId) {
selected_station = (String)parent.getItemAtPosition(position);
//TODO Do something with the selected text
}
});
In layout of AutoCompleteTextView
:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFFFFF"
android:padding="10dp" >
<TextView
android:id="@+id/textViewItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:text="Item name here..."
android:textColor="#000000"
android:textSize="20sp" />
</RelativeLayout>
When I type like "af..", it shows me Africa (AF) to select but not America (AFM).
The data is just an example data. it's not that I am using AutoCompleteTextView
for just 3 items.
EDIT: when I remove the parentheses, it works properly. But I need to keep the parentheses for further use.
回答1:
The default implementation of the filter for ArrayAdapter
is searching the beginning of words (separated by space), I mean it uses startsWith
. You will need to implement an ArrayFilter
which uses contains
together with startsWith
.
Your issue will be solved by the following steps:
- Download the
ArrayAdapter.java
file from here - Add that file into the project (you can refactor by renaming file to
CustomArrayAdapter.java
, for example). In the file, you will find a private class
ArrayFilter
. Then, addvalueText.contains(prefixString)
andwords[k].contains(prefixString)
as the following:if (valueText.startsWith(prefixString) || valueText.contains(prefixString)) { newValues.add(value); } else { final String[] words = valueText.split(" "); final int wordCount = words.length; // Start at index 0, in case valueText starts with space(s) for (int k = 0; k < wordCount; k++) { if (words[k].startsWith(prefixString) || words[k].contains(prefixString)) { newValues.add(value); break; } } }
Use that customized
ArrayAdapter
for yourAutoCompleteTextView
And here is the result screenshot:
Hope this helps!
回答2:
An answer, provided by @BNK, is correct. However, I would like to give a similar solution, which doesn't require the whole ArrayAdapter
class file. Instead, we will just extend that class and override its only 2 methods: getView()
and getFilter()
. So, define your auto complete class:
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.List;
public class AutoSuggestAdapter extends ArrayAdapter
{
private Context context;
private int resource;
private List<String> items;
private List<String> tempItems;
private List<String> suggestions;
public AutoSuggestAdapter(Context context, int resource, List<String> items)
{
super(context, resource, 0, items);
this.context = context;
this.resource = resource;
this.items = items;
tempItems = new ArrayList<String>(items);
suggestions = new ArrayList<String>();
}
@Override
public View getView(int position, View convertView, ViewGroup parent)
{
View view = convertView;
if (convertView == null)
{
LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(resource, parent, false);
}
String item = items.get(position);
if (item != null && view instanceof TextView)
{
((TextView) view).setText(item);
}
return view;
}
@Override
public Filter getFilter()
{
return nameFilter;
}
Filter nameFilter = new Filter()
{
@Override
public CharSequence convertResultToString(Object resultValue)
{
String str = (String) resultValue;
return str;
}
@Override
protected FilterResults performFiltering(CharSequence constraint)
{
if (constraint != null)
{
suggestions.clear();
for (String names : tempItems)
{
if (names.toLowerCase().contains(constraint.toString().toLowerCase()))
{
suggestions.add(names);
}
}
FilterResults filterResults = new FilterResults();
filterResults.values = suggestions;
filterResults.count = suggestions.size();
return filterResults;
}
else
{
return new FilterResults();
}
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results)
{
List<String> filterList = (ArrayList<String>) results.values;
if (results != null && results.count > 0)
{
clear();
for (String item : filterList)
{
add(item);
notifyDataSetChanged();
}
}
}
};
}
Define auto complete view in XML for example:
<AutoCompleteTextView
android:id="@+id/autoComplete"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="Enter some text ..."/>
And use it:
AutoCompleteTextView autoComplete = (AutoCompleteTextView) findViewById(R.id.autoComplete);
List <String> stringList = new ArrayList<String>();
stringList.add("Black");
stringList.add("White");
stringList.add("Yellow");
stringList.add("Green");
stringList.add("Blue");
stringList.add("Brown");
stringList.add("Orange");
stringList.add("Pink");
stringList.add("Violet");
stringList.add("Cyan");
stringList.add("LightBlue");
AutoSuggestAdapter adapter = new AutoSuggestAdapter(this, android.R.layout.simple_list_item_1, stringList);
autoComplete.setAdapter(adapter);
// specify the minimum type of characters before drop-down list is shown
autoComplete.setThreshold(1);
回答3:
Just manually show the drop-down via autoCompleteTextView.showDropDown()
everywhere you want.
For example:
autoCompleteTextView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
acSrcCity.showDropDown();
return false;
}
});
回答4:
In your case, you could use String.contains
instead of String.startsWith
.
See this question: custom-autocompletetextview-behavior
回答5:
if you are wanna add the data in
String[] arr=new String[100];
then its wrong. You can do the same work as in form of ArrayList but remember you will never put here a Getter/Setter class. Just simply declare it. See this example.
Declare in main partition:
ArrayList<String>arr=new ArrayList<>();
and then initilize it in this way:
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = (JSONObject) jsonArray.get(i);
String imei = jsonObject1.getString("imei");
String name = jsonObject1.getString("name");
String my_pic = jsonObject1.getString("my_pic");
String email = jsonObject1.getString("email");
arr.add(name);
}
adapter= new ArrayAdapter<>
(this, android.R.layout.select_dialog_item, arr);
autoCompleteText.setThreshold(1);//will start working from first character
autoCompleteText.setAdapter(adapter);//setting the adapter data into the AutoCompleteTextView
autoCompleteText.setTextColor(Color.RED);
}
I hope this will work for you.
来源:https://stackoverflow.com/questions/32926034/autocompletetextview-not-completing-words-inside-parentheses