ViewTransition support multiple View

This commit is contained in:
seven332 committed 2015-05-10 01:53:08 +08:00
1 parent 96f3b027e5
commit d06922cb08
4 files changed
+159 -84

No files matched your search

@@ -17,18 +17,26 @@ package com.hippo.animation;
import android.animation.Animator;
public class SimpleAnimatorListener implements Animator.AnimatorListener {
public abstract class SimpleAnimatorListener implements Animator.AnimatorListener {
private boolean mCanceled;
@Override
public void onAnimationStart(Animator animation) {
mCanceled = false;
}
@Override
public void onAnimationEnd(Animator animation) {
onAnimationEnd(animation, mCanceled);
}
public void onAnimationEnd(Animator animation, boolean canceled) {
}
@Override
public void onAnimationCancel(Animator animation) {
mCanceled = true;
}
@Override
@@ -18,7 +18,7 @@ package com.hippo.effect;
import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.os.Build;
import android.support.annotation.NonNull;
import android.view.RenderNodeAnimator;
import android.view.View;
import com.hippo.animation.SimpleAnimatorListener;
@@ -28,99 +28,166 @@ public class ViewTransition {
private static long ANIMATE_TIME = 300L;
private View mView1;
private View mView2;
private boolean mSwitch = false;
private final View[] mViews;
public ViewTransition(@NonNull View view1, @NonNull View view2) {
mView1 = view1;
mView2 = view2;
private int mShownView = -1;
ViewUtils.setVisibility(view1, View.VISIBLE);
ViewUtils.setVisibility(view2, View.GONE);
}
private Animator mAnimator1;
private Animator mAnimator2;
public void toggle() {
if (mSwitch) {
showFirstView();
} else {
showSecondView();
public ViewTransition(View... views) {
if (views.length < 2) {
throw new IllegalStateException("You must pass view to ViewTransition");
}
for (View v : views) {
if (v == null) {
throw new IllegalStateException("Any View pass to ViewTransition must not be null");
}
}
mViews = views;
showView(0, false);
}
public void showFirstView() {
showFirstView(true);
public void showView(int shownView) {
showView(shownView, true);
}
public void showFirstView(boolean animation) {
if (mSwitch) {
mSwitch = false;
public void showView(int shownView, boolean animation) {
View[] views = mViews;
int length = views.length;
if (shownView >= length || shownView < 0) {
throw new IndexOutOfBoundsException("Only " + length + " view(s) in " +
"the ViewTransition, but attempt to show " + shownView);
}
if (mShownView != shownView) {
int oldShownView = mShownView;
mShownView = shownView;
// Cancel animation
if (mAnimator1 != null) {
mAnimator1.cancel();
}
if (mAnimator2 != null) {
mAnimator2.cancel();
}
if (animation) {
ObjectAnimator oa1 = ObjectAnimator.ofFloat(mView1, "alpha", 0f, 1f);
oa1.setDuration(ANIMATE_TIME);
oa1.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
ViewUtils.setVisibility(mView1, View.VISIBLE);
for (int i = 0; i < length; i++) {
if (i != oldShownView && i != shownView) {
View v = views[i];
v.setAlpha(0f);
ViewUtils.setVisibility(v, View.GONE);
}
});
ObjectAnimator oa2 = ObjectAnimator.ofFloat(mView2, "alpha", 1f, 0f);
oa2.setDuration(ANIMATE_TIME);
oa2.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
ViewUtils.setVisibility(mView2, View.GONE);
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
oa1.setAutoCancel(true);
oa2.setAutoCancel(true);
}
oa1.start();
oa2.start();
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
startAnimationsL(views[oldShownView], views[shownView]);
} else {
startAnimations(views[oldShownView], views[shownView]);
}
} else {
ViewUtils.setVisibility(mView1, View.VISIBLE);
ViewUtils.setVisibility(mView2, View.GONE);
for (int i = 0; i < length; i++) {
View v = views[i];
if (i == shownView) {
v.setAlpha(1f);
ViewUtils.setVisibility(v, View.VISIBLE);
} else {
v.setAlpha(0f);
ViewUtils.setVisibility(v, View.GONE);
}
}
}
}
}
public void showSecondView() {
showSecondView(true);
private void startAnimationsL(final View hiddenView, View shownView) {
RenderNodeAnimator rna1 = new RenderNodeAnimator(RenderNodeAnimator.ALPHA, 0f);
rna1.setTarget(hiddenView);
rna1.setDuration(ANIMATE_TIME);
rna1.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
mAnimator1 = null;
}
@Override
public void onAnimationEnd(Animator animation, boolean canceled) {
super.onAnimationEnd(animation, canceled);
if (!canceled) {
ViewUtils.setVisibility(hiddenView, View.GONE);
mAnimator1 = null;
}
}
});
rna1.start();
mAnimator1 = rna1;
ViewUtils.setVisibility(shownView, View.VISIBLE);
RenderNodeAnimator rna2 = new RenderNodeAnimator(RenderNodeAnimator.ALPHA, 1f);
rna2.setTarget(shownView);
rna2.setDuration(ANIMATE_TIME);
rna2.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
mAnimator2 = null;
}
@Override
public void onAnimationEnd(Animator animation, boolean canceled) {
super.onAnimationEnd(animation, canceled);
if (!canceled) {
mAnimator2 = null;
}
}
});
rna2.start();
mAnimator2 = rna2;
}
public void showSecondView(boolean animation) {
if (!mSwitch) {
mSwitch = true;
if (animation) {
ObjectAnimator oa1 = ObjectAnimator.ofFloat(mView1, "alpha", 1f, 0f);
oa1.setDuration(ANIMATE_TIME);
oa1.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationEnd(Animator animation) {
ViewUtils.setVisibility(mView1, View.GONE);
}
});
ObjectAnimator oa2 = ObjectAnimator.ofFloat(mView2, "alpha", 0f, 1f);
oa2.setDuration(ANIMATE_TIME);
oa2.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
ViewUtils.setVisibility(mView2, View.VISIBLE);
}
});
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
oa1.setAutoCancel(true);
oa2.setAutoCancel(true);
}
oa1.start();
oa2.start();
} else {
ViewUtils.setVisibility(mView1, View.GONE);
ViewUtils.setVisibility(mView2, View.VISIBLE);
private void startAnimations(final View hiddenView, final View shownView) {
ObjectAnimator oa1 = ObjectAnimator.ofFloat(hiddenView, "alpha", 0f);
oa1.setDuration(ANIMATE_TIME);
oa1.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
mAnimator1 = null;
}
}
@Override
public void onAnimationEnd(Animator animation, boolean canceled) {
super.onAnimationEnd(animation, canceled);
if (!canceled) {
ViewUtils.setVisibility(hiddenView, View.GONE);
mAnimator1 = null;
}
}
});
oa1.start();
mAnimator1 = oa1;
ViewUtils.setVisibility(shownView, View.VISIBLE);
ObjectAnimator oa2 = ObjectAnimator.ofFloat(shownView, "alpha", 1f);
oa2.setDuration(ANIMATE_TIME);
oa2.addListener(new SimpleAnimatorListener() {
@Override
public void onAnimationCancel(Animator animation) {
super.onAnimationCancel(animation);
mAnimator2 = null;
}
@Override
public void onAnimationEnd(Animator animation, boolean canceled) {
super.onAnimationEnd(animation, canceled);
if (!canceled) {
mAnimator2 = null;
}
}
});
oa2.start();
mAnimator2 = oa2;
}
}
@@ -180,11 +180,11 @@ public class GalleryListScene extends Scene implements SearchBar.Helper,
switch (mState) {
case STATE_NORMAL:
case STATE_SIMPLE_SEARCH:
mViewTransition.showFirstView(false);
mViewTransition.showView(0, false);
break;
case STATE_SEARCH:
case STATE_SEARCH_SHOW_LIST:
mViewTransition.showSecondView(false);
mViewTransition.showView(1, false);
break;
}
@@ -259,7 +259,7 @@ public class GalleryListScene extends Scene implements SearchBar.Helper,
break;
case STATE_SEARCH:
mState = STATE_NORMAL;
mViewTransition.showFirstView();
mViewTransition.showView(0);
mSearchBar.setState(SearchBar.STATE_NORMAL);
returnSearchBarPosition();
setFabState(FAB_STATE_NORMAL);
@@ -323,7 +323,7 @@ public class GalleryListScene extends Scene implements SearchBar.Helper,
public void onClickAdvanceSearch() {
if (mState == STATE_NORMAL) {
mState = STATE_SEARCH;
mViewTransition.showSecondView();
mViewTransition.showView(1);
mSearchLayout.scrollSearchContainerToTop();
mSearchBar.setState(SearchBar.STATE_SEARCH);
returnSearchBarPosition();
@@ -347,7 +347,7 @@ public class GalleryListScene extends Scene implements SearchBar.Helper,
mSearchDatabase.addQuery(query);
mState = STATE_NORMAL;
mViewTransition.showFirstView();
mViewTransition.showView(0);
mSearchBar.setState(SearchBar.STATE_NORMAL);
returnSearchBarPosition();
setFabState(FAB_STATE_NORMAL);
@@ -249,7 +249,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
switch (oldState) {
default:
case STATE_NORMAL:
mViewTransition.showSecondView(animation);
mViewTransition.showView(1);
mEditText.requestFocus();
mDrawerArrowDrawable.setArrow(animation ? ANIMATE_TIME : 0);
mAddDeleteDrawable.setDelete(animation ? ANIMATE_TIME : 0);
@@ -259,7 +259,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
break;
case STATE_SEARCH:
if (state == STATE_NORMAL) {
mViewTransition.showFirstView(animation);
mViewTransition.showView(0);
mDrawerArrowDrawable.setMenu(animation ? ANIMATE_TIME : 0);
mAddDeleteDrawable.setAdd(animation ? ANIMATE_TIME : 0);
} else if (state == STATE_SEARCH_LIST) {
@@ -269,7 +269,7 @@ public class SearchBar extends CardView implements View.OnClickListener,
case STATE_SEARCH_LIST:
hideImeAndSuggestionsList(animation);
if (state == STATE_NORMAL) {
mViewTransition.showFirstView(animation);
mViewTransition.showView(0);
mDrawerArrowDrawable.setMenu(animation ? ANIMATE_TIME : 0);
mAddDeleteDrawable.setAdd(animation ? ANIMATE_TIME : 0);
}