Affichage des résultats de la liste déroulante AutoCompleteTextView
-
21-12-2019 - |
Question
Dans Xamarin, quand j'ai un AutoCompleteTextView
ou un MultiAutoCompleteTextView
avec une liste déroulante, la recherche peut-elle être effectuée pour les occurrences de chaîne qui apparaissent à mi-chemin de l'élément de chaîne ?
Par exemple, si j'ai le tableau de chaînes suivant :
String[] countries = new string[] { "Item1", "Item2", "Item3", "Item4", "Item5" };
Et je tape "Ite" dans le AutoCompleteTextView
ou un MultiAutoCompleteTextView
, tous les éléments ci-dessus s'afficheront.
Ma question concerne le tableau de chaînes suivant :
String[] countries = new string[] { "1abcd", "2abdc", "1234", "Item42abcd", "Item5" };
Est-il possible de taper "abcd" dans le champ AutoCompleteTextView
ou un MultiAutoCompleteTextView
, et ce qui suit s'affichera :
"1abcd", "2abdc", "Item42abcd"
La solution
J'essaie de garder mon code compatible multiplateforme, j'utilise donc généralement un adaptateur basé sur ObservableCollection et sous Android, il implémente à la fois IListAdapter et ISpinnerAdapter.Cela permet d'éviter les problèmes de performances avec des ensembles de données volumineux.Voici un petit code de démonstration pour les fonctionnalités de base en utilisant simplement EditText et un ArrayAdapter de base :
[Activity (Label = "SearchBox", MainLauncher = true)]
public class MainActivity : Activity
{
private readonly string[] countries = { "1abcd", "2abdc", "1234", "Item42abcd", "Item5" };
protected override void OnCreate(Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
var editText = this.FindViewById<EditText> (Resource.Id.editText1);
var listView = this.FindViewById<ListView> (Resource.Id.listView1);
listView.Adapter = new ArrayAdapter (this, Resource.Layout.ListItem, countries);
editText.TextChanged += (sender, e) => listView.Adapter =
new ArrayAdapter (
this,
Resource.Layout.ListItem,
countries.Where (a => a.Contains (editText.Text)).ToArray ());
}
}
Autres conseils
Vous devez créer votre propre adaptateur et filtrer vous-même, par défaut l'adaptateur fonctionne avec startsWith
, tu dois le changer contains
.
L’exemple complet ici.
public class AutoCompleteAdapter extends ArrayAdapter<String> implements Filterable {
private ArrayList<String> fullList;
private ArrayList<String> mOriginalValues;
private ArrayFilter mFilter;
private MainActivity mActivity;
public AutoCompleteAdapter(MainActivity activity, int resource, List<String> objects) {
super(activity, resource, objects);
fullList = (ArrayList<String>) objects;
mOriginalValues = new ArrayList<String>(fullList);
mActivity = activity;
}
@Override
public int getCount() {
return fullList.size();
}
@Override
public String getItem(int position) {
return fullList.get(position);
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
return super.getView(position, convertView, parent);
}
@Override
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ArrayFilter();
}
return mFilter;
}
@Override
public View getDropDownView(int position, View convertView, ViewGroup parent) {
TextView v = (TextView) super.getView(position, convertView, parent);
if (v == null) {
v = new TextView(mActivity);
}
v.setText(fullList.get(position));
v.setTextColor(mActivity.getResources().getColor(R.color.textColor));
v.setTextSize(mActivity.getResources().getDimension(R.dimen.my_orders_spinner_text_size));
v.setPadding(
(int)mActivity.getResources().getDimension(R.dimen.my_orders_spinner_text_padding),
(int)mActivity.getResources().getDimension(R.dimen.my_orders_spinner_text_padding),
(int)mActivity.getResources().getDimension(R.dimen.my_orders_spinner_text_padding),
(int)mActivity.getResources().getDimension(R.dimen.my_orders_spinner_text_padding));
return v;
}
private class ArrayFilter extends Filter {
private Object lock;
@Override
protected FilterResults performFiltering(CharSequence prefix) {
FilterResults results = new FilterResults();
if (mOriginalValues == null) {
synchronized (lock) {
mOriginalValues = new ArrayList<String>(fullList);
}
}
if (prefix == null || prefix.length() == 0) {
synchronized (lock) {
ArrayList<String> list = new ArrayList<String>(mOriginalValues);
results.values = list;
results.count = list.size();
}
} else {
final String prefixString = prefix.toString().toLowerCase();
ArrayList<String> values = mOriginalValues;
int count = values.size();
ArrayList<String> newValues = new ArrayList<String>(count);
for (int i = 0; i < count; i++) {
String item = values.get(i);
if (item.toLowerCase().contains(prefixString)) {
newValues.add(item);
}
}
results.values = newValues;
results.count = newValues.size();
}
return results;
}
@SuppressWarnings("unchecked")
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if(results.values!=null){
fullList = (ArrayList<String>) results.values;
}else{
fullList = new ArrayList<String>();
}
if (results.count > 0) {
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
}
}
- Prendre des chaînes de suggestion dans un élément de nom de tableau.Prendre une référence AutoCleTleTextView du fichier Auto_Complete_string.xml.Ajout d'un tableau d'éléments à l'adaptateur et ajout d'un adaptateur à AutoCompleteTextView.
Mise en œuvre
public class AutoCompleteString extends Activity implements OnItemClickListener,
OnItemSelectedListener {
// Initialize variables
AutoCompleteTextView textView=null;
private ArrayAdapter<String> adapter;
//These values show in autocomplete
String item[]={
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"
};
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.auto_complete_string);
// Initialize AutoCompleteTextView values
// Get AutoCompleteTextView reference from xml
textView = (AutoCompleteTextView) findViewById(R.id.Months);
//Create adapter
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_dropdown_item_1line, item);
textView.setThreshold(1);
//Set adapter to AutoCompleteTextView
textView.setAdapter(adapter);
}
}