Tuesday, 22 January 2013

Animating the SearchView

I’ve been taking a closer look at the SearchView widget. This widget was introduced in Android 3.0 but has also had a few additions and updates to it since then. It was designed to be used mainly in an ActionBar , but it’s also possible to use it within any layout.

One of the cool things about the SearchView is that it can be collapsed (iconified) so that it only takes a small amount of space, and when pressed it can go into an expanded state so that text can be entered and searched

Collapsing and expanding the SearchView works fine, but for me something immediately did not feel right. If you try this yourself you’ll notice that there is no transition animation between the collapsed and expanded states. Things just disappear and appear, it’s like a magician's trick without the puff of smoke.

To make things better it would be good if there were some animations when collapsing and expanding the SearchView, maybe a slide in and out. So after a bit of digging around I noticed that the SearchView essentially is a Layout that contains a few LinearLayouts.

Since Android 3.0 it’s been possible to animate layout changes within a LinearLayout by setting an attribute called animateLayoutChanges. When this is set, removing a View from the layout will cause it to fade out and the remaining views will slide in to fill the empty space left by the removed view.  Adding a view will cause existing views to slide out of the way to make room for the new view.

So in theory we could just set this attribute on a LinearLayout in the SearchView and our transitions between the collapse and expand state will be animated. Not quite, since the LinearLayout is within the SearchView we do not have access to the XML so we need to do the equivalent in Java. We can do this by setting a LayoutTransistion on the LinearLayout within the search.  There’s a little more work than usual to get a reference to this LinearLayout, but once we have done that setting the layout transition is just one line of code. Here’s the code to do this:


SearchView searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
//Get the ID for the search bar LinearLayout
int searchBarId = searchView.getContext().getResources().getIdentifier("android:id/search_bar", null, null);
//Get the search bar Linearlayout
LinearLayout searchBar = (LinearLayout) searchView.findViewById(searchBarId);
//Give the Linearlayout a transition animation.
searchBar.setLayoutTransition(new LayoutTransition());

With these few lines of code we now have an animated expand and collapse for the SearchView, this is how it looks:

This is a video of the animations running in an emulator. On a real device the animations run much more smoothly. It’s not perfect, but its a fair improvement for not much effort. To make things even better it would also be nice to animate the adding and removing of buttons once the SearchView is in the expanded state. Unfortunately this is not something that can be done with a few lines of code. It’s most likely that to achieve this a new SearchView would have to be written with built in support for animations. Maybe that could be another blog post.