大多数app的导航条右边都有一个放大镜图标,你无需花太多时间就能在一个移动app中找到这个搜索按钮。这个图标总是长得很相似,行为也大同小异:点击放大镜图标,然后搜索框被打开。
这样一种标准的UI不是设计师最喜欢的动画方式。但谁说我们就不能做的更好呢?
我们想,“要是一个普通的搜索框打开的同时伴着抖动效果会如何呢?”当看到我们search bar动画最终效果时,我们想到了果冻-由果汁和糖煮成的甜蜜,晶莹剔透的粘稠物体。
看起来很好吃的样子,是吧?让我们来看看 如何在Android上实现toolbar的果冻动画。
我们如何实现Jelly Toolbar动画
toolbar果冻动画看起来很简单,绝大部分是如此。我们创建了一个自定义view,它包含了我们熟知的标准Toolbar,一个包含背景的view,以及一个包含图标的view。其结构如下:
<FrameLayout > <android.support.v7.widget.Toolbar /> <com.yalantis.jellytoolbar.widget.JellyView /> <com.yalantis.jellytoolbar.widget.ContentLayout /></FrameLayout>
JellyView的工作原理
我们决定在Canvas上绘制动画。在向你展示Kotlin的动画源码之前,我们想讲解一下实现的思路。要让view产生抖动,我们使用了一个二阶贝塞尔曲线。(你可能还想看看我们关于绘制贝塞尔曲线的文章)
曲线的形状取决于控制点的位置。让我们看看如何绘制这个view:
override fun onDraw(canvas: Canvas?) { super.onDraw(canvas) redraw(canvas) } private fun redraw(canvas: Canvas?) { paint.shader = gradient path.apply { moveTo(jellyViewWidth, 0f) lineTo(width.toFloat(), 0f) lineTo(width.toFloat(), height.toFloat()) lineTo(jellyViewWidth, height.toFloat()) quadTo(jellyViewWidth - difference, height / 2f, jellyViewWidth, 0f) } canvas?.drawPath(path, paint) path.reset() path.close() }
我们不断的根据difference变量改变二阶贝塞尔曲线的控制点位置。为此我们创建了一个自定义的插值器(interpolator)。下面这个sine函数恰当的代表了果冻类物体的抖动效果:
class JellyInterpolator : Interpolator { override fun getInterpolation(t: Float) = (Math.min(1.0, Math.sin(28 * t - 6.16) / (5 * t - 1.1))).toFloat()}
如何使用这个库?
首先,把JellyToolbar添加到activity的xml布局中:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.yalantis.jellytoolbar.widget.JellyToolbar android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@color/colorPrimary" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingStart="@dimen/activity_horizontal_margin" app:cancelIcon="@drawable/ic_close" app:endColor="@color/colorEnd" app:icon="@drawable/ic_search" app:startColor="@color/colorStart" app:title="@string/str_news_feed" app:titleTextColor="@android:color/white" /></LinearLayout>
然后,把一个JellyListener对象以及内容视图(一个插入到toolbar中的view)。JellyToolbar有一个 getToolbar()方法,它可以让你使用标准Toolbar的所有方法。
public class MainActivity extends AppCompatActivity { private JellyToolbar toolbar; private AppCompatEditText editText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); toolbar = (JellyToolbar) findViewById(R.id.toolbar); toolbar.getToolbar().setLogo(R.drawable.ic_menu); toolbar.setJellyListener(jellyListener); editText = (AppCompatEditText) LayoutInflater.from(this).inflate(R.layout.edit_text, null); editText.setBackgroundResource(R.color.colorTransparent); toolbar.setContentView(editText); } private JellyListener jellyListener = new JellyListener() { @Override public void onCancelIconClicked() { if (TextUtils.isEmpty(editText.getText())) { toolbar.collapse(); } else { editText.getText().clear(); } } };}
要控制动画使用collapse() 和 expand()方法。
共同学习,写下你的评论
评论加载中...
作者其他优质文章