基于此示例
我使用支持设计库创建了一个工厂来重新创建相同的操作。揭示和工厂动画运作良好,但现在我遇到了两个问题:
1)我的工厂包含一个图标。当fab启动动画时(就像在gif中一样),图标会变成炮轰,因为它会更改scaleX
和scaleY
。那么有办法防止这种情况吗?
2)该示例创建了动画,但它并没有解释如何反转显示...我希望onKeyDown()内容被反复出现并再次出现在工厂中。
这是github项目https://github.com/saulmm/Curved-Fab-Reveal-Example 这里是我使用的代码:
首先我的工厂在布局中:
<FrameLayout
android:id="@+id/fab_container"
android:layout_below="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="-30dp"
android:elevation="2dp"
>
<include
android:id="@+id/voice_content"
android:layout_width="match_parent"
android:layout_height="match_parent"
layout="@layout/voice_content_layout" />
<android.support.design.widget.FloatingActionButton
android:id="@+id/myFAB"
android:transitionName="button_fab"
app:backgroundTint="@color/colorAccent"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_mic_white_24dp"
app:elevation="2dp"
app:borderWidth="0dp"
android:layout_marginRight="16dp"
android:layout_marginBottom="16dp"
android:layout_gravity="bottom|right"
android:layout_alignParentBottom="true"
android:layout_alignParentEnd="true"
android:onClick="onFabPressed" />
</FrameLayout>
这是Java代码的其余部分:
public void onFabPressed(View view) {
final float startX = myFab.getX();
AnimatorPath path = new AnimatorPath();
path.moveTo(0, 0);
path.curveTo(-200, 200, -400, 100, -600, 50);
final ObjectAnimator anim = ObjectAnimator.ofObject(this, "fabLoc",
new PathEvaluator(), path.getPoints().toArray());
anim.setInterpolator(new AccelerateInterpolator());
anim.setDuration(ANIMATION_DURATION);
anim.start();
anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
if (Math.abs(startX - myFab.getX()) > MINIMUN_X_DISTANCE) {
if (!mRevealFlag) {
mFabContainer.setY(mFabContainer.getY() + mFabSize / 2);
myFab.animate()
.scaleXBy(SCALE_FACTOR)
.scaleYBy(SCALE_FACTOR)
.setListener(mEndRevealListener)
.setDuration(ANIMATION_DURATION);
mRevealFlag = true;
}
}
}
});
}
private AnimatorListenerAdapter mEndRevealListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
super.onAnimationEnd(animation);
myFab.setVisibility(View.INVISIBLE);
mFabContainer.setBackgroundColor(getResources().getColor(R.color.colorAccent));
for (int i = 0; i < voiceContentLayout.getChildCount(); i++) {
View v = voiceContentLayout.getChildAt(i);
ViewPropertyAnimator animator = v.animate()
.scaleX(1).scaleY(1)
.setDuration(ANIMATION_DURATION);
animator.setStartDelay(i * 50);
animator.start();
}
}
};
/**
* We need this setter to translate between the information the animator
* produces (a new "PathPoint" describing the current animated location)
* and the information that the button requires (an xy location). The
* setter will be called by the ObjectAnimator given the 'fabLoc'
* property string.
*/
public void setFabLoc(PathPoint newLoc) {
myFab.setTranslationX(newLoc.mX);
if (mRevealFlag)
myFab.setTranslationY(newLoc.mY - (mFabSize / 2));
else
myFab.setTranslationY(newLoc.mY);
}