本项目的 GitHub 地址:https://github.com/yuqirong/FlexibleSearchBar
关于搜索栏,可以说各种 app 都有不同的样式。影响比较深刻的就有华为应用市场的搜索栏(同样,简书的搜索栏也是类似的)。
而今天,就是带你来实现华为应用市场那样的搜索栏。
我们先放上我们实现的效果图吧:
怎么样,想不想学?
我们先来简述一下实现的思路吧,其实并不复杂。
首先,在搜索栏还未打开时,先确定半径 R ,然后假设一个变量 offset 用来动态改变搜索栏的宽度。如图所示:
所以可以得到一个公式:offset = total width - 2 * R ;
那么显而易见,offset 的取值就在 [0, total width - 2 * R] 之间了。
所以,我们可以借助属性动画来完成这数值的变化。在调用 invalidate()
进行重绘,达到动态增加搜索栏宽度的效果。反之,关闭搜索栏也是同理的。
那么下面就用代码来实现它咯!
attrs
关于自定义的属性,我们可以想到的有搜索栏的背景颜色、搜索栏的位置(左或右)、搜索栏的状态(打开或关闭)等。具体的可以查看下面的 attrs.xml 。根据英文应该能知道对应属性的作用了。
1 | <?xml version="1.0" encoding="utf-8"?> |
constructor
而在构造器中,肯定就是初始化一些 attrs 中的全局变量了,这也不是重点,都是机械式的代码。
1 | public SearchBarView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { |
initAnimator
initAnimator
方法中是两个属性动画,打开和关闭动画。非常 easy 的代码。
1 | private void initAnimator(long duration) { |
onMeasure
同样,onMeasure
中的代码也是很机械的,基本上都是同一个套路了。
1 | @Override |
onDraw
在 onDraw
中先画了搜索栏的背景,然后是搜索栏的图标,最后是搜索栏的提示文字。
画背景的时候,是需要根据搜索栏在左边还是右边的位置来确定值的。
而画图标的时候,是根据搜索栏关闭时那个圆的内切正方形作为 Rect 的。
最后画提示文字没什么好讲的了,都是定死的代码。
1 | @Override |
startOpen、startClose
最后,需要将 startOpen
和 startClose
方法暴露给外部,方便调用。在其内部就是调用两个属性动画而已。
1 | /** |
End
到这也差不多了,该讲的都讲了,这篇写得真 TMD 简洁。至于和 AppBarLayout
的混合使用,见 GitHub 中的代码即可。
有问题的可以在下面留言。没问题的老铁可以来一波 star 。
FlexibleSearchBar:https://github.com/yuqirong/FlexibleSearchBar