- 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);
}绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论