diff --git a/app/src/main/java/com/hippo/drawable/DrawerArrowDrawable.java b/app/src/main/java/com/hippo/drawable/DrawerArrowDrawable.java deleted file mode 100644 index 51ea44eb1..000000000 --- a/app/src/main/java/com/hippo/drawable/DrawerArrowDrawable.java +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2015 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.drawable; - -import android.animation.ObjectAnimator; -import android.content.Context; -import android.content.res.Resources; -import android.graphics.Canvas; -import android.graphics.ColorFilter; -import android.graphics.Paint; -import android.graphics.Path; -import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; - -import androidx.annotation.ColorInt; -import androidx.annotation.Keep; - -import com.hippo.ehviewer.R; -import com.hippo.yorozuya.MathUtils; - -/** - * A drawable that can draw a "Drawer hamburger" menu or an Arrow and animate between them. - */ -public class DrawerArrowDrawable extends Drawable { - - // The angle in degrees that the arrow head is inclined at. - private static final float ARROW_HEAD_ANGLE = (float) Math.toRadians(45); - private final Paint mPaint = new Paint(); - private final float mBarThickness; - // The length of top and bottom bars when they merge into an arrow - private final float mTopBottomArrowSize; - // The length of middle bar - private final float mBarSize; - // The length of the middle bar when arrow is shaped - private final float mMiddleArrowSize; - // The space between bars when they are parallel - private final float mBarGap; - // Whether bars should spin or not during progress - private final boolean mSpin; - // Use Path instead of canvas operations so that if color has transparency, overlapping sections - // wont look different - private final Path mPath = new Path(); - // The reported intrinsic size of the drawable. - private final int mSize; - // the amount that overlaps w/ bar size when rotation is max - private final float mMaxCutForBarSize; - // Whether we should mirror animation when animation is reversed. - private boolean mVerticalMirror = false; - // The interpolated version of the original progress - private float mProgress; - - /** - * @param context used to get the configuration for the drawable from - */ - public DrawerArrowDrawable(Context context, int color) { - Resources resources = context.getResources(); - - mPaint.setAntiAlias(true); - mPaint.setColor(color); - mSize = resources.getDimensionPixelSize(R.dimen.dad_drawable_size); - // round this because having this floating may cause bad measurements - mBarSize = Math.round(resources.getDimension(R.dimen.dad_bar_size)); - // round this because having this floating may cause bad measurements - mTopBottomArrowSize = Math.round(resources.getDimension(R.dimen.dad_top_bottom_bar_arrow_size)); - mBarThickness = resources.getDimension(R.dimen.dad_thickness); - // round this because having this floating may cause bad measurements - mBarGap = Math.round(resources.getDimension(R.dimen.dad_gap_between_bars)); - mSpin = resources.getBoolean(R.bool.dad_spin_bars); - mMiddleArrowSize = resources.getDimension(R.dimen.dad_middle_bar_arrow_size); - - mPaint.setStyle(Paint.Style.STROKE); - mPaint.setStrokeJoin(Paint.Join.MITER); - mPaint.setStrokeCap(Paint.Cap.BUTT); - mPaint.setStrokeWidth(mBarThickness); - - mMaxCutForBarSize = (float) (mBarThickness / 2 * Math.cos(ARROW_HEAD_ANGLE)); - } - - /** - * If set, canvas is flipped when progress reached to end and going back to start. - */ - protected void setVerticalMirror(boolean verticalMirror) { - mVerticalMirror = verticalMirror; - } - - @Override - public void draw(Canvas canvas) { - Rect bounds = getBounds(); - // Interpolated widths of arrow bars - final float arrowSize = MathUtils.lerp(mBarSize, mTopBottomArrowSize, mProgress); - final float middleBarSize = MathUtils.lerp(mBarSize, mMiddleArrowSize, mProgress); - // Interpolated size of middle bar - final float middleBarCut = Math.round(MathUtils.lerp(0, mMaxCutForBarSize, mProgress)); - // The rotation of the top and bottom bars (that make the arrow head) - final float rotation = MathUtils.lerp(0, ARROW_HEAD_ANGLE, mProgress); - - // The whole canvas rotates as the transition happens - final float canvasRotate = MathUtils.lerp(-180, 0, mProgress); - final float arrowWidth = Math.round(arrowSize * Math.cos(rotation)); - final float arrowHeight = Math.round(arrowSize * Math.sin(rotation)); - - mPath.rewind(); - final float topBottomBarOffset = MathUtils.lerp(mBarGap + mBarThickness, -mMaxCutForBarSize, - mProgress); - - final float arrowEdge = -middleBarSize / 2; - // draw middle bar - mPath.moveTo(arrowEdge + middleBarCut, 0); - mPath.rLineTo(middleBarSize - middleBarCut * 2, 0); - - // bottom bar - mPath.moveTo(arrowEdge, topBottomBarOffset); - mPath.rLineTo(arrowWidth, arrowHeight); - - // top bar - mPath.moveTo(arrowEdge, -topBottomBarOffset); - mPath.rLineTo(arrowWidth, -arrowHeight); - - mPath.close(); - - canvas.save(); - // Rotate the whole canvas if spinning, if not, rotate it 180 to get - // the arrow pointing the other way for RTL. - canvas.translate(bounds.centerX(), bounds.centerY()); - if (mSpin) { - canvas.rotate(canvasRotate * (mVerticalMirror ? -1 : 1)); - } - canvas.drawPath(mPath, mPaint); - - canvas.restore(); - } - - public void setColor(@ColorInt int color) { - mPaint.setColor(color); - invalidateSelf(); - } - - @Override - public void setAlpha(int i) { - mPaint.setAlpha(i); - } - - @Override - public void setColorFilter(ColorFilter colorFilter) { - mPaint.setColorFilter(colorFilter); - } - - @Override - public int getIntrinsicHeight() { - return mSize; - } - - @Override - public int getIntrinsicWidth() { - return mSize; - } - - @Override - public int getOpacity() { - return PixelFormat.TRANSLUCENT; - } - - @Keep - public float getProgress() { - return mProgress; - } - - @Keep - public void setProgress(float progress) { - if (progress == 1f) { - setVerticalMirror(true); - } else if (progress == 0f) { - setVerticalMirror(false); - } - mProgress = progress; - invalidateSelf(); - } - - public void setMenu(long duration) { - setShape(false, duration); - } - - public void setArrow(long duration) { - setShape(true, duration); - } - - public void setShape(boolean arrow, long duration) { - if (!((!arrow && mProgress == 0f) || (arrow && mProgress == 1f))) { - float endProgress = arrow ? 1f : 0f; - if (duration <= 0) { - setProgress(endProgress); - } else { - ObjectAnimator oa = ObjectAnimator.ofFloat(this, "progress", endProgress); - oa.setDuration(duration); - oa.setAutoCancel(true); - oa.start(); - } - } - } -} 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 f075eac6d..1f3372b21 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 @@ -48,7 +48,6 @@ import com.google.android.material.datepicker.MaterialDatePicker; import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.hippo.app.BaseDialogBuilder; import com.hippo.drawable.AddDeleteDrawable; -import com.hippo.drawable.DrawerArrowDrawable; import com.hippo.easyrecyclerview.EasyRecyclerView; import com.hippo.easyrecyclerview.FastScroller; import com.hippo.ehviewer.EhApplication; @@ -117,9 +116,6 @@ public class FavoritesScene extends SearchBarScene implements @Nullable @ViewLifeCircle private FavoritesHelper mHelper; - @Nullable - @ViewLifeCircle - private DrawerArrowDrawable mLeftDrawable; private AddDeleteDrawable mActionFabDrawable; @Nullable private DrawerLayout mDrawerLayout; @@ -276,8 +272,6 @@ public class FavoritesScene extends SearchBarScene implements fastScroller.setPadding(fastScroller.getPaddingLeft(), fastScroller.getPaddingTop() + paddingTopSB, fastScroller.getPaddingRight(), fastScroller.getPaddingBottom()); - mLeftDrawable = new DrawerArrowDrawable(context, ResourcesKt.resolveColor(getTheme(), android.R.attr.colorControlNormal)); - setNavigationDrawable(mLeftDrawable); setAllowEmptySearch(false); updateSearchBar(); updateJumpFab(); @@ -375,7 +369,6 @@ public class FavoritesScene extends SearchBarScene implements } mAdapter = null; - mLeftDrawable = null; mOldFavCat = null; mOldKeyword = null; @@ -728,21 +721,19 @@ public class FavoritesScene extends SearchBarScene implements } private void enterSearchMode(boolean animation) { - if (mSearchMode || mLeftDrawable == null) { + if (mSearchMode) { return; } mSearchMode = true; showSearchBar(); - mLeftDrawable.setArrow(ANIMATE_TIME); } private void exitSearchMode(boolean animation) { - if (!mSearchMode || mLeftDrawable == null) { + if (!mSearchMode) { return; } mSearchMode = false; showSearchBar(); - mLeftDrawable.setMenu(ANIMATE_TIME); } private void onGetFavoritesSuccess(FavoritesParser.Result result, int taskId) { 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 68dad24df..b1046b37f 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 @@ -65,7 +65,6 @@ import com.google.android.material.floatingactionbutton.FloatingActionButton; import com.hippo.app.BaseDialogBuilder; import com.hippo.app.EditTextDialogBuilder; import com.hippo.drawable.AddDeleteDrawable; -import com.hippo.drawable.DrawerArrowDrawable; import com.hippo.easyrecyclerview.EasyRecyclerView; import com.hippo.easyrecyclerview.FastScroller; import com.hippo.ehviewer.EhApplication; @@ -193,8 +192,6 @@ public final class GalleryListScene extends SearchBarScene @Nullable private GalleryListHelper mHelper; @Nullable - private DrawerArrowDrawable mLeftDrawable; - @Nullable private AddDeleteDrawable mActionFabDrawable; @Nullable private List mQuickSearchList; @@ -583,12 +580,10 @@ public final class GalleryListScene extends SearchBarScene fastScroller.setPadding(fastScroller.getPaddingLeft(), fastScroller.getPaddingTop() + paddingTopSB, fastScroller.getPaddingRight(), fastScroller.getPaddingBottom()); - mLeftDrawable = new DrawerArrowDrawable(context, ResourcesKt.resolveColor(getTheme(), android.R.attr.colorControlNormal)); setOnApplySearch((query) -> { onApplySearch(query); return null; }); - setNavigationDrawable(mLeftDrawable); setSearchBarHint(); setSearchBarSuggestionProvider(); @@ -653,7 +648,6 @@ public final class GalleryListScene extends SearchBarScene mAdapter = null; mSearchLayout = null; mViewTransition = null; - mLeftDrawable = null; mActionFabDrawable = null; } diff --git a/app/src/main/java/com/hippo/widget/SearchBarMover.java b/app/src/main/java/com/hippo/widget/SearchBarMover.java deleted file mode 100644 index 4658bd6a6..000000000 --- a/app/src/main/java/com/hippo/widget/SearchBarMover.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * 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.widget; - -import android.animation.Animator; -import android.animation.ValueAnimator; -import android.view.View; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.recyclerview.widget.RecyclerView; - -import com.hippo.yorozuya.MathUtils; -import com.hippo.yorozuya.SimpleAnimatorListener; -import com.hippo.yorozuya.ViewUtils; - -public class SearchBarMover extends RecyclerView.OnScrollListener { - - private static final long ANIMATE_TIME = 300L; - private final Helper mHelper; - private final View mSearchBar; - private boolean mShow; - private ValueAnimator mSearchBarMoveAnimator; - - public SearchBarMover(Helper helper, View searchBar, RecyclerView... recyclerViews) { - mHelper = helper; - mSearchBar = searchBar; - for (RecyclerView recyclerView : recyclerViews) { - recyclerView.addOnScrollListener(this); - } - } - - public void cancelAnimation() { - if (mSearchBarMoveAnimator != null) { - mSearchBarMoveAnimator.cancel(); - } - } - - @Override - public void onScrollStateChanged(@NonNull RecyclerView recyclerView, int newState) { - if (newState == RecyclerView.SCROLL_STATE_IDLE && mHelper.isValidView(recyclerView)) { - returnSearchBarPosition(); - } - } - - @Override - public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) { - if (mHelper.isValidView(recyclerView)) { - int oldBottom = (int) ViewUtils.getY2(mSearchBar); - int offsetYStep = MathUtils.clamp(-dy, -oldBottom, -(int) mSearchBar.getTranslationY()); - if (offsetYStep != 0) { - ViewUtils.translationYBy(mSearchBar, offsetYStep); - } - } - } - - public void returnSearchBarPosition() { - returnSearchBarPosition(true); - } - - @SuppressWarnings("SimplifiableIfStatement") - public void returnSearchBarPosition(boolean animation) { - if (mSearchBar.getHeight() == 0) { - // Layout not called - return; - } - - boolean show; - if (mHelper.forceShowSearchBar()) { - show = true; - } else { - RecyclerView recyclerView = mHelper.getValidRecyclerView(); - if (recyclerView == null) { - return; - } - if (!recyclerView.isShown()) { - show = true; - } else if (recyclerView.computeVerticalScrollOffset() < mSearchBar.getBottom()) { - show = true; - } else { - show = (int) ViewUtils.getY2(mSearchBar) > (mSearchBar.getHeight()) / 2; - } - } - - int offset; - if (show) { - offset = -(int) mSearchBar.getTranslationY(); - } else { - offset = -(int) ViewUtils.getY2(mSearchBar); - } - - if (offset == 0) { - // No need to scroll - return; - } - - if (animation) { - if (mSearchBarMoveAnimator != null) { - if (mShow == show) { - // The same target, no need to do animation - return; - } else { - // Cancel it - mSearchBarMoveAnimator.cancel(); - mSearchBarMoveAnimator = null; - } - } - - mShow = show; - final ValueAnimator va = ValueAnimator.ofInt(0, offset); - va.setDuration(ANIMATE_TIME); - va.addListener(new SimpleAnimatorListener() { - @Override - public void onAnimationEnd(Animator animation) { - mSearchBarMoveAnimator = null; - } - }); - va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - int lastValue; - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - int value = (Integer) animation.getAnimatedValue(); - int offsetStep = value - lastValue; - lastValue = value; - ViewUtils.translationYBy(mSearchBar, offsetStep); - } - }); - mSearchBarMoveAnimator = va; - va.start(); - } else { - if (mSearchBarMoveAnimator != null) { - mSearchBarMoveAnimator.cancel(); - } - ViewUtils.translationYBy(mSearchBar, offset); - } - } - - public void showSearchBar() { - showSearchBar(true); - } - - public void showSearchBar(boolean animation) { - if (mSearchBar.getHeight() == 0) { - // Layout not called - return; - } - - final int offset = -(int) mSearchBar.getTranslationY(); - - if (offset == 0) { - // No need to scroll - return; - } - - if (animation) { - if (mSearchBarMoveAnimator != null) { - if (mShow) { - // The same target, no need to do animation - return; - } else { - // Cancel it - mSearchBarMoveAnimator.cancel(); - mSearchBarMoveAnimator = null; - } - } - - mShow = true; - final ValueAnimator va = ValueAnimator.ofInt(0, offset); - va.setDuration(ANIMATE_TIME); - va.addListener(new SimpleAnimatorListener() { - @Override - public void onAnimationEnd(Animator animation) { - mSearchBarMoveAnimator = null; - } - }); - va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() { - int lastValue; - - @Override - public void onAnimationUpdate(ValueAnimator animation) { - int value = (Integer) animation.getAnimatedValue(); - int offsetStep = value - lastValue; - lastValue = value; - ViewUtils.translationYBy(mSearchBar, offsetStep); - } - }); - mSearchBarMoveAnimator = va; - va.start(); - } else { - if (mSearchBarMoveAnimator != null) { - mSearchBarMoveAnimator.cancel(); - } - ViewUtils.translationYBy(mSearchBar, offset); - } - } - - public interface Helper { - - boolean isValidView(RecyclerView recyclerView); - - @Nullable - RecyclerView getValidRecyclerView(); - - boolean forceShowSearchBar(); - } -} diff --git a/app/src/main/res/layout/scene_searchbar.xml b/app/src/main/res/layout/scene_searchbar.xml index b38510195..e4af94264 100644 --- a/app/src/main/res/layout/scene_searchbar.xml +++ b/app/src/main/res/layout/scene_searchbar.xml @@ -28,7 +28,8 @@ + android:layout_height="wrap_content" + app:navigationIcon="@drawable/ic_baseline_menu_24"/>