diff --git a/.gitignore b/.gitignore
index c6cbe56..c88a4b6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,8 +1,7 @@
*.iml
.gradle
/local.properties
-/.idea/workspace.xml
-/.idea/libraries
+.idea
.DS_Store
/build
/captures
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index f0b7884..c3431c1 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -10,16 +10,9 @@
android:id="@+id/thumb"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:background="@mipmap/profile_background"
app:menu_direction="bottom"
app:scale_ratio=".38">
-
-
-
-
-
* Created by hitomi on 2016/8/26.
@@ -21,349 +21,345 @@
*/
public class ThumbnailAnimator {
- private final Interpolator interpolator = new OvershootInterpolator();
-
- /**
- * 缩略图菜单
- */
- private ThumbnailMenu thumbnailMenu;
-
- /**
- * 用于放置缩略图菜单的容器 ScrollView
- */
- private final FrameLayout scrollLayout;
-
- /**
- * 用于放置缩略图菜单的容器 ViewGroup
- */
- private ThumbnailContainer container;
-
- /**
- * Fragment 容器布局集合
- */
- private List tranLayoutList;
-
- /**
- *菜单关闭时的监听器
- */
- private ThumbnailMenu.OnThumbnailMenuCloseListener onMenuCloseListener;
-
- /**
- * 菜单方向
- */
- private int direction;
-
- private boolean init = true;
-
- public ThumbnailAnimator(int direction, ThumbnailMenu thumbnailMenu, List tranLayoutList) {
- this.direction = direction;
- this.thumbnailMenu = thumbnailMenu;
- this.tranLayoutList = tranLayoutList;
-
- scrollLayout = (FrameLayout) thumbnailMenu.findViewWithTag(ThumbnailMenu.TAG_SCROLL_LAYOUT);
- container = (ThumbnailContainer) scrollLayout.getChildAt(0);
+ private final Interpolator interpolator = new OvershootInterpolator();
+ /**
+ * 菜单是否打开
+ */
+ private boolean isOpen = false;
+ /**
+ * 是否正在执行动画
+ */
+ private boolean mIsInAnimation = false;
+ /**
+ * 缩略图菜单
+ */
+ private ThumbnailMenu thumbnailMenu;
+
+ /**
+ * 用于放置缩略图菜单的容器 ScrollView
+ */
+ private final FrameLayout scrollLayout;
+
+ /**
+ * 用于放置缩略图菜单的容器 ViewGroup
+ */
+ private ThumbnailContainer container;
+
+ /**
+ * Fragment 容器布局集合
+ */
+ private List tranLayoutList;
+
+ /**
+ * 菜单关闭时的监听器
+ */
+ private ThumbnailMenu.OnThumbnailMenuCloseListener onMenuCloseListener;
+
+ /**
+ * 菜单方向
+ */
+ private int direction;
+
+ private boolean init = true;
+
+ public ThumbnailAnimator(int direction, ThumbnailMenu thumbnailMenu,
+ List tranLayoutList) {
+ this.direction = direction;
+ this.thumbnailMenu = thumbnailMenu;
+ this.tranLayoutList = tranLayoutList;
+
+ scrollLayout = (FrameLayout) thumbnailMenu.findViewWithTag(ThumbnailMenu.TAG_SCROLL_LAYOUT);
+ container = (ThumbnailContainer) scrollLayout.getChildAt(0);
+ }
+
+ public boolean isOpen() {
+ return isOpen;
+ }
+
+ /**
+ * 动画模式打开菜单
+ */
+ public void openMenuAnimator() {
+ if (mIsInAnimation || isOpen) {
+ return;
}
+ mIsInAnimation = true;
+ switch (direction) {
+ case ThumbnailFactory.MENU_DIRECTION_LEFT:
+ case ThumbnailFactory.MENU_DIRECTION_RIGHT:
+ horizontalOpenMenu();
+ break;
- /**
- * 动画模式打开菜单
- */
- public void openMenuAnimator() {
- scrollLayout.setVisibility(View.VISIBLE);
- switch (direction) {
- case ThumbnailFactory.MENU_DIRECTION_LEFT:
- case ThumbnailFactory.MENU_DIRECTION_RIGHT:
- horizontalOpenMenu();
- break;
-
- case ThumbnailFactory.MENU_DIRECTION_BOTTOM:
- verticalOpenMun();
- break;
+ case ThumbnailFactory.MENU_DIRECTION_BOTTOM:
+ verticalOpenMenu();
+ break;
- }
}
-
- /**
- * 动画模式关闭菜单,并显示 transitionLayout
- *
- * @param transitionLayout 选中页面所在的 TransitionLayout
- * @param onMenuCloseListener
- */
- public void closeMenuAnimator(TransitionLayout transitionLayout,
- ThumbnailMenu.OnThumbnailMenuCloseListener onMenuCloseListener) {
- this.onMenuCloseListener = onMenuCloseListener;
- switch (direction) {
- case ThumbnailFactory.MENU_DIRECTION_LEFT:
- case ThumbnailFactory.MENU_DIRECTION_RIGHT:
- horizontalCloseMenu(transitionLayout);
- break;
-
- case ThumbnailFactory.MENU_DIRECTION_BOTTOM:
- verticalCloseMenu(transitionLayout);
- break;
- }
+ }
+
+ /**
+ * 动画模式关闭菜单,并显示 transitionLayout
+ *
+ * @param transitionLayout 选中页面所在的 TransitionLayout
+ * @param onMenuCloseListener
+ */
+ public void closeMenuAnimator(TransitionLayout transitionLayout,
+ ThumbnailMenu.OnThumbnailMenuCloseListener onMenuCloseListener) {
+ if (mIsInAnimation || !isOpen) {
+ return;
}
-
- /**
- * 纵向打开菜单
- */
- private void verticalOpenMun() {
- float endTranX, endTranY;
- if (init) {
- for (int i = 0; i < tranLayoutList.size(); i++) {
- final TransitionLayout currTranLayout = tranLayoutList.get(i);
- final float tmpTranX = currTranLayout.getWidth() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
-
- endTranX = -tmpTranX + (i * (currTranLayout.getWidth() * thumbnailMenu.getScaleRatio() + ThumbnailMenu.THUM_MARGIN));
- endTranY = currTranLayout.getHeight() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
-
- AnimatorSet animSet = makeOpenMenuAnimatorSet(endTranX, endTranY, currTranLayout);
- addOpenMenuAnimatorSetListener(animSet, currTranLayout, endTranY, i, tmpTranX);
- }
- init = false;
- } else {
- TransitionLayout showingTranLayout = (TransitionLayout) thumbnailMenu.getChildAt(thumbnailMenu.getChildCount() - 1);
-
- float singleThumMenuWidth = showingTranLayout.getWidth() * thumbnailMenu.getScaleRatio();
- int menuIndex = tranLayoutList.indexOf(showingTranLayout);
-
- // 调整菜单滚动的位置
- int adjustScrollPosition = (int) (menuIndex * (singleThumMenuWidth + ThumbnailMenu.THUM_MARGIN));
- HorizontalScrollView scrollView = (HorizontalScrollView) scrollLayout;
- scrollView.scrollTo(adjustScrollPosition, 0);
-
- // 当前 ScrollView 滚动的距离
- int scrollDistance = scrollView.getScrollX();
- float tmpTranX = showingTranLayout.getWidth() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
-
- endTranX = -tmpTranX + (menuIndex * (singleThumMenuWidth + ThumbnailMenu.THUM_MARGIN)) - scrollDistance;
- endTranY = showingTranLayout.getHeight() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
-
- AnimatorSet animSet = makeOpenMenuAnimatorSet(endTranX, endTranY, showingTranLayout);
- addOpenMenuAnimatorSetListener(animSet, showingTranLayout, endTranY, menuIndex, tmpTranX);
- }
+ mIsInAnimation = true;
+ this.onMenuCloseListener = onMenuCloseListener;
+ switch (direction) {
+ case ThumbnailFactory.MENU_DIRECTION_LEFT:
+ case ThumbnailFactory.MENU_DIRECTION_RIGHT:
+ horizontalCloseMenu(transitionLayout);
+ break;
+
+ case ThumbnailFactory.MENU_DIRECTION_BOTTOM:
+ verticalCloseMenu(transitionLayout);
+ break;
}
-
- /**
- * 纵向(左侧或者右侧)关闭菜单,并显示选中的 TransitionLayout
- *
- * @param transitionLayout 选中页面所在的 TransitionLayout
- */
- private void verticalCloseMenu(final TransitionLayout transitionLayout) {
- HorizontalScrollView scrollView = (HorizontalScrollView) scrollLayout;
- // 当前 ScrollView 滚动的距离
- final int scrollDistance = scrollView.getScrollX();
- // 当前选中的 TransitionLayout 所在模型的 Left
- final int currTranLeft = ((FrameLayout) transitionLayout.getParent()).getLeft();
-
- int tranTop = ((FrameLayout) transitionLayout.getParent()).getTop();
- // 将选中 TransitionLayout 从其所在模型中移除并放置在 ThumbnailMenu 相对模型所在同一个位置上
- final int choosenMenuIndex = tranLayoutList.indexOf(transitionLayout);
- FrameLayout frameLayout = (FrameLayout) container.getChildAt(choosenMenuIndex);
- frameLayout.removeView(transitionLayout);
-
- final FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
- transitionLayout.getWidth(),
- transitionLayout.getHeight());
- frameParams.leftMargin = currTranLeft - scrollDistance;
- frameParams.topMargin = tranTop;
- transitionLayout.setLayoutParams(frameParams);
-
- thumbnailMenu.addView(transitionLayout);
-
- float endTranX = (thumbnailMenu.getWidth() - transitionLayout.getWidth()) * .5f - currTranLeft + scrollDistance;
- float endTranY = -frameParams.topMargin;
-
- AnimatorSet animSet = makeCloseMenuAnimatorSet(transitionLayout, endTranX, endTranY);
- addCloseMenuAnimatorSetListener(transitionLayout, frameParams, animSet);
+ }
+
+ /**
+ * 纵向打开菜单
+ */
+ private void verticalOpenMenu() {
+ float endTranX, endTranY;
+ if (init) {
+ for (int i = 0; i < tranLayoutList.size(); i++) {
+ final TransitionLayout currTranLayout = tranLayoutList.get(i);
+ final float tmpTranX =
+ currTranLayout.getWidth() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
+
+ endTranX = -tmpTranX + (i * (currTranLayout.getWidth() * thumbnailMenu.getScaleRatio()
+ + ThumbnailMenu.THUM_MARGIN));
+ endTranY = currTranLayout.getHeight() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
+
+ AnimatorSet animSet = makeOpenMenuAnimatorSet(endTranX, endTranY, currTranLayout);
+ addOpenMenuAnimatorSetListener(animSet, currTranLayout, i);
+ }
+ init = false;
+ } else {
+ TransitionLayout showingTranLayout =
+ (TransitionLayout) thumbnailMenu.getChildAt(thumbnailMenu.getChildCount() - 1);
+
+ float singleThumMenuWidth = showingTranLayout.getWidth() * thumbnailMenu.getScaleRatio();
+ int menuIndex = tranLayoutList.indexOf(showingTranLayout);
+
+
+ HorizontalScrollView scrollView = (HorizontalScrollView) scrollLayout;
+
+ // 当前 ScrollView 滚动的距离
+ int scrollDistance = scrollView.getScrollX();
+ float tmpTranX = showingTranLayout.getWidth() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
+
+ endTranX = -tmpTranX + (menuIndex * (singleThumMenuWidth + ThumbnailMenu.THUM_MARGIN))
+ - scrollDistance;
+ endTranY = showingTranLayout.getHeight() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
+
+ AnimatorSet animSet = makeOpenMenuAnimatorSet(endTranX, endTranY, showingTranLayout);
+ addOpenMenuAnimatorSetListener(animSet, showingTranLayout, menuIndex);
}
+ }
+
+ /**
+ * 纵向(左侧或者右侧)关闭菜单,并显示选中的 TransitionLayout
+ *
+ * @param transitionLayout 选中页面所在的 TransitionLayout
+ */
+ private void verticalCloseMenu(final TransitionLayout transitionLayout) {
+ thumbnailMenu.bringChildToFront(transitionLayout);
+
+ HorizontalScrollView scrollView = (HorizontalScrollView) scrollLayout;
+ // 当前 ScrollView 滚动的距离
+ final int scrollDistance = scrollView.getScrollX();
+
+ final int choosenMenuIndex = tranLayoutList.indexOf(transitionLayout);
+ ThumbnailView frameLayout = (ThumbnailView) container.getChildAt(choosenMenuIndex);
+ // 当前选中的 TransitionLayout 所在模型的 Left
+ final int currTranLeft = frameLayout.getLeft();
+
+ float offsetX = (thumbnailMenu.getWidth() - frameLayout.getWidth()) * .5f;
+ float offsetY = (thumbnailMenu.getHeight() - frameLayout.getHeight()) * .5f;
+ transitionLayout.setTranslationX(currTranLeft - scrollDistance - offsetX);
+ transitionLayout.setTranslationY(offsetY);
+
+ AnimatorSet animSet = makeCloseMenuAnimatorSet(transitionLayout, 0, 0);
+ addCloseMenuAnimatorSetListener(animSet);
+ }
+
+ /**
+ * 横向(左侧或者右侧)打开菜单
+ */
+ private void horizontalOpenMenu() {
+ float endTranX, endTranY;
+ if (init) {
+ for (int i = 0; i < tranLayoutList.size(); i++) {
+ TransitionLayout currTranLayout = tranLayoutList.get(i);
+ float tmpTranY = currTranLayout.getHeight() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
+
+ endTranX = currTranLayout.getWidth() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
+ endTranY = -tmpTranY + (i * (currTranLayout.getHeight() * thumbnailMenu.getScaleRatio()
+ + ThumbnailMenu.THUM_MARGIN));
- /**
- * 横向(左侧或者右侧)打开菜单
- */
- private void horizontalOpenMenu() {
- float endTranX, endTranY;
- if (init) {
- for (int i = 0; i < tranLayoutList.size(); i++) {
- TransitionLayout currTranLayout = tranLayoutList.get(i);
- float tmpTranY = currTranLayout.getHeight() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
-
- endTranX = currTranLayout.getWidth() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
- endTranY = -tmpTranY + (i * (currTranLayout.getHeight() * thumbnailMenu.getScaleRatio() + ThumbnailMenu.THUM_MARGIN));
-
- AnimatorSet animSet = makeOpenMenuAnimatorSet(endTranX, endTranY, currTranLayout);
- addOpenMenuAnimatorSetListener(animSet, currTranLayout, tmpTranY, i, endTranX);
- }
- init = false;
- } else {
- TransitionLayout showingTranLayout = (TransitionLayout) thumbnailMenu.getChildAt(thumbnailMenu.getChildCount() - 1);
-
- float singleThumMenuHeight = showingTranLayout.getHeight() * thumbnailMenu.getScaleRatio();
- int menuIndex = tranLayoutList.indexOf(showingTranLayout);
-
- // 调整菜单滚动的位置
- int adjustScrollPosition = (int) (menuIndex * (singleThumMenuHeight + ThumbnailMenu.THUM_MARGIN));
- ScrollView scrollView = (ScrollView) scrollLayout;
- scrollView.scrollTo(0, adjustScrollPosition);
-
- // 当前 ScrollView 滚动的距离
- int scrollDistance = scrollView.getScrollY();
- float tmpTranY = showingTranLayout.getHeight() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
-
- endTranX = showingTranLayout.getWidth() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
- endTranY = -tmpTranY + (menuIndex * (singleThumMenuHeight + ThumbnailMenu.THUM_MARGIN)) - scrollDistance;
-
- AnimatorSet animSet = makeOpenMenuAnimatorSet(endTranX, endTranY, showingTranLayout);
- addOpenMenuAnimatorSetListener(animSet, showingTranLayout, tmpTranY, menuIndex, endTranX);
- }
-
+ endTranX = direction == ThumbnailFactory.MENU_DIRECTION_LEFT ? -endTranX : endTranX;
+ AnimatorSet animSet = makeOpenMenuAnimatorSet(endTranX, endTranY, currTranLayout);
+ addOpenMenuAnimatorSetListener(animSet, currTranLayout, i);
+ }
+ init = false;
+ } else {
+ TransitionLayout showingTranLayout =
+ (TransitionLayout) thumbnailMenu.getChildAt(thumbnailMenu.getChildCount() - 1);
+
+ float singleThumMenuHeight = showingTranLayout.getHeight() * thumbnailMenu.getScaleRatio();
+ int menuIndex = tranLayoutList.indexOf(showingTranLayout);
+
+ ScrollView scrollView = (ScrollView) scrollLayout;
+
+ // 当前 ScrollView 滚动的距离
+ int scrollDistance = scrollView.getScrollY();
+ float tmpTranY = showingTranLayout.getHeight() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
+
+ endTranX = showingTranLayout.getWidth() * (1.f - thumbnailMenu.getScaleRatio()) * .5f;
+ endTranY = -tmpTranY + (menuIndex * (singleThumMenuHeight + ThumbnailMenu.THUM_MARGIN))
+ - scrollDistance;
+
+ endTranX = direction == ThumbnailFactory.MENU_DIRECTION_LEFT ? -endTranX : endTranX;
+ AnimatorSet animSet = makeOpenMenuAnimatorSet(endTranX, endTranY, showingTranLayout);
+ addOpenMenuAnimatorSetListener(animSet, showingTranLayout, menuIndex);
}
- /**
- * 横向(左侧或者右侧)关闭菜单,并显示选中的 TransitionLayout
- *
- * @param transitionLayout 选中页面所在的TransitionLayout
- */
- private void horizontalCloseMenu(final TransitionLayout transitionLayout) {
- // 当前 ScrollView 滚动的距离
- final int scrollDistance = scrollLayout.getScrollY();
- // 当前选中的 TransitionLayout 所在模型的 Top
- final int currTranTop = ((FrameLayout) transitionLayout.getParent()).getTop();
-
- // 将选中 TransitionLayout 从其所在模型中移除并放置在 ThumbnailMenu 相对模型所在同一个位置上
- final int choosenMenuIndex = tranLayoutList.indexOf(transitionLayout);
- FrameLayout frameLayout = (FrameLayout) container.getChildAt(choosenMenuIndex);
- frameLayout.removeView(transitionLayout);
-
- final FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
- transitionLayout.getWidth(),
- transitionLayout.getHeight());
- frameParams.topMargin = currTranTop - scrollDistance;
- transitionLayout.setLayoutParams(frameParams);
-
- thumbnailMenu.addView(transitionLayout);
+ }
- float endTranX = (thumbnailMenu.getWidth() - transitionLayout.getWidth()) * .5f;
- float endTranY = (thumbnailMenu.getHeight() - transitionLayout.getHeight()) * .5f - currTranTop + scrollDistance;
+ /**
+ * 横向(左侧或者右侧)关闭菜单,并显示选中的 TransitionLayout
+ *
+ * @param transitionLayout 选中页面所在的TransitionLayout
+ */
+ private void horizontalCloseMenu(final TransitionLayout transitionLayout) {
+ thumbnailMenu.bringChildToFront(transitionLayout);
- AnimatorSet animSet = makeCloseMenuAnimatorSet(transitionLayout, endTranX, endTranY);
- addCloseMenuAnimatorSetListener(transitionLayout, frameParams, animSet);
+ // 当前 ScrollView 滚动的距离
+ final int scrollDistance = scrollLayout.getScrollY();
- }
+ final int choosenMenuIndex = tranLayoutList.indexOf(transitionLayout);
+ ThumbnailView frameLayout = (ThumbnailView) container.getChildAt(choosenMenuIndex);
+ // 当前选中的 TransitionLayout 所在模型的 Top
+ final int currTranTop = frameLayout.getTop();
- private void addCloseMenuAnimatorSetListener(final TransitionLayout transitionLayout,
- final FrameLayout.LayoutParams frameParams,
- AnimatorSet animSet) {
-
- animSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- frameParams.leftMargin = 0;
- frameParams.topMargin = 0;
- // 还原选中的 TransitionLayout
- transitionLayout.setTranslationX(0);
- transitionLayout.setTranslationY(0);
- transitionLayout.setLayoutParams(frameParams);
-
- if (onMenuCloseListener != null) {
- onMenuCloseListener.onMenuCloseListener();
- }
- scrollLayout.setVisibility(View.GONE);
- }
- });
- }
+ float offsetX = (thumbnailMenu.getWidth() - frameLayout.getWidth()) * .5f;
+ float translationX =
+ direction == ThumbnailFactory.MENU_DIRECTION_LEFT ? -offsetX : offsetX;
+ transitionLayout.setTranslationX(translationX);
+ transitionLayout.setTranslationY(currTranTop - scrollDistance
+ - (thumbnailMenu.getHeight() - frameLayout.getHeight()) * .5f);
- /**
- * 创建打开菜单的动画集
- *
- * @param endTranX
- * @param endTranY
- * @param transitionLayout
- * @return
- */
- @NonNull
- private AnimatorSet makeOpenMenuAnimatorSet(float endTranX, float endTranY, TransitionLayout transitionLayout) {
- endTranX = direction == ThumbnailFactory.MENU_DIRECTION_LEFT ? -endTranX : endTranX;
+ AnimatorSet animSet = makeCloseMenuAnimatorSet(transitionLayout, 0, 0);
+ addCloseMenuAnimatorSetListener(animSet);
- ObjectAnimator scaleXAnima = ObjectAnimator.ofFloat(
- transitionLayout, "scaleX", transitionLayout.getScaleX(), thumbnailMenu.getScaleRatio());
- ObjectAnimator scaleYAnima = ObjectAnimator.ofFloat(
- transitionLayout, "scaleY", transitionLayout.getScaleY(), thumbnailMenu.getScaleRatio());
-
- ObjectAnimator tranXAnima = ObjectAnimator.ofFloat(
- transitionLayout, "translationX", transitionLayout.getTranslationX(), endTranX);
- ObjectAnimator tranYAnima = ObjectAnimator.ofFloat(
- transitionLayout, "translationY", transitionLayout.getTranslationY(), endTranY);
-
- AnimatorSet animSet = new AnimatorSet();
- animSet.setDuration(300);
- animSet.setInterpolator(interpolator);
- animSet.play(scaleXAnima).with(scaleYAnima).before(tranXAnima).before(tranYAnima);
- animSet.start();
- return animSet;
- }
+ }
- /**
- * 创建关闭菜单的动画集
- *
- * @param transitionLayout
- * @param endTranX
- * @param endTranY
- * @return
- */
- @NonNull
- private AnimatorSet makeCloseMenuAnimatorSet(TransitionLayout transitionLayout, float endTranX, float endTranY) {
- ObjectAnimator scaleXAnima = ObjectAnimator.ofFloat(
- transitionLayout, "scaleX", transitionLayout.getScaleX(), transitionLayout.getScaleX() / thumbnailMenu.getScaleRatio());
- ObjectAnimator scaleYAnima = ObjectAnimator.ofFloat(
- transitionLayout, "scaleY", transitionLayout.getScaleX(), transitionLayout.getScaleY() / thumbnailMenu.getScaleRatio());
-
- float currTranX = direction == ThumbnailFactory.MENU_DIRECTION_RIGHT ?
- -transitionLayout.getTranslationX() :
- transitionLayout.getTranslationX();
-
- ObjectAnimator tranXAnima = ObjectAnimator.ofFloat(
- transitionLayout, "translationX", currTranX, endTranX);
- ObjectAnimator tranYAnima = ObjectAnimator.ofFloat(
- transitionLayout, "translationY", transitionLayout.getTranslationY(), endTranY);
-
- AnimatorSet animSet = new AnimatorSet();
- animSet.setDuration(300);
- animSet.play(tranXAnima).with(tranYAnima).before(scaleXAnima).before(scaleYAnima);
- animSet.setInterpolator(interpolator);
- animSet.start();
- return animSet;
- }
+ private void addCloseMenuAnimatorSetListener(AnimatorSet animSet) {
- /**
- * 为菜单打开动画集添加一个监听器
- *
- * @param animSet
- * @param transitionLayout
- * @param tmpTranY
- * @param index
- * @param finalEndTranX
- */
- private void addOpenMenuAnimatorSetListener(AnimatorSet animSet, final TransitionLayout transitionLayout,
- final float tmpTranY, final int index, final float finalEndTranX) {
- animSet.addListener(new AnimatorListenerAdapter() {
- @Override
- public void onAnimationEnd(Animator animation) {
- // 1. 将 transitionLayout 从 menu 容器中移除
- thumbnailMenu.removeViewAt(thumbnailMenu.indexOfChild(transitionLayout));
-
- // 2. 将 transitionLayout 放入菜单容器中
- // 设置为原来的宽高大小,是因为之前缩小过
- FrameLayout.LayoutParams frameParams = new FrameLayout.LayoutParams(
- transitionLayout.getWidth(),
- transitionLayout.getHeight()
- );
- FrameLayout frameLayout = (FrameLayout) container.getChildAt(index);
- // 调整位置
- transitionLayout.setTranslationX(-finalEndTranX);
- transitionLayout.setTranslationY(-tmpTranY);
- // 将缩小后的 transitionLayout 放入模型中
- frameLayout.addView(transitionLayout, frameParams);
- }
- });
- }
+ animSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ if (onMenuCloseListener != null) {
+ onMenuCloseListener.onMenuCloseListener();
+ }
+ isOpen = false;
+ mIsInAnimation = false;
+ }
+ });
+ }
+
+ /**
+ * 创建打开菜单的动画集
+ *
+ * @param endTranX
+ * @param endTranY
+ * @param transitionLayout
+ * @return
+ */
+ @NonNull
+ private AnimatorSet makeOpenMenuAnimatorSet(float endTranX, float endTranY,
+ TransitionLayout transitionLayout) {
+ ObjectAnimator scaleXAnima = ObjectAnimator.ofFloat(
+ transitionLayout, "scaleX", transitionLayout.getScaleX(), thumbnailMenu.getScaleRatio());
+ ObjectAnimator scaleYAnima = ObjectAnimator.ofFloat(
+ transitionLayout, "scaleY", transitionLayout.getScaleY(), thumbnailMenu.getScaleRatio());
+
+ ObjectAnimator tranXAnima = ObjectAnimator.ofFloat(
+ transitionLayout, "translationX", transitionLayout.getTranslationX(), endTranX);
+ ObjectAnimator tranYAnima = ObjectAnimator.ofFloat(
+ transitionLayout, "translationY", transitionLayout.getTranslationY(), endTranY);
+
+ AnimatorSet animSet = new AnimatorSet();
+ animSet.setDuration(300);
+ animSet.setInterpolator(interpolator);
+ animSet.play(scaleXAnima).with(scaleYAnima).with(tranXAnima).with(tranYAnima);
+ animSet.start();
+ return animSet;
+ }
+
+ /**
+ * 创建关闭菜单的动画集
+ *
+ * @param transitionLayout
+ * @param endTranX
+ * @param endTranY
+ * @return
+ */
+ @NonNull
+ private AnimatorSet makeCloseMenuAnimatorSet(TransitionLayout transitionLayout, float endTranX,
+ float endTranY) {
+ ObjectAnimator scaleXAnima = ObjectAnimator.ofFloat(
+ transitionLayout, "scaleX", transitionLayout.getScaleX(),
+ transitionLayout.getScaleX() / thumbnailMenu.getScaleRatio());
+ ObjectAnimator scaleYAnima = ObjectAnimator.ofFloat(
+ transitionLayout, "scaleY", transitionLayout.getScaleX(),
+ transitionLayout.getScaleY() / thumbnailMenu.getScaleRatio());
+
+ float currTranX = transitionLayout.getTranslationX();
+
+ ObjectAnimator tranXAnima = ObjectAnimator.ofFloat(
+ transitionLayout, "translationX", currTranX, endTranX);
+ ObjectAnimator tranYAnima = ObjectAnimator.ofFloat(
+ transitionLayout, "translationY", transitionLayout.getTranslationY(), endTranY);
+
+ AnimatorSet animSet = new AnimatorSet();
+ animSet.setDuration(300);
+ animSet.play(tranXAnima).with(tranYAnima).with(scaleXAnima).with(scaleYAnima);
+ animSet.setInterpolator(interpolator);
+ animSet.start();
+ return animSet;
+ }
+
+ /**
+ * 为菜单打开动画集添加一个监听器
+ *
+ * @param animSet
+ * @param transitionLayout
+ * @param index
+ */
+ private void addOpenMenuAnimatorSetListener(AnimatorSet animSet,
+ final TransitionLayout transitionLayout,
+ final int index) {
+ animSet.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+
+ // ThumbnailView frameLayout = (ThumbnailView) container.getChildAt(index);
+ // frameLayout.setVisibility(View.VISIBLE);
+
+ // 移到屏幕外进行隐藏处理
+ transitionLayout.setTranslationY(transitionLayout.getHeight());
+
+ isOpen = true;
+ mIsInAnimation = false;
+ }
+ });
+ }
}
diff --git a/tmlibrary/src/main/java/com/hitomi/tmlibrary/ThumbnailMenu.java b/tmlibrary/src/main/java/com/hitomi/tmlibrary/ThumbnailMenu.java
index 0d9b858..e355851 100644
--- a/tmlibrary/src/main/java/com/hitomi/tmlibrary/ThumbnailMenu.java
+++ b/tmlibrary/src/main/java/com/hitomi/tmlibrary/ThumbnailMenu.java
@@ -1,5 +1,10 @@
+/*
+ * Copyright (C) 2016 Baidu, Inc. All Rights Reserved.
+ */
package com.hitomi.tmlibrary;
+import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
+
import android.content.Context;
import android.content.res.TypedArray;
import android.support.v4.view.PagerAdapter;
@@ -11,8 +16,6 @@
import java.util.ArrayList;
import java.util.List;
-import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
-
/**
* 缩略图菜单
* Created by hitomi on 2016/8/19.
@@ -20,229 +23,242 @@
*/
public class ThumbnailMenu extends FrameLayout {
- static final float SCALE_RATIO = .45f;
+ static final float SCALE_RATIO = .45f;
- static final int THUM_MARGIN = 2;
+ static final int THUM_MARGIN = 2;
- static final String TAG_SCROLL_LAYOUT = "tag_scroll_layout";
+ static final String TAG_SCROLL_LAYOUT = "tag_scroll_layout";
- private ThumbnailFactory factory;
+ private ThumbnailFactory factory;
- private ThumbnailAnimator thumbnailAnimator;
+ private ThumbnailAnimator thumbnailAnimator;
- private ThumbnailMenuChooser thumbnailMenuChooser;
+ private ThumbnailMenuChooser thumbnailMenuChooser;
- private FrameLayout thumScrollLayout;
+ private FrameLayout thumScrollLayout;
- private PagerAdapter pageAdapter;
+ private PagerAdapter pageAdapter;
- private OnThumbnailMenuCloseListener menuCloseListener;
+ private OnThumbnailMenuCloseListener menuCloseListener;
- private List objects;
+ private List objects;
- private List tranLayoutList;
+ private List tranLayoutList;
- /**
- * 缩略图菜单位置方向
- */
- private int direction = ThumbnailFactory.MENU_DIRECTION_BOTTOM;
+ /**
+ * 缩略图菜单位置方向
+ */
+ private int direction = ThumbnailFactory.MENU_DIRECTION_BOTTOM;
- /**
- * 缩略图当前缩放比率
- */
- private float scaleRation = SCALE_RATIO;
+ /**
+ * 缩略图当前缩放比率
+ */
+ private float scaleRation = SCALE_RATIO;
- /**
- * 第一次初始化标记
- */
- private boolean init = true;
+ /**
+ * 第一次初始化标记
+ */
+ private boolean init = true;
- /**
- * 菜单是否打开
- */
- private boolean isOpen;
+ /**
+ * 页面数量
+ */
+ private int pageCount;
- /**
- * 页面数量
- */
- private int pageCount;
+ public ThumbnailMenu(Context context) {
+ this(context, null);
+ }
- public ThumbnailMenu(Context context) {
- this(context, null);
- }
+ public ThumbnailMenu(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
- public ThumbnailMenu(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
+ public ThumbnailMenu(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
- public ThumbnailMenu(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
+ TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ThumbnailMenu);
+ direction = typedArray.getInt(R.styleable.ThumbnailMenu_menu_direction, direction);
+ scaleRation = typedArray.getFloat(R.styleable.ThumbnailMenu_scale_ratio, scaleRation);
+ scaleRation = scaleRation >= 1.f ? 1.f : scaleRation;
+ scaleRation = scaleRation <= .1f ? .1f : scaleRation;
+ typedArray.recycle();
- TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ThumbnailMenu);
- direction = typedArray.getInt(R.styleable.ThumbnailMenu_menu_direction, direction);
- scaleRation = typedArray.getFloat(R.styleable.ThumbnailMenu_scale_ratio, scaleRation);
- scaleRation = scaleRation >= 1.f ? 1.f : scaleRation;
- scaleRation = scaleRation <= .1f ? .1f : scaleRation;
- typedArray.recycle();
+ init();
+ }
- init();
- }
+ private void init() {
- private void init() {
- isOpen = false;
- objects = new ArrayList();
- tranLayoutList = new ArrayList<>();
+ objects = new ArrayList();
+ tranLayoutList = new ArrayList<>();
- thumbnailMenuChooser = new ThumbnailMenuChooser();
- factory = new ThumbnailFactory();
- }
+ thumbnailMenuChooser = new ThumbnailMenuChooser();
+ factory = new ThumbnailFactory();
+ }
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- super.onLayout(changed, left, top, right, bottom);
- if (init) {
- thumScrollLayout = factory.createMenuContainer(getContext(), direction);
- thumScrollLayout.setTag(TAG_SCROLL_LAYOUT);
- thumScrollLayout.setVisibility(View.GONE);
- addView(thumScrollLayout);
-
- thumbnailAnimator = new ThumbnailAnimator(direction, this, tranLayoutList);
- buildingModels();
-
- init = false;
- }
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ if (init) {
+ thumScrollLayout = factory.createMenuContainer(getContext(), direction);
+ thumScrollLayout.setTag(TAG_SCROLL_LAYOUT);
+ addView(thumScrollLayout, 0);
+
+ thumbnailAnimator = new ThumbnailAnimator(direction, this, tranLayoutList);
+ buildingModels();
+
+ init = false;
+ }
+ }
+
+ /**
+ * 绑定页面适配器
+ *
+ * @param adapter
+ */
+ public void setAdapter(PagerAdapter adapter) {
+ if (pageAdapter != null) {
+ pageAdapter.startUpdate(this);
+ for (int i = 0; i < adapter.getCount(); i++) {
+ pageAdapter.destroyItem((ViewGroup) getChildAt(i), i, objects.get(i));
+ }
+ pageAdapter.finishUpdate(this);
}
- /**
- * 绑定页面适配器
- *
- * @param adapter
- */
- public void setAdapter(PagerAdapter adapter) {
- if (pageAdapter != null) {
- pageAdapter.startUpdate(this);
- for (int i = 0; i < adapter.getCount(); i++) {
- pageAdapter.destroyItem((ViewGroup) getChildAt(i + 1), i, objects.get(i));
- }
- pageAdapter.finishUpdate(this);
- }
+ pageAdapter = adapter;
+ pageCount = pageAdapter.getCount();
- pageAdapter = adapter;
- pageCount = pageAdapter.getCount();
-
- LayoutParams layoutParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
- for (int i = 0; i < pageCount; i++) {
- TransitionLayout frameLayout = new TransitionLayout(getContext());
- frameLayout.setId(i + 1);// id 不能为0
- frameLayout.setLayoutParams(layoutParams);
- frameLayout.setOnClickListener(thumbnailMenuChooser);
- addView(frameLayout);
- tranLayoutList.add(0, frameLayout); // 倒序添加
- }
+ pageAdapter.startUpdate(this);
- for (int i = 0; i < pageCount; i++) {
- Object object = pageAdapter.instantiateItem((ViewGroup) getChildAt(i + 1), i);
- objects.add(object);
- }
- pageAdapter.finishUpdate(this);
- }
+ LayoutParams layoutParams = new LayoutParams(MATCH_PARENT, MATCH_PARENT);
+ for (int i = 0; i < pageCount; i++) {
+ TransitionLayout frameLayout = new TransitionLayout(getContext());
+ frameLayout.setId(i + 1);// id 不能为0
+ frameLayout.setLayoutParams(layoutParams);
+ addView(frameLayout);
+ tranLayoutList.add(0, frameLayout); // 倒序添加
- /**
- * 获取缩略图菜单容器中的 ScrollView 中唯一 ViewGroup [这里是LinearLayout]
- *
- * @return
- */
- public ThumbnailContainer getThumContainner() {
- return (ThumbnailContainer) thumScrollLayout.getChildAt(0);
+ Object object = pageAdapter.instantiateItem(frameLayout, i);
+ objects.add(object);
}
-
- /**
- * 创建 modelCount 数量的缩略图模型添加到缩略图菜单容器中
- */
- private void buildingModels() {
- final ThumbnailContainer containerLayout = getThumContainner();
- containerLayout.removeAllViews();
-
- for (int i = 0; i < pageCount; i++) {
- ThumbnailContainer.LayoutParams containerLayoutParams = new ThumbnailContainer.LayoutParams(
- (int) (getWidth() * scaleRation), (int) (getHeight() * scaleRation));
- if (i != 0) {
- if (direction == ThumbnailFactory.MENU_DIRECTION_BOTTOM) {
- containerLayoutParams.leftMargin = THUM_MARGIN;
- } else {
- containerLayoutParams.topMargin = THUM_MARGIN;
- }
- }
-
- if (direction == ThumbnailFactory.MENU_DIRECTION_BOTTOM) {
- containerLayoutParams.topMargin = getHeight() - containerLayoutParams.height;
- }
- if (direction == ThumbnailFactory.MENU_DIRECTION_RIGHT) {
- containerLayoutParams.leftMargin = getWidth() - containerLayoutParams.width;
- }
-
- FrameLayout modelLayout = new FrameLayout(getContext());
- modelLayout.setTag(i);
- containerLayout.addView(modelLayout, containerLayoutParams);
+ pageAdapter.finishUpdate(this);
+ }
+
+ /**
+ * 获取缩略图菜单容器中的 ScrollView 中唯一 ViewGroup [这里是LinearLayout]
+ *
+ * @return
+ */
+ public ThumbnailContainer getThumContainner() {
+ return (ThumbnailContainer) thumScrollLayout.getChildAt(0);
+ }
+
+ /**
+ * 创建 modelCount 数量的缩略图模型添加到缩略图菜单容器中
+ */
+ private void buildingModels() {
+ final ThumbnailContainer containerLayout = getThumContainner();
+ containerLayout.removeAllViews();
+
+ for (int i = 0; i < pageCount; i++) {
+ ThumbnailContainer.LayoutParams containerLayoutParams = new ThumbnailContainer.LayoutParams(
+ (int) (getWidth() * scaleRation), (int) (getHeight() * scaleRation));
+ if (i != 0) {
+ if (direction == ThumbnailFactory.MENU_DIRECTION_BOTTOM) {
+ containerLayoutParams.leftMargin = THUM_MARGIN;
+ } else {
+ containerLayoutParams.topMargin = THUM_MARGIN;
}
+ }
+
+ if (direction == ThumbnailFactory.MENU_DIRECTION_BOTTOM) {
+ containerLayoutParams.topMargin = getHeight() - containerLayoutParams.height;
+ }
+ if (direction == ThumbnailFactory.MENU_DIRECTION_RIGHT) {
+ containerLayoutParams.leftMargin = getWidth() - containerLayoutParams.width;
+ }
+
+ ThumbnailView modelLayout = new ThumbnailView(getContext());
+ modelLayout.setTag(i);
+ modelLayout.setTransitionLayout(tranLayoutList.get(i));
+ modelLayout.setOnClickListener(thumbnailMenuChooser);
+ containerLayout.addView(modelLayout, containerLayoutParams);
}
-
- /**
- * 打开菜单
- */
- public void openMenu() {
- if (!isOpen) {
- isOpen = true;
- thumbnailAnimator.openMenuAnimator();
- }
+ }
+
+ /**
+ * 打开菜单
+ */
+ public void openMenu() {
+ if (!isOpen()) {
+ thumbnailAnimator.openMenuAnimator();
}
-
- /**
- * 关闭菜单
- *
- * @param transitionLayout
- */
- private void closeMenu(TransitionLayout transitionLayout) {
- if (isOpen) {
- isOpen = false;
- thumbnailAnimator.closeMenuAnimator(transitionLayout, menuCloseListener);
- }
+ }
+
+ /**
+ * 关闭菜单
+ *
+ * @param transitionLayout
+ */
+ private void closeMenu(TransitionLayout transitionLayout) {
+ if (isOpen()) {
+ thumbnailAnimator.closeMenuAnimator(transitionLayout, menuCloseListener);
}
-
- /**
- * 菜单是否打开
- *
- * @return
- */
- public boolean isOpen() {
- return isOpen;
+ }
+
+ /**
+ * 菜单是否打开
+ *
+ * @return
+ */
+ public boolean isOpen() {
+ if (thumbnailAnimator == null) {
+ return false;
}
+ return thumbnailAnimator.isOpen();
+ }
- /**
- * 返回缩略图缩放的比率
- *
- * @return
- */
- public float getScaleRatio() {
- return scaleRation;
- }
+ /**
+ * 返回缩略图缩放的比率
+ *
+ * @return
+ */
+ public float getScaleRatio() {
+ return scaleRation;
+ }
- public void setOnMenuCloseListener(OnThumbnailMenuCloseListener menuCloseListener) {
- this.menuCloseListener = menuCloseListener;
- }
+ public void setOnMenuCloseListener(OnThumbnailMenuCloseListener menuCloseListener) {
+ this.menuCloseListener = menuCloseListener;
+ }
- public interface OnThumbnailMenuCloseListener {
- void onMenuCloseListener();
- }
+ public interface OnThumbnailMenuCloseListener {
+ void onMenuCloseListener();
+ }
- private class ThumbnailMenuChooser implements OnClickListener {
+ private class ThumbnailMenuChooser implements OnClickListener {
- @Override
- public void onClick(View view) {
- if (isOpen && view instanceof TransitionLayout) {
- TransitionLayout choosenLayout = (TransitionLayout) view;
- closeMenu(choosenLayout);
- }
- }
+ @Override
+ public void onClick(View view) {
+ if (view instanceof ThumbnailView) {
+ TransitionLayout choosenLayout = ((ThumbnailView) view).getTransitionLayout();
+ closeMenu(choosenLayout);
+ }
}
+ }
+
+ @Override
+ public void bringChildToFront(View child) {
+ ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
+ detachViewFromParent(child);
+ attachViewToParent(child, -1, layoutParams);
+ child.setClickable(true);//防止事件透传
+ invalidate();
+ }
+
+ public void takeChildToBehind(View child) {
+ ViewGroup.LayoutParams layoutParams = child.getLayoutParams();
+ detachViewFromParent(child);
+ attachViewToParent(child, 0, layoutParams);
+ invalidate();
+ }
+
}
diff --git a/tmlibrary/src/main/java/com/hitomi/tmlibrary/ThumbnailView.java b/tmlibrary/src/main/java/com/hitomi/tmlibrary/ThumbnailView.java
new file mode 100644
index 0000000..ed8041c
--- /dev/null
+++ b/tmlibrary/src/main/java/com/hitomi/tmlibrary/ThumbnailView.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2016 Baidu, Inc. All Rights Reserved.
+ */
+package com.hitomi.tmlibrary;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.View;
+
+/**
+ * Created by LukeSkywalker on 2016/9/29.
+ */
+public class ThumbnailView extends TransitionLayout {
+ private TransitionLayout mTransitionLayout;
+
+ public ThumbnailView(Context context) {
+ super(context);
+ }
+
+ public ThumbnailView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public ThumbnailView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public void setTransitionLayout(TransitionLayout transitionLayout) {
+ mTransitionLayout = transitionLayout;
+ removeAllViews();
+ View mView = new View(getContext());
+ addView(mView);
+ }
+
+ public TransitionLayout getTransitionLayout() {
+ return mTransitionLayout;
+ }
+
+ @Override
+ protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
+ if (mTransitionLayout != null) {
+ float sw = getMeasuredWidth() / (float) mTransitionLayout.getWidth();
+ float sh = getMeasuredHeight() / (float) mTransitionLayout.getHeight();
+ canvas.scale(sw, sh);
+ mTransitionLayout.draw(canvas);
+ }
+ return super.drawChild(canvas, child, drawingTime);
+ }
+}
diff --git a/tmlibrary/src/main/java/com/hitomi/tmlibrary/TransitionLayout.java b/tmlibrary/src/main/java/com/hitomi/tmlibrary/TransitionLayout.java
index ab91b98..8b92f09 100644
--- a/tmlibrary/src/main/java/com/hitomi/tmlibrary/TransitionLayout.java
+++ b/tmlibrary/src/main/java/com/hitomi/tmlibrary/TransitionLayout.java
@@ -1,8 +1,10 @@
+/*
+ * Copyright (C) 2016 Baidu, Inc. All Rights Reserved.
+ */
package com.hitomi.tmlibrary;
import android.content.Context;
import android.util.AttributeSet;
-import android.view.View;
import android.widget.FrameLayout;
/**
@@ -11,8 +13,6 @@
*/
public class TransitionLayout extends FrameLayout {
- private final View view;
-
public TransitionLayout(Context context) {
this(context, null);
}
@@ -23,8 +23,6 @@ public TransitionLayout(Context context, AttributeSet attrs) {
public TransitionLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
-
- view = getChildAt(0);
}
}