Skip to content
Ari C edited this page Aug 31, 2022 · 14 revisions

Hi!

Over the last 1 plus years, since the initial release of this library, I have spent time adding new features, fixing bugs (at times bugs that were introduced by new features, I know... if only I had time to add test cases), answering questions, and saying thank you to the the wonderful contributors.

Why am I saying this? because I have now reached a point where I need to move on, so I won't be maintaining this project anymore, that is why I wanted to give you a detailed description of the inner-workings of this library so that you can download the code and make it work for your need, and perhaps even make it work with Kotlin (now that it is a first-class language).

How it all started

Back then (when Material design was introduced) I was working on a project which had search as a primary functionality, and I thought that the 'persistent search' concept in the guidelines would be perfect for it. Trouble was, I couldn't find a ready (and suitable) open source solution, so I decided to be the one who will implement it and make it open source.

...

Let's get started

Objective

Make a search view that looks like this when there is no suggestions:

And like this when the search is focused and there are suggestions:

Challenges

  1. Make the suggestions animate down nicely.
  2. Make use of the CardView to get the round corners (CardView handles a lot of backwards compatibility for us, if you don't believe me, start digging into the code) and it is a challenge because CardView doesn't seem to provide an option for having only top or bottom rounded corners, and the search bar and the suggestions section will be two different views, as you'll see.

Solution

Separate the view into two different sections, the search bar section and the suggestions section. The suggestions section will be positioned at the bottom of the search bar by using a LinearLayout. The suggestions section will be a simple FrameLayout that will be invisible at all times, and this layout will hold the CardView that will hold the suggestions RecyclerView. When the view initializes, the CardView will position itself at a translationY of -cardViewHeight that will make it go completely out of the bounds of the suggestions section. When suggestions need to be shown, we will animate down the CardView's translationY so that the items in its child RecyclerView are visible.

To make sense out of all of this, here are some illustrations:

. . .

Figure 1)

When suggestions are showing, but they don't take up all the available height:

Figure 2)

When no suggestions are showing:

Figure 3)

When suggestions take up the full height of the RecyclerView:

Now that you get the overall idea, let's go over some code.

Here is what happens when the client calls swapSuggestions(...):

We update our adapter with the new items and observe the next RecyclerView's layout to make sure that suggestion items have their height already measured. Next, when the layout has finished, we animate the RecyclerView parent's translationY just enough for the suggestions to show. The function that does the animation also returns a boolean indicating if the suggestions take up the full height of the RecyclerView see here. Next, if the suggestions did not take up all the available height of the RecyclerView, we reverse the RecyclerView's layout and we also reverse the suggestions list (provided by the client). This way, the suggestions show from the bottom and the items' order is unaffected.

That basically sums up the core of the library, everything else is pretty standard, so you can figure it out, there are comments where I thought it was warranted.

Another challenge was to get around the aforementioned CardView round corners issue. For that, have a look at some of the comments here.

. . .

Thanks for reading and contributing to this library (and others)!

Clone this wiki locally