0

在Xamarin中,我遇到了AutoCompleteTextView的自定義適配器問題。對AutoCompleteTextView使用自定義適配器的ClassCastException

這裏是我的代碼:

private void SetupAutoCompleteTextViewWithCustomAdapter() 
{ 
    List<CustomItem> customItems = new List<CustomItem>(); 

    CustomItem customItem = new CustomItem(); 
    customItem.Heading = "TestHeading"; 
    customItem.SubHeading = "TestSubHeading"; 
    customItems.Add(customItem); 

    customItem = new CustomItem(); 
    customItem.Heading = "TestHeading 2"; 
    customItem.SubHeading = "TestSubHeading 2"; 
    customItems.Add(customItem); 

    customItem = new CustomItem(); 
    customItem.Heading = "TestHeading 3"; 
    customItem.SubHeading = "TestSubHeading 3"; 
    customItems.Add(customItem); 

    AutoCompleteTextView AutoCompleteTextViewWithCustomAdapter = (AutoCompleteTextView) FindViewById(Resource.Id.AutoCompleteTextView); 
    AutoCompleteTextViewWithCustomAdapter.Adapter = new CustomAdapter (this, customItems); 

} 

這裏是我的自定義適配器:

public class CustomAdapter : BaseAdapter<CustomItem> { 
    List<CustomItem> items; 
    Activity context; 
    public CustomAdapter(Activity context, List<CustomItem> items) 
     : base() 
    { 
     this.context = context; 
     this.items = items; 
    } 
    public override long GetItemId(int position) 
    { 
     return position; 
    } 
    public override CustomItem this[int position] 
    { 
     get { return items[position]; } 
    } 
    public override int Count 
    { 
     get { return items.Count; } 
    } 
    public override View GetView(int position, View convertView, ViewGroup parent) 
    { 
     var item = items[position]; 

     View view = convertView; 
     if (view == null) // no view to re-use, create new 
      view = context.LayoutInflater.Inflate(Resource.Layout.CustomView, null); 
     view.FindViewById<TextView>(Resource.Id.TextViewMapHeading).Text = item.Heading; 
     view.FindViewById<TextView> (Resource.Id.TextViewMapHeading).TextSize = 20; 
     view.FindViewById<TextView>(Resource.Id.TextViewItem).Text = item.SubHeading; 
     view.FindViewById<ImageView>(Resource.Id.Image).SetImageResource(item.ImageResourceId); 

     return view; 
    } 
} 

這裏是我的自定義項目類:

public class CustomItem 
{ 
    public string Heading { get; set; } 
    public string SubHeading { get; set; } 
    public int ImageResourceId { get; set; } 
} 

這裏是我的CustomView佈局文件:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content" 
    android:padding="8dp"> 
    <LinearLayout 
     android:id="@+id/Text" 
     android:orientation="vertical" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:paddingLeft="10dip"> 
     <TextView 
      android:id="@+id/TextViewMapHeading" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:textSize="28sp" /> 
     <TextView 
      android:id="@+id/TextViewItem" 
      android:layout_width="fill_parent" 
      android:layout_height="wrap_content" 
      android:autoLink="all" /> 
    </LinearLayout> 
    <ImageView 
     android:id="@+id/Image" 
     android:layout_width="48dp" 
     android:layout_height="48dp" 
     android:padding="5dp" 
     android:src="@drawable/icon" 
     android:visibility="invisible" 
     android:layout_alignParentRight="true" /> 
</RelativeLayout> 

這裏是我得到的錯誤:

java.lang.ClassCastException:simplemapdemo.CustomAdapter不能 投地android.widget.Filterable

我可以請有一定的幫助得到這個工作?

在此先感謝

+0

在哪一行發生? – nikis

+0

在android.widget.AutoCompleteTextView.setAdapter(AutoCompleteTextView.java:618) – Garry

回答

1

由於用於AutoCompleteTextViewAdapter必須農具Filterable接口,所以修改CustomAdapter類似以下內容:

public class CustomAdapter extends BaseAdapter<CustomItem> implements Filterable { 

    ArrayFilter mFilter; 
    ... 

    // please override other method in BaseAdatper as your need 
    ... 

    @Override 
    public Filter getFilter() { 
     if (mFilter == null) { 
      mFilter = new ArrayFilter(); 
     } 
     return mFilter; 
    } 

    // you can modify the custom Filter used for AutoCompleteTextView as your need 
    private class ArrayFilter extends Filter { 
     @Override 
     protected FilterResults performFiltering(CharSequence prefix) { 
      FilterResults results = new FilterResults(); 

      if (mOriginalValues == null) { 
       synchronized (mLock) { 
        mOriginalValues = new ArrayList<T>(mObjects); 
       } 
      } 

      if (prefix == null || prefix.length() == 0) { 
       ArrayList<T> list; 
       synchronized (mLock) { 
        list = new ArrayList<T>(mOriginalValues); 
       } 
       results.values = list; 
       results.count = list.size(); 
      } else { 
       String prefixString = prefix.toString().toLowerCase(); 

       ArrayList<T> values; 
       synchronized (mLock) { 
        values = new ArrayList<T>(mOriginalValues); 
       } 

       final int count = values.size(); 
       final ArrayList<T> newValues = new ArrayList<T>(); 

       for (int i = 0; i < count; i++) { 
        final T value = values.get(i); 
        final String valueText = value.toString().toLowerCase(); 

        // First match against the whole, non-splitted value 
        if (valueText.startsWith(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)) { 
           newValues.add(value); 
           break; 
          } 
         } 
        } 
       } 

       results.values = newValues; 
       results.count = newValues.size(); 
      } 

      return results; 
     } 

     @Override 
     protected void publishResults(CharSequence constraint, FilterResults results) { 
      //noinspection unchecked 
      mObjects = (List<T>) results.values; 
      if (results.count > 0) { 
       notifyDataSetChanged(); 
      } else { 
       notifyDataSetInvalidated(); 
      } 
     } 
    } 
} 

您可以參考ArrayAdapter的源代碼。

+0

需要使用哪些語句來實現Filterable?另外,我怎樣才能找到自己的呢? – Garry

+0

請參考我的新編輯。此外,你可以git源代碼[這裏](https://android.googlesource.com/platform/frameworks/base/) – FeiFei

+0

我無法解決「可過濾」,我需要使用什麼顯式使用語句? – Garry