2013-06-06 22 views
8

Gibt es eine einfache Möglichkeit, ein 2 TextView Dropdown auf eine AutoCompleteTextView festzulegen.So fügen Sie einen benutzerdefinierten Adapter zu einer AutoCompleteTextView hinzu

Es gibt android.R.layout.two_line_list_item Welche ich keine Beispiele finden konnte, wie man verwendet.

Also habe ich versucht, dies:

public class TwoLineDropdownAdapter extends BaseAdapter { 

    private LayoutInflater mInflater = null; 
    private Activity activity; 
    public ArrayList<TwoLineDropDown> values = new ArrayList<TwoLineDropDown>(); 

    public TwoLineDropdownAdapter(Activity a, ArrayList<TwoLineDropDown> items) { 

     values = items; 
     activity = a; 
     mInflater = (LayoutInflater) activity 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    public int getCount() { 

     return values.size(); 
    } 

    public TwoLineDropDown getItem(int position) { 

     return values.get(position); 
    } 

    public long getItemId(int position) { 

     return position; 
    } 

    public static class ViewHolder { 

     public TextView title; 
     public TextView description; 
    } 

    public View getView(final int position, View convertView, ViewGroup parent) { 

     ViewHolder holder; 

     if (convertView == null) { 

      holder = new ViewHolder(); 

      convertView = mInflater.inflate(R.layout.dropdown_text_twoline, 
        parent, false); 
      holder.title = (TextView) convertView 
        .findViewById(R.id.text1); 
      holder.description = (TextView) convertView 
        .findViewById(R.id.text2); 

      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     return convertView; 
    } 

    public void add(TwoLineDropDown ei) { 

     values.add(ei); 
    } 
} 

Aber ich vor einem Problem hier:

TwoLineDropdownAdapter AutoCompleteAdapter = new TwoLineDropdownAdapter(this, items); 
myAutoComplete.setAdapter(AutoCompleteAdapter); 

, während der Adapter Einstellung heißt es:

Gebundene Miss Übereinstimmung: Die generische Methode setAdapter (T) vom Typ AutoCompleteTextView gilt nicht für die Argumente (TwoLineDropdownAdapter). Der abgeleitete Typ TwoLineDropdownAdapter ist kein gültiger Ersatz für den beschränkten Parameter

Wie dieses Problem zu lösen?

danken Ihnen

Antwort

7

der Dokumentation nach, die abgeleitete Art von setAdapter in AutoCompleteTextView ist:

<T extends ListAdapter & Filterable> void setAdapter(T adapter) 

Ihr Adapter ein ListAdapter sein muss (die BaseAdapter ist, so weit so gut) und ein Filterbare , welcher BaseAdapter nicht ist, noch ist Ihre Adapterimplementierung. Ich würde eine ArrayAdapter erweitern, die Filterbare ist, nicht zu erwähnen, würde die Implementierung vereinfachen (einige Ihrer Methoden duplizieren Methoden des ArrayAdapter für das gleiche Ergebnis):

public class TwoLineDropdownAdapter extends ArrayAdapter<TwoLineDropDown> { 

    private LayoutInflater mInflater = null; 
    private Activity activity; 

    public TwoLineDropdownAdapter(Activity a, ArrayList<TwoLineDropDown> items) { 
     super(a, 0, items); 
     activity = a; 
     mInflater = (LayoutInflater) activity 
       .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 
    } 

    public static class ViewHolder { 

     public TextView title; 
     public TextView description; 
    } 

    public View getView(final int position, View convertView, ViewGroup parent) { 

     ViewHolder holder; 

     if (convertView == null) { 

      holder = new ViewHolder(); 

      convertView = mInflater.inflate(R.layout.dropdown_text_twoline, 
        parent, false); 
      holder.title = (TextView) convertView 
        .findViewById(R.id.text1); 
      holder.description = (TextView) convertView 
        .findViewById(R.id.text2); 

      convertView.setTag(holder); 
     } else { 
      holder = (ViewHolder) convertView.getTag(); 
     } 

     return convertView; 
    } 
} 
+8

Ich habe diese Methode angewendet, jedoch erscheint keine automatische Vervollständigung. – tony9099

+0

können Sie überschreiben "erweitert ListAdapter & Filterable" zu BaseAdapter?, Sage ich: Adapter in Adapter? – delive

+0

@delive Sie können "ListAdapter" mit der gewünschten Unterklasse ersetzen. – njzk2

15

Hier-Code ist für mich arbeiten,

Dieser Adapter wird in autocompletetextview Set

AutoCompleteTextView etProductSearch = (AutoCompleteTextView)getView().findViewById(R.id.edtSearchBoxTakeOrder); 
ProductSearchAdapter adapter = new ProductSearchAdapter(getActivity(), android.R.layout.simple_dropdown_item_1line, productList); 
etProductSearch.setAdapter(adapter); 

ProductSearchAdapter Klasse

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; 

public class ProductSearchAdapter extends ArrayAdapter<ProductDataModel> { 
    private ArrayList<ProductDataModel> items; 
    private ArrayList<ProductDataModel> itemsAll; 
    private ArrayList<ProductDataModel> suggestions; 
    private int viewResourceId; 

    @SuppressWarnings("unchecked") 
    public ProductSearchAdapter(Context context, int viewResourceId, 
      ArrayList<ProductDataModel> items) { 
     super(context, viewResourceId, items); 
     this.items = items; 
     this.itemsAll = (ArrayList<ProductDataModel>) items.clone(); 
     this.suggestions = new ArrayList<ProductDataModel>(); 
     this.viewResourceId = viewResourceId; 
    } 

    public View getView(int position, View convertView, ViewGroup parent) { 
     View v = convertView; 
     if (v == null) { 
      LayoutInflater vi = (LayoutInflater) getContext().getSystemService(
        Context.LAYOUT_INFLATER_SERVICE); 
      v = vi.inflate(viewResourceId, null); 
     } 
     ProductDataModel product = items.get(position); 
     if (product != null) { 
       TextView productLabel = (TextView) v.findViewById(android.R.id.text1); 
      if (productLabel != null) { 
       productLabel.setText(product.getProductName()); 
      } 
     } 
     return v; 
    } 

    @Override 
    public Filter getFilter() { 
     return nameFilter; 
    } 

    Filter nameFilter = new Filter() { 
     public String convertResultToString(Object resultValue) { 
      String str = ((ProductDataModel) (resultValue)).getProductName(); 
      return str; 
     } 

     @Override 
     protected FilterResults performFiltering(CharSequence constraint) { 
      if (constraint != null) { 
       suggestions.clear(); 
       for (ProductDataModel product : itemsAll) { 
        if (product.getProductName().toLowerCase() 
          .startsWith(constraint.toString().toLowerCase())) { 
         suggestions.add(product); 
        } 
       } 
       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) { 
      @SuppressWarnings("unchecked") 
      ArrayList<ProductDataModel> filteredList = (ArrayList<ProductDataModel>) results.values; 
      if (results != null && results.count > 0) { 
       clear(); 
       for (ProductDataModel c : filteredList) { 
        add(c); 
       } 
       notifyDataSetChanged(); 
      } 
     } 
    }; 

} 
+0

Danke! Das war sehr hilfreich! Ich hatte ein Problem - Dropdown-Liste in meiner AutoCompleteTextView nicht angezeigt und GetView-Methode meines benutzerdefinierten Adapters wurde nicht aufgerufen. Alles was ich tun musste, war die getFilter-Methode wie in diesem Beispiel hinzuzufügen –

0

Ich glaube, dass der einfachste Ansatz ist, SimpleAdapter zu erweitern.

public class MyAdapter extends android.widget.SimpleAdapter { 

    static ArrayList<Map<String, String>> toMapList(Collection<MyObject> objectsCollection) { 
     ArrayList<Map<String, String>> objectsList = new ArrayList<Map<String, String>>(objectsCollection.size()); 
     for (MyObject obj : objectsCollection) { 
      Map<String, String> map = new HashMap<String, String>(); 
      map.put("name", obj.getName()); 
      map.put("details", obj.getDetails()); 
      objectsList.add(map); 
     }; 
     return objectsList; 
    } 

    public MyAdapter(Context context, Collection<MyObject> objects) { 

     super(context, toMapList(objects), 
       R.layout.auto_complete_layout, new String[] {"name", "description"}, new int[] {R.id.name, R.id.description}); 
    } 
} 

Der größte Nachteil ist, dass diese Kandidaten basierend bringen wird auf jedem Leerzeichen getrennte Wort in entweder Namen oder die Beschreibung. Wenn Sie ein weiteres Feld zu Ihrem auto_complete_layout hinzufügen, wird es auch an der Zuordnung beteiligt sein.

Daher beendete ich mit dem Umschreiben der SimpleAdapter, um meine Bedürfnisse besser zu erfüllen, eine erhebliche Menge der Basisklasse Overhead entfernen, die für meinen Anwendungsfall nicht relevant war. Aber die paar Zeilen oben geben Ihnen einen guten Start und bieten einen soliden Hinweis auf die Anpassung von.

Verwandte Themen