Autocompletetextview Custom Arrayadapter & Filter Performance
Solution 1:
This is coming fairly late, however I thought I'd weigh in on your problem...mostly because the rather scaring things occurring with your implementation. To answer your immediate question, there's not much you can easily do to avoid the full ArrayList
iteration when filtering. If you need something faster, you'll need to look into pre-processing your data into something with faster search times. AutoComplete Algorithm?.
I have a general rule of thumb for customizing the ArrayAdapter
filtering logic. Don't do it. Whenever you run into this situation, the correct solution is to roll your own adapter solution (Using BaseAdapter
)...or find a 3rd party solution that allows you too. Part of the issue is that internally the ArrayAdapter
has it's own two lists for filtering and it's own internal synchronized lock. Your AutoCompleteAdapter
is exposing a ton of mutators, all of which synchronize on an object you can't sync on. That means you risk concurrency issues if the adapter is mutated while filtering is occurring.
As it stands with your code, the ArrayAdapter
is linked up with your productsAll
list. Any mutations, accessors, methods etc will always reference that list. At first I was surprised your solution worked! Then I realized you aren't using getItem
as is the norm. I imagine you are completely neglecting all the other ArrayAdapter
methods, else you'd have seen rather strange behavior. If that's the case, ArrayAdapter
isn't really doing anything for you and you're loading up this huge class for nothing. Would be trivial to switch it out with BaseAdapter
.
In fact I'm surprised you aren't seeing other strange problems. For instance, no matter what your filtered list shows, your adapter is always registering the productsAll
list count instead of the productsShown
count. Which may be why you have all these index out of bounds checks? Typically not needed.
I'm also surprised your filtering operation updates the list since you fail to invoke notifyDataSetChanged
when finished.
Next big problem, you should never nest adapters. I'm usually advocating this because people embed ListViews
...which is another no no of itself. This is the first I've heard about nesting with AutoCompleteTextView
though. Slightly different situation, yet I'd still say this is a bad idea. Why? There's no guarantee how many times getView
will be invoked for a given position. It could call it once...it could call it 4 times...or more. So imagine recreating your adapter 4 times per item. Even if only 10 items display at a time, you're looking at 40 instantiations of your custom adapter! I sure hope you figured out a way to recycle those adapters to lower that number.
However considering you aren't using the ViewHolder
I'm assuming you don't even know about the recycling behavior? ViewHolder
is a must do for any adapter. It single handily will provide an enormous performance boast. Right now, you are creating a new view with every getView
invocation and ignoring any of the recycled views provided. There a million examples online that show and explain the ViewHolder
. Here's one such link.
Side note, ArrayAdapter
already implements Filterable
. Re-adding the implements in your custom adapter is not needed.
To sum up:
- Implement
BaseAdapter
instead - Don't embed adapters. Find a different way to display your UI without requiring multiple
AutoCompleteTextViews
inside of aListView
. - Can't really improve your filtering logic without some heavy data pre-processing.
- Use ViewHolder paradigm.
Must watch video from Google I/O about ListViews and adapters.
Here's some further readings about the ArrayAdapter
.
Post a Comment for "Autocompletetextview Custom Arrayadapter & Filter Performance"