From 9d4eadffac0d5b2ce2b79ee8938ff591b4743efc Mon Sep 17 00:00:00 2001 From: seven332 Date: Sat, 9 Apr 2016 16:52:27 +0800 Subject: [PATCH] Add up react to SnackBar --- .../com/hippo/ehviewer/ui/MainActivity.java | 17 +- .../hippo/ehviewer/ui/scene/BaseScene.java | 14 ++ .../ehviewer/ui/scene/DownloadsScene.java | 6 +- .../ehviewer/ui/scene/FavoritesScene.java | 6 +- .../ui/scene/GalleryCommentsScene.java | 16 +- .../ehviewer/ui/scene/GalleryListScene.java | 6 +- .../hippo/ehviewer/widget/EhDrawerLayout.java | 166 ++++++++++++++++++ app/src/main/res/layout/activity_main.xml | 4 +- .../res/layout/scene_gallery_comments.xml | 1 + app/src/main/res/values/ids.xml | 3 + 10 files changed, 231 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/com/hippo/ehviewer/widget/EhDrawerLayout.java diff --git a/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java index 35c8fd290..7f3f40dc4 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java @@ -67,6 +67,7 @@ import com.hippo.ehviewer.ui.scene.SelectSiteScene; import com.hippo.ehviewer.ui.scene.SignInScene; import com.hippo.ehviewer.ui.scene.WarningScene; import com.hippo.ehviewer.ui.scene.WebViewSignInScene; +import com.hippo.ehviewer.widget.EhDrawerLayout; import com.hippo.io.UniFileInputStreamPipe; import com.hippo.scene.Announcer; import com.hippo.scene.SceneFragment; @@ -110,7 +111,7 @@ public final class MainActivity extends StageActivity Whole life cycle ---------------*/ @Nullable - private DrawerLayout mDrawerLayout; + private EhDrawerLayout mDrawerLayout; @Nullable private NavigationView mNavView; @Nullable @@ -358,7 +359,7 @@ public final class MainActivity extends StageActivity protected void onCreate2(@Nullable Bundle savedInstanceState) { setContentView(R.layout.activity_main); - mDrawerLayout = (DrawerLayout) ViewUtils.$$(this, R.id.draw_view); + mDrawerLayout = (EhDrawerLayout) ViewUtils.$$(this, R.id.draw_view); mNavView = (NavigationView) ViewUtils.$$(this, R.id.nav_view); mRightDrawer = (FrameLayout) ViewUtils.$$(this, R.id.right_drawer); View headerLayout = mNavView.getHeaderView(0); @@ -493,6 +494,18 @@ public final class MainActivity extends StageActivity mDisplayName.setText(displayName); } + public void addAboveSnackView(View view) { + if (mDrawerLayout != null) { + mDrawerLayout.addAboveSnackView(view); + } + } + + public void removeAboveSnackView(View view) { + if (mDrawerLayout != null) { + mDrawerLayout.removeAboveSnackView(view); + } + } + public int getDrawerLockMode(int edgeGravity) { if (mDrawerLayout != null) { return mDrawerLayout.getDrawerLockMode(edgeGravity); diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/BaseScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/BaseScene.java index 6de6438cc..5c850394f 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/BaseScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/BaseScene.java @@ -49,6 +49,20 @@ public abstract class BaseScene extends SceneFragment { } } + public void addAboveSnackView(View view) { + FragmentActivity activity = getActivity(); + if (activity instanceof MainActivity) { + ((MainActivity) activity).addAboveSnackView(view); + } + } + + public void removeAboveSnackView(View view) { + FragmentActivity activity = getActivity(); + if (activity instanceof MainActivity) { + ((MainActivity) activity).removeAboveSnackView(view); + } + } + public void setDrawerLockMode(int lockMode, int edgeGravity) { FragmentActivity activity = getActivity(); if (activity instanceof MainActivity) { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.java index 4dbd29085..d386fa70f 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/DownloadsScene.java @@ -327,6 +327,7 @@ public class DownloadsScene extends ToolbarScene mFabLayout.setHidePrimaryFab(true); mFabLayout.setAutoCancel(false); mFabLayout.setOnClickFabListener(this); + addAboveSnackView(mFabLayout); updateView(); @@ -437,9 +438,12 @@ public class DownloadsScene extends ToolbarScene mRecyclerView.stopScroll(); mRecyclerView = null; } + if (null != mFabLayout) { + removeAboveSnackView(mFabLayout); + mFabLayout = null; + } mRecyclerView = null; - mFabLayout = null; mViewTransition = null; mAdapter = null; mLayoutManager = null; diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java index c9fa38473..46ca8979c 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/FavoritesScene.java @@ -278,6 +278,7 @@ public class FavoritesScene extends BaseScene implements mFabLayout.setAutoCancel(false); mFabLayout.setHidePrimaryFab(true); mFabLayout.setOnClickFabListener(this); + addAboveSnackView(mFabLayout); // Restore search mode if (mSearchMode) { @@ -393,11 +394,14 @@ public class FavoritesScene extends BaseScene implements mRecyclerView.stopScroll(); mRecyclerView = null; } + if (null != mFabLayout) { + removeAboveSnackView(mFabLayout); + mFabLayout = null; + } mAdapter = null; mSearchBar = null; - mFabLayout = null; mSearchBarMover = null; mLeftDrawable = null; diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java index 60254da93..57773f72a 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryCommentsScene.java @@ -72,6 +72,7 @@ import com.hippo.util.DrawableManager; import com.hippo.util.ReadableTime; import com.hippo.util.TextUrl; import com.hippo.view.ViewTransition; +import com.hippo.widget.FabLayout; import com.hippo.widget.LinkifyTextView; import com.hippo.yorozuya.AnimationUtils; import com.hippo.yorozuya.AssertUtils; @@ -107,6 +108,8 @@ public final class GalleryCommentsScene extends ToolbarScene @Nullable private EasyRecyclerView mRecyclerView; @Nullable + private FabLayout mFabLayout; + @Nullable private FloatingActionButton mFab; @Nullable private View mEditPanel; @@ -182,6 +185,7 @@ public final class GalleryCommentsScene extends ToolbarScene mEditPanel = ViewUtils.$$(view, R.id.edit_panel); mSendImage = (ImageView) ViewUtils.$$(mEditPanel, R.id.send); mEditText = (EditText) ViewUtils.$$(mEditPanel, R.id.edit_text); + mFabLayout = (FabLayout) ViewUtils.$$(view, R.id.fab_layout); mFab = (FloatingActionButton) ViewUtils.$$(view, R.id.fab); Context context = getContext2(); @@ -216,6 +220,9 @@ public final class GalleryCommentsScene extends ToolbarScene mSendImage.setOnClickListener(this); mFab.setOnClickListener(this); + addAboveSnackView(mEditPanel); + addAboveSnackView(mFabLayout); + mViewTransition = new ViewTransition(mRecyclerView, tip); updateView(false); @@ -231,9 +238,16 @@ public final class GalleryCommentsScene extends ToolbarScene mRecyclerView.stopScroll(); mRecyclerView = null; } + if (null != mEditPanel) { + removeAboveSnackView(mEditPanel); + mEditPanel = null; + } + if (null != mFabLayout) { + removeAboveSnackView(mFabLayout); + mFabLayout = null; + } mFab = null; - mEditPanel = null; mSendImage = null; mEditText = null; mAdapter = null; diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java index a9049de10..574b237c8 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java @@ -442,6 +442,7 @@ public final class GalleryListScene extends BaseScene mFabLayout.setHidePrimaryFab(false); mFabLayout.setOnClickFabListener(this); mFabLayout.setOnExpandListener(this); + addAboveSnackView(mFabLayout); mActionFabDrawable = new AddDeleteDrawable(context); mActionFabDrawable.setColor(resources.getColor(R.color.primary_drawable_dark)); @@ -521,11 +522,14 @@ public final class GalleryListScene extends BaseScene mRecyclerView.stopScroll(); mRecyclerView = null; } + if (null != mFabLayout) { + removeAboveSnackView(mFabLayout); + mFabLayout = null; + } mAdapter = null; mSearchLayout = null; mSearchBar = null; - mFabLayout = null; mSearchFab = null; mViewTransition = null; mLeftDrawable = null; diff --git a/app/src/main/java/com/hippo/ehviewer/widget/EhDrawerLayout.java b/app/src/main/java/com/hippo/ehviewer/widget/EhDrawerLayout.java new file mode 100644 index 000000000..72b2ecd8a --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/widget/EhDrawerLayout.java @@ -0,0 +1,166 @@ +/* + * Copyright 2016 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.widget; + +import android.animation.ValueAnimator; +import android.content.Context; +import android.os.Build; +import android.support.annotation.Nullable; +import android.support.design.widget.CoordinatorLayout; +import android.support.design.widget.Snackbar; +import android.support.v4.view.ViewCompat; +import android.util.AttributeSet; +import android.view.View; + +import com.hippo.ehviewer.R; +import com.hippo.widget.drawerlayout.DrawerLayout; +import com.hippo.yorozuya.AnimationUtils; + +import java.util.ArrayList; +import java.util.List; + +@CoordinatorLayout.DefaultBehavior(EhDrawerLayout.Behavior.class) +public class EhDrawerLayout extends DrawerLayout { + + private List mAboveSnackViewList; + + public EhDrawerLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public EhDrawerLayout(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + public void addAboveSnackView(View view) { + if (null == mAboveSnackViewList) { + mAboveSnackViewList = new ArrayList<>(); + } + mAboveSnackViewList.add(view); + } + + public void removeAboveSnackView(View view) { + if (null == mAboveSnackViewList) { + return; + } + mAboveSnackViewList.remove(view); + } + + public int getAboveSnackViewCount() { + return null == mAboveSnackViewList ? 0 : mAboveSnackViewList.size(); + } + + @Nullable + public View getAboveSnackViewAt(int index) { + if (null == mAboveSnackViewList || index < 0 || index >= mAboveSnackViewList.size()) { + return null; + } else { + return mAboveSnackViewList.get(index); + } + } + + public static class Behavior extends CoordinatorLayout.Behavior { + // We only support the FAB <> Snackbar shift movement on Honeycomb and above. This is + // because we can use view translation properties which greatly simplifies the code. + private static final boolean SNACKBAR_BEHAVIOR_ENABLED = Build.VERSION.SDK_INT >= 11; + + @Override + public boolean layoutDependsOn(CoordinatorLayout parent, + EhDrawerLayout child, View dependency) { + // We're dependent on all SnackbarLayouts (if enabled) + return SNACKBAR_BEHAVIOR_ENABLED && dependency instanceof Snackbar.SnackbarLayout; + } + + @Override + public boolean onDependentViewChanged(CoordinatorLayout parent, EhDrawerLayout child, + View dependency) { + if (dependency instanceof Snackbar.SnackbarLayout) { + for (int i = 0, n = child.getAboveSnackViewCount(); i < n; i++) { + View view = child.getAboveSnackViewAt(i); + updateChildTranslationForSnackbar(parent, child, view); + } + } + return false; + } + + private void updateChildTranslationForSnackbar(CoordinatorLayout parent, + EhDrawerLayout view, final View child) { + final float targetTransY = getChildTranslationYForSnackbar(parent, view); + float childTranslationY = 0.0f; + Object obj = child.getTag(R.id.fab_translation_y); + if (obj instanceof Float) { + childTranslationY = (Float) obj; + } + if (childTranslationY == targetTransY) { + // We're already at (or currently animating to) the target value, return... + return; + } + + ValueAnimator fabTranslationYAnimator = null; + obj = child.getTag(R.id.fab_translation_y_animator); + if (obj instanceof ValueAnimator) { + fabTranslationYAnimator = (ValueAnimator) obj; + } + // Make sure that any current animation is cancelled + if (fabTranslationYAnimator != null && fabTranslationYAnimator.isRunning()) { + fabTranslationYAnimator.cancel(); + } + + final float currentTransY = ViewCompat.getTranslationY(child); + + if (child.isShown() + && Math.abs(currentTransY - targetTransY) > (child.getHeight() * 0.667f)) { + // If the FAB will be travelling by more than 2/3 of it's height, let's animate + // it instead + if (fabTranslationYAnimator == null) { + fabTranslationYAnimator = ValueAnimator.ofFloat(); + fabTranslationYAnimator.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR); + fabTranslationYAnimator.addUpdateListener( + new ValueAnimator.AnimatorUpdateListener() { + @Override + public void onAnimationUpdate(ValueAnimator animation) { + ViewCompat.setTranslationY(child, (Float) animation.getAnimatedValue()); + } + }); + child.setTag(R.id.fab_translation_y_animator, fabTranslationYAnimator); + } + fabTranslationYAnimator.setFloatValues(currentTransY, targetTransY); + fabTranslationYAnimator.start(); + } else { + // Now update the translation Y + ViewCompat.setTranslationY(child, targetTransY); + } + + child.setTag(R.id.fab_translation_y, targetTransY); + } + + private float getChildTranslationYForSnackbar(CoordinatorLayout parent, + EhDrawerLayout child) { + float minOffset = 0; + final List dependencies = parent.getDependencies(child); + for (int i = 0, z = dependencies.size(); i < z; i++) { + final View view = dependencies.get(i); + if (view instanceof Snackbar.SnackbarLayout && parent.doViewsOverlap(child, view)) { + minOffset = Math.min(minOffset, + ViewCompat.getTranslationY(view) - view.getHeight()); + } + } + + return minOffset; + } + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 4adceabd8..f457299a4 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -20,7 +20,7 @@ android:layout_width="match_parent" android:layout_height="match_parent"> - - + diff --git a/app/src/main/res/layout/scene_gallery_comments.xml b/app/src/main/res/layout/scene_gallery_comments.xml index e01ae0106..db3e7fae0 100644 --- a/app/src/main/res/layout/scene_gallery_comments.xml +++ b/app/src/main/res/layout/scene_gallery_comments.xml @@ -82,6 +82,7 @@ + + +