Fatal Exception ClassCastException with autocompletetextview dropdown on performFiltering
I have a custom performFiltering for a AutoCompleteTextView that fetches new data and filters it:
@Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults filterResults = new FilterResults();
if (null != constraint && constraint.length() >= 2) {
ArrayList<Destination> temporaryDestination = updateArray();
filterResults.count = temporaryDestination.size();
filterResults.values = temporaryDestination;
return filterResults;
} else {
if (destinations != null) {
filterResults.count = destinations.size();
filterResults.values = destinations;
}
return filterResults;
}
}
If I type two letters that retrieve a lot of destinations and scroll down i get a FC and the following stacktrace:
06-22 14:44:07.756: ERROR/AndroidRuntime(2188): FATAL EXCEPTION: main
java.lang.ClassCastException: android.widget.AbsListView$LayoutParams
at android.widget.AutoCompleteTextView.buildDropDown开发者_StackOverflow社区(AutoCompleteTextView.java:1350)
at android.widget.AutoCompleteTextView.showDropDown(AutoCompleteTextView.java:1140)
at android.widget.AutoCompleteTextView.onKeyDown(AutoCompleteTextView.java:714)
at android.view.KeyEvent.dispatch(KeyEvent.java:1256)
at android.view.View.dispatchKeyEvent(View.java:3855)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
at android.view.ViewGroup.dispatchKeyEvent(ViewGroup.java:789)
at com.android.internal.policy.impl.PhoneWindow$DecorView.superDispatchKeyEvent(PhoneWindow.java:1687)
at com.android.internal.policy.impl.PhoneWindow.superDispatchKeyEvent(PhoneWindow.java:1120)
at android.app.Activity.dispatchKeyEvent(Activity.java:2073)
at com.android.internal.policy.impl.PhoneWindow$DecorView.dispatchKeyEvent(PhoneWindow.java:1663)
at android.view.ViewRoot.deliverKeyEventToViewHierarchy(ViewRoot.java:2560)
at android.view.ViewRoot.handleFinishedEvent(ViewRoot.java:2535)
at android.view.ViewRoot.handleMessage(ViewRoot.java:1867)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
If I return a maximum of 5 results it works fine (I simply add the following):
if (null != constraint && constraint.length() >= 2) {
ArrayList<Destination> temporaryDestination = updateArray();
if (temporaryDestination.size()>5) {
temporaryDestination = new ArrayList<Destination>(temporaryDestination.subList(0, 5));
}
filterResults.count = temporaryDestination.size();
filterResults.values = temporaryDestination;
I have tracked the error down to the following in the Android Source code at line 1350 in AutoCompleteTextView that does the following:
if (view != null) {
LinearLayout.LayoutParams hintParams =
(LinearLayout.LayoutParams) view.getLayoutParams();
otherHeights = view.getMeasuredHeight() + hintParams.topMargin
+ hintParams.bottomMargin;
}
}
However I do not understand why this code recieves the wrong class when the results are larger then 5 and you start to scroll. The solution to limit the results to 5 is ugly as I feel that the real problem is still there. Anyone have any suggestions?
Here is the xml layout for the autocomplete items (but no custom dropdown implementation):
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/list_layout"
android:layout_width="fill_parent"
android:layout_height="wrap_content" >
<TextView
android:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:padding="10dp"
android:textSize="16sp"
android:textColor="#000">
</TextView>
</RelativeLayout>
Ok I managed a solution so here goes:
Instead of a custom filter I use a regular Adapter that I update in a onPostExcecute after a asynctask has gotten the new data. On the result I create a new adapter and set it to the autocompletetextview. Also I only perform new searches on 2 chars just to keep the traffic down.
The trick is to get the autocomplete to actually show something since it has no data when the user starts to type. By setting a new adapter and performing .showDropdown it worked, but the data was not filtered to the actual typed data because the user would type more chars after the initial 2.
This was resolved by setting the autocompletetextview text to the text that it has, thus forcing a refresh of the filtering and dropdown data. The key here is to use text from afterTextChange (I am using a textchange listener) use setText and then call setSelection(newText.length()) to place the cursor on the correct place.
The problem that I filed here has not been resolved as I'm doing the datastuff in a new way, it seems that handling the autocomplete data inside the filter is not a good idea because it is threaded and expects immutable data when working, as far as I can tell.
精彩评论