From 86d00cc0d1a89525a17feef7ab9f88b2ccf4f1e2 Mon Sep 17 00:00:00 2001 From: tarsin Date: Tue, 19 Jul 2022 22:17:40 +0800 Subject: [PATCH] Use mdc's slider --- .../ui/scene/GalleryPreviewsScene.java | 10 +- .../main/java/com/hippo/widget/Slider.java | 515 ------------------ app/src/main/res/layout/dialog_go_to.xml | 7 +- app/src/main/res/values/styles.xml | 6 - 4 files changed, 9 insertions(+), 529 deletions(-) delete mode 100644 app/src/main/java/com/hippo/widget/Slider.java diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java index 76b1abab9..031024cae 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryPreviewsScene.java @@ -36,6 +36,7 @@ import androidx.appcompat.app.AlertDialog; import androidx.recyclerview.widget.RecyclerView; import com.google.android.material.dialog.MaterialAlertDialogBuilder; +import com.google.android.material.slider.Slider; import com.hippo.easyrecyclerview.EasyRecyclerView; import com.hippo.easyrecyclerview.MarginItemDecoration; import com.hippo.ehviewer.EhApplication; @@ -53,7 +54,6 @@ import com.hippo.ehviewer.ui.MainActivity; import com.hippo.scene.SceneFragment; import com.hippo.widget.ContentLayout; import com.hippo.widget.LoadImageView; -import com.hippo.widget.Slider; import com.hippo.widget.recyclerview.AutoGridLayoutManager; import com.hippo.yorozuya.AssertUtils; import com.hippo.yorozuya.LayoutUtils; @@ -209,7 +209,7 @@ public class GalleryPreviewsScene extends ToolbarScene { return true; } int pages = mHelper.getPages(); - if (pages > 0 && mHelper.canGoTo()) { + if (pages > 1 && mHelper.canGoTo()) { GoToDialogHelper helper = new GoToDialogHelper(pages, mHelper.getPageForTop()); AlertDialog dialog = new MaterialAlertDialogBuilder(context).setTitle(R.string.go_to) .setView(R.layout.dialog_go_to) @@ -418,8 +418,8 @@ public class GalleryPreviewsScene extends ToolbarScene { ((TextView) ViewUtils.$$(dialog, R.id.start)).setText(String.format(Locale.US, "%d", 1)); ((TextView) ViewUtils.$$(dialog, R.id.end)).setText(String.format(Locale.US, "%d", mPages)); mSlider = (Slider) ViewUtils.$$(dialog, R.id.slider); - mSlider.setRange(1, mPages); - mSlider.setProgress(mCurrentPage + 1); + mSlider.setValueTo(mPages); + mSlider.setValue(mCurrentPage + 1); dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(this); dialog.setOnDismissListener(this); @@ -431,7 +431,7 @@ public class GalleryPreviewsScene extends ToolbarScene { return; } - int page = mSlider.getProgress() - 1; + int page = (int) (mSlider.getValue() - 1); if (page >= 0 && page < mPages && mHelper != null) { mHelper.goTo(page); if (mDialog != null) { diff --git a/app/src/main/java/com/hippo/widget/Slider.java b/app/src/main/java/com/hippo/widget/Slider.java deleted file mode 100644 index 7c37eb3ad..000000000 --- a/app/src/main/java/com/hippo/widget/Slider.java +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Copyright 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.widget; - -import android.animation.ValueAnimator; -import android.annotation.SuppressLint; -import android.content.Context; -import android.content.res.Resources; -import android.content.res.TypedArray; -import android.graphics.Canvas; -import android.graphics.Color; -import android.graphics.Paint; -import android.graphics.Rect; -import android.graphics.RectF; -import android.graphics.drawable.Drawable; -import android.util.AttributeSet; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.View; -import android.view.ViewConfiguration; -import android.widget.PopupWindow; -import android.widget.RelativeLayout; - -import androidx.annotation.NonNull; -import androidx.appcompat.widget.AppCompatImageView; -import androidx.core.graphics.drawable.DrawableCompat; - -import com.hippo.ehviewer.R; -import com.hippo.yorozuya.AnimationUtils; -import com.hippo.yorozuya.LayoutUtils; -import com.hippo.yorozuya.MathUtils; -import com.hippo.yorozuya.SimpleHandler; - -public class Slider extends View { - - private static final char[] CHARACTERS = { - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' - }; - - private static final int BUBBLE_WIDTH = 26; - private static final int BUBBLE_HEIGHT = 32; - private final RectF mLeftRectF = new RectF(); - private final RectF mRightRectF = new RectF(); - private final int[] mTemp = new int[2]; - private Context mContext; - private Paint mPaint; - private Paint mBgPaint; - private PopupWindow mPopup; - private BubbleView mBubble; - private int mStart; - private int mEnd; - private int mProgress; - private float mPercent; - private int mDrawProgress; - private float mDrawPercent; - private int mTargetProgress; - private float mThickness; - private float mRadius; - private float mCharWidth; - private float mCharHeight; - private int mBubbleWidth; - private int mBubbleHeight; - private int mBubbleMinWidth; - private int mBubbleMinHeight; - private int mPopupX; - private int mPopupY; - private int mPopupWidth; - private boolean mReverse = false; - - private boolean mShowBubble; - - private float mDrawBubbleScale = 0f; - - private ValueAnimator mProgressAnimation; - private ValueAnimator mBubbleScaleAnimation; - - private OnSetProgressListener mListener; - - private CheckForShowBubble mCheckForShowBubble; - - public Slider(Context context, AttributeSet attrs) { - super(context, attrs); - init(context, attrs); - } - - public Slider(Context context, AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(context, attrs); - } - - @SuppressWarnings("deprecation") - private void init(Context context, AttributeSet attrs) { - mContext = context; - mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - textPaint.setTextAlign(Paint.Align.CENTER); - - Resources resources = context.getResources(); - mBubbleMinWidth = resources.getDimensionPixelOffset(R.dimen.slider_bubble_width); - mBubbleMinHeight = resources.getDimensionPixelOffset(R.dimen.slider_bubble_height); - - mBubble = new BubbleView(context, textPaint); - mBubble.setScaleX(0.0f); - mBubble.setScaleY(0.0f); - RelativeLayout relativeLayout = new RelativeLayout(context); - relativeLayout.addView(mBubble); - relativeLayout.setBackgroundDrawable(null); - mPopup = new PopupWindow(relativeLayout); - mPopup.setOutsideTouchable(false); - mPopup.setTouchable(false); - mPopup.setFocusable(false); - - TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.Slider); - textPaint.setColor(a.getColor(R.styleable.Slider_textColor, Color.WHITE)); - textPaint.setTextSize(a.getDimensionPixelSize(R.styleable.Slider_textSize, 12)); - - updateTextSize(); - - setRange(a.getInteger(R.styleable.Slider_start, 0), a.getInteger(R.styleable.Slider_end, 0)); - setProgress(a.getInteger(R.styleable.Slider_slider_progress, 0)); - mThickness = a.getDimension(R.styleable.Slider_thickness, 2); - mRadius = a.getDimension(R.styleable.Slider_radius, 6); - - mBgPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - - a.recycle(); - - mProgressAnimation = new ValueAnimator(); - mProgressAnimation.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR); - mProgressAnimation.addUpdateListener(animation -> { - float value = (Float) animation.getAnimatedValue(); - mDrawPercent = value; - mDrawProgress = Math.round(MathUtils.lerp((float) mStart, mEnd, value)); - updateBubblePosition(); - mBubble.setProgress(mDrawProgress); - invalidate(); - }); - - mBubbleScaleAnimation = new ValueAnimator(); - mBubbleScaleAnimation.addUpdateListener(animation -> { - float value = (Float) animation.getAnimatedValue(); - mDrawBubbleScale = value; - mBubble.setScaleX(value); - mBubble.setScaleY(value); - invalidate(); - }); - } - - private void updateTextSize() { - int length = CHARACTERS.length; - float[] widths = new float[length]; - mPaint.getTextWidths(CHARACTERS, 0, length, widths); - mCharWidth = 0.0f; - for (float f : widths) { - mCharWidth = Math.max(mCharWidth, f); - } - - Paint.FontMetrics fm = mPaint.getFontMetrics(); - mCharHeight = fm.bottom - fm.top; - } - - private void updateBubbleSize() { - int oldWidth = mBubbleWidth; - int oldHeight = mBubbleHeight; - mBubbleWidth = (int) Math.max(mBubbleMinWidth, - Integer.toString(mEnd).length() * mCharWidth + LayoutUtils.dp2pix(mContext, 8)); - mBubbleHeight = (int) Math.max(mBubbleMinHeight, - mCharHeight + LayoutUtils.dp2pix(mContext, 8)); - - if (oldWidth != mBubbleWidth && oldHeight != mBubbleHeight) { - RelativeLayout.LayoutParams lp = (RelativeLayout.LayoutParams) mBubble.getLayoutParams(); - lp.width = mBubbleWidth; - lp.height = mBubbleHeight; - mBubble.setLayoutParams(lp); - } - } - - private void updatePopup() { - int width = getWidth(); - int paddingTop = getPaddingTop(); - int paddingBottom = getPaddingBottom(); - - getLocationInWindow(mTemp); - - mPopupWidth = (int) (width - mRadius - mRadius + mBubbleWidth); - int popupHeight = mBubbleHeight; - mPopupX = (int) (mTemp[0] + mRadius - (mBubbleWidth / 2)); - mPopupY = (int) (mTemp[1] - popupHeight + paddingTop + - ((getHeight() - paddingTop - paddingBottom) / 2) - - mRadius - LayoutUtils.dp2pix(mContext, 2)); - - mPopup.update(mPopupX, mPopupY, mPopupWidth, popupHeight, false); - } - - private void updateBubblePosition() { - float x = ((mPopupWidth - mBubbleWidth) * (mReverse ? (1.0f - mDrawPercent) : mDrawPercent)); - mBubble.setX(x); - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - - updatePopup(); - updateBubblePosition(); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - - mPopup.showAtLocation(this, Gravity.TOP | Gravity.LEFT, mPopupX, mPopupY); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - - mPopup.dismiss(); - } - - private void startProgressAnimation(float percent) { - float currentValue; - if (mProgressAnimation.isRunning()) { - mProgressAnimation.setCurrentPlayTime(mProgressAnimation.getCurrentPlayTime()); - Object value = mProgressAnimation.getAnimatedValue(); - if (value instanceof Float) { - currentValue = (float) value; - } else { - currentValue = mDrawPercent; - } - } else { - currentValue = mDrawPercent; - } - mProgressAnimation.cancel(); - mProgressAnimation.setFloatValues(currentValue, percent); - mProgressAnimation.setDuration(Math.min(500, (long) (50 * getWidth() * Math.abs(currentValue - percent)))); - mProgressAnimation.start(); - } - - private void startShowBubbleAnimation() { - mBubbleScaleAnimation.cancel(); - mBubbleScaleAnimation.setFloatValues(mDrawBubbleScale, 1.0f); - mBubbleScaleAnimation.setInterpolator(AnimationUtils.FAST_SLOW_INTERPOLATOR); - mBubbleScaleAnimation.setDuration((long) (300 * Math.abs(mDrawBubbleScale - 1.0f))); - mBubbleScaleAnimation.start(); - } - - private void startHideBubbleAnimation() { - mBubbleScaleAnimation.cancel(); - mBubbleScaleAnimation.setFloatValues(mDrawBubbleScale, 0.0f); - mBubbleScaleAnimation.setInterpolator(AnimationUtils.SLOW_FAST_INTERPOLATOR); - mBubbleScaleAnimation.setDuration((long) (300 * Math.abs(mDrawBubbleScale - 0.0f))); - mBubbleScaleAnimation.start(); - } - - public void setColor(int color) { - mPaint.setColor(color); - mBubble.setColor(color); - invalidate(); - } - - public void setRange(int start, int end) { - mStart = start; - mEnd = end; - setProgress(mProgress); - - updateBubbleSize(); - } - - public int getProgress() { - return mProgress; - } - - public void setProgress(int progress) { - progress = MathUtils.clamp(progress, mStart, mEnd); - int oldProgress = mProgress; - if (mProgress != progress) { - mProgress = progress; - mPercent = MathUtils.delerp(mStart, mEnd, mProgress); - mTargetProgress = progress; - - if (mProgressAnimation == null) { - // For init - mDrawPercent = mPercent; - mDrawProgress = mProgress; - updateBubblePosition(); - mBubble.setProgress(mDrawProgress); - } else { - startProgressAnimation(mPercent); - } - invalidate(); - } - if (mListener != null) { - mListener.onSetProgress(this, progress, oldProgress, false, true); - } - } - - public void setReverse(boolean reverse) { - if (mReverse != reverse) { - mReverse = reverse; - invalidate(); - } - } - - public void setOnSetProgressListener(OnSetProgressListener listener) { - mListener = listener; - } - - @Override - protected void onDraw(@NonNull Canvas canvas) { - int width = getWidth(); - int height = getHeight(); - if (width < LayoutUtils.dp2pix(mContext, 24)) { - canvas.drawRect(0, 0, width, getHeight(), mPaint); - } else { - int paddingLeft = getPaddingLeft(); - int paddingTop = getPaddingTop(); - int paddingRight = getPaddingRight(); - int paddingBottom = getPaddingBottom(); - float thickness = mThickness; - float radius = mRadius; - float halfThickness = thickness / 2; - - int saved = canvas.save(); - - canvas.translate(0, paddingTop + ((height - paddingTop - paddingBottom) / 2)); - - float currentX = paddingLeft + radius + (width - radius - radius - paddingLeft - paddingRight) * - (mReverse ? (1.0f - mDrawPercent) : mDrawPercent); - - mLeftRectF.set(paddingLeft + radius, -halfThickness, currentX, halfThickness); - mRightRectF.set(currentX, -halfThickness, width - paddingRight - radius, halfThickness); - - // Draw bar - if (mReverse) { - canvas.drawRect(mRightRectF, mPaint); - canvas.drawRect(mLeftRectF, mBgPaint); - } else { - canvas.drawRect(mLeftRectF, mPaint); - canvas.drawRect(mRightRectF, mBgPaint); - } - - // Draw controller - float scale = 1.0f - mDrawBubbleScale; - if (scale != 0.0f) { - canvas.scale(scale, scale, currentX, 0); - canvas.drawCircle(currentX, 0, radius, mPaint); - } - - canvas.restoreToCount(saved); - } - } - - private void setShowBubble(boolean showBubble) { - if (mShowBubble != showBubble) { - mShowBubble = showBubble; - if (showBubble) { - startShowBubbleAnimation(); - } else { - startHideBubbleAnimation(); - } - } - } - - @SuppressLint("ClickableViewAccessibility") - @Override - public boolean onTouchEvent(@NonNull MotionEvent event) { - int action = event.getAction(); - switch (action) { - case MotionEvent.ACTION_DOWN: - case MotionEvent.ACTION_MOVE: - case MotionEvent.ACTION_UP: - case MotionEvent.ACTION_CANCEL: - - if (mListener != null) { - if (action == MotionEvent.ACTION_DOWN) { - mListener.onFingerDown(); - } else if (action == MotionEvent.ACTION_UP) { - mListener.onFingerUp(); - } - } - - int paddingLeft = getPaddingLeft(); - int paddingRight = getPaddingRight(); - float radius = mRadius; - float x = event.getX(); - int progress = Math.round(MathUtils.lerp((float) mStart, (float) mEnd, - MathUtils.clamp((mReverse ? (getWidth() - paddingLeft - radius - x) : (x - radius - paddingLeft)) / - (getWidth() - radius - radius - paddingLeft - paddingRight), 0.0f, 1.0f))); - float percent = MathUtils.delerp(mStart, mEnd, progress); - - // ACTION_CANCEL not changed - if (action == MotionEvent.ACTION_CANCEL) { - progress = mProgress; - percent = mPercent; - } - - if (mTargetProgress != progress) { - mTargetProgress = progress; - startProgressAnimation(percent); - - if (mListener != null) { - mListener.onSetProgress(this, mProgress, progress, true, false); - } - } - - if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) { - SimpleHandler.getInstance().removeCallbacks(mCheckForShowBubble); - setShowBubble(false); - } else if (action == MotionEvent.ACTION_DOWN) { - if (mCheckForShowBubble == null) { - mCheckForShowBubble = new CheckForShowBubble(); - } - SimpleHandler.getInstance().postDelayed(mCheckForShowBubble, ViewConfiguration.getTapTimeout()); - } - - if (action == MotionEvent.ACTION_UP) { - int oldProgress = mProgress; - if (mProgress != progress) { - mProgress = progress; - mPercent = mDrawPercent; - } - if (mListener != null) { - mListener.onSetProgress(this, progress, oldProgress, true, true); - } - } - break; - } - - return true; - } - - public interface OnSetProgressListener { - - void onSetProgress(Slider slider, int newProgress, int oldProgress, boolean byUser, boolean confirm); - - void onFingerDown(); - - void onFingerUp(); - } - - @SuppressLint("ViewConstructor") - private static class BubbleView extends AppCompatImageView { - - private static final float TEXT_CENTER = (float) BUBBLE_WIDTH / 2.0f / BUBBLE_HEIGHT; - - private final Drawable mDrawable; - - private final Paint mTextPaint; - private final Rect mRect = new Rect(); - private String mProgressStr = ""; - - public BubbleView(Context context, Paint paint) { - super(context); - setImageResource(R.drawable.v_slider_bubble); - mDrawable = DrawableCompat.wrap(getDrawable()); - setImageDrawable(mDrawable); - mTextPaint = paint; - } - - public void setColor(int color) { - DrawableCompat.setTint(mDrawable, color); - } - - public void setProgress(int progress) { - String str = Integer.toString(progress); - if (!str.equals(mProgressStr)) { - mProgressStr = str; - mTextPaint.getTextBounds(str, 0, str.length(), mRect); - invalidate(); - } - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) { - super.onSizeChanged(w, h, oldw, oldh); - setPivotX(w / 2); - setPivotY(h); - } - - @Override - protected void onDraw(@NonNull Canvas canvas) { - super.onDraw(canvas); - - int width = getWidth(); - int height = getHeight(); - int x = width / 2; - int y = (int) ((height * TEXT_CENTER) + (mRect.height() / 2)); - canvas.drawText(mProgressStr, x, y, mTextPaint); - } - } - - private final class CheckForShowBubble implements Runnable { - - @Override - public void run() { - setShowBubble(true); - } - } -} diff --git a/app/src/main/res/layout/dialog_go_to.xml b/app/src/main/res/layout/dialog_go_to.xml index 47512bbab..a3756a334 100644 --- a/app/src/main/res/layout/dialog_go_to.xml +++ b/app/src/main/res/layout/dialog_go_to.xml @@ -28,13 +28,14 @@ android:layout_gravity="center_vertical" android:gravity="center_horizontal" /> - + android:layout_weight="1" + android:stepSize="1" + android:valueFrom="1" /> center_vertical - -