- CompoundButton 源码分析
- LinearLayout 源码分析
- SearchView 源码解析
- LruCache 源码解析
- ViewDragHelper 源码解析
- BottomSheets 源码解析
- Media Player 源码分析
- NavigationView 源码解析
- Service 源码解析
- Binder 源码分析
- Android 应用 Preference 相关及源码浅析 SharePreferences 篇
- ScrollView 源码解析
- Handler 源码解析
- NestedScrollView 源码解析
- SQLiteOpenHelper/SQLiteDatabase/Cursor 源码解析
- Bundle 源码解析
- LocalBroadcastManager 源码解析
- Toast 源码解析
- TextInputLayout
- LayoutInflater 和 LayoutInflaterCompat 源码解析
- TextView 源码解析
- NestedScrolling 事件机制源码解析
- ViewGroup 源码解析
- StaticLayout 源码分析
- AtomicFile 源码解析
- AtomicFile 源码解析
- Spannable 源码分析
- Notification 之 Android 5.0 实现原理
- CoordinatorLayout 源码分析
- Scroller 源码解析
- SwipeRefreshLayout 源码分析
- FloatingActionButton 源码解析
- AsyncTask 源码分析
- TabLayout 源码解析
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
3.fab 的动画
fab 还支持 fab 以动画的方式显现/隐藏,通常和 AppBarLayout 一起使用,可以通过 hide()
/ show()
两个方法控制。
那么动画是如何实现的呢:
private void show(OnVisibilityChangedListener listener, boolean fromUser) { getImpl().show(wrapOnVisibilityChangedListener(listener), fromUser); } private void hide(@Nullable OnVisibilityChangedListener listener, boolean fromUser) { getImpl().hide(wrapOnVisibilityChangedListener(listener), fromUser); }
这里因为要兼容不同版本,所以具体实现也交给了不同的 fab 实现类。3.x 之后很好办,直接使用属性动画,如果是 3.x 之前的话,那么只能使用传统的 Animation 了
以 hide()
为例,使用属性动画较为简单,直接使用 View#animate()
即可链式调用。
@Override void hide(@Nullable final InternalVisibilityChangedListener listener, final boolean fromUser) { if (mIsHiding || mView.getVisibility() != View.VISIBLE) { // A hide animation is in progress, or we're already hidden. Skip the call if (listener != null) { listener.onHidden(); } return; } if (!ViewCompat.isLaidOut(mView) || mView.isInEditMode()) { // If the view isn't laid out, or we're in the editor, don't run the animation mView.internalSetVisibility(View.GONE, fromUser); if (listener != null) { listener.onHidden(); } } else { mView.animate().cancel(); mView.animate() .scaleX(0f) .scaleY(0f) .alpha(0f) .setDuration(SHOW_HIDE_ANIM_DURATION) .setInterpolator(AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR) .setListener(new AnimatorListenerAdapter() { private boolean mCancelled; @Override public void onAnimationStart(Animator animation) { mIsHiding = true; mCancelled = false; mView.internalSetVisibility(View.VISIBLE, fromUser); } @Override public void onAnimationCancel(Animator animation) { mIsHiding = false; mCancelled = true; } @Override public void onAnimationEnd(Animator animation) { mIsHiding = false; if (!mCancelled) { mView.internalSetVisibility(View.GONE, fromUser); if (listener != null) { listener.onHidden(); } } } }); } }
如果使用传统动画的话,则先在 xml 中定义好动画,然后构造 Animation
实例,启动动画。
@Override void hide(@Nullable final InternalVisibilityChangedListener listener, final boolean fromUser) { if (mIsHiding || mView.getVisibility() != View.VISIBLE) { // A hide animation is in progress, or we're already hidden. Skip the call if (listener != null) { listener.onHidden(); } return; } Animation anim = android.view.animation.AnimationUtils.loadAnimation( mView.getContext(), R.anim.design_fab_out); anim.setInterpolator(AnimationUtils.FAST_OUT_LINEAR_IN_INTERPOLATOR); anim.setDuration(SHOW_HIDE_ANIM_DURATION); anim.setAnimationListener(new AnimationUtils.AnimationListenerAdapter() { @Override public void onAnimationStart(Animation animation) { mIsHiding = true; } @Override public void onAnimationEnd(Animation animation) { mIsHiding = false; mView.internalSetVisibility(View.GONE, fromUser); if (listener != null) { listener.onHidden(); } } }); mView.startAnimation(anim); }
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论