New scroll bar

This commit is contained in:
h4h13 2020-01-18 13:15:20 +05:30
parent 77f7b1bd5b
commit 24f78d9738
4 changed files with 261 additions and 0 deletions

View file

@ -0,0 +1,49 @@
/*
* Copyright (c) 2020 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic.util
import android.view.ViewGroup
import code.name.monkey.appthemehelper.ThemeStore.Companion.accentColor
import code.name.monkey.appthemehelper.util.ColorUtil.isColorLight
import code.name.monkey.appthemehelper.util.MaterialValueHelper.getPrimaryTextColor
import code.name.monkey.appthemehelper.util.TintHelper
import code.name.monkey.retromusic.views.PopupBackground
import me.zhanghai.android.fastscroll.FastScroller
import me.zhanghai.android.fastscroll.FastScrollerBuilder
import me.zhanghai.android.fastscroll.PopupStyles
import me.zhanghai.android.fastscroll.R
object ThemedFastScroller {
fun create(view: ViewGroup): FastScroller {
val context = view.context
val color = accentColor(context)
val textColor = getPrimaryTextColor(context, isColorLight(color))
val fastScrollerBuilder = FastScrollerBuilder(view)
fastScrollerBuilder.useMd2Style()
fastScrollerBuilder.setPopupStyle { popupText ->
PopupStyles.MD2.accept(popupText)
popupText.background = PopupBackground(context)
popupText.setTextColor(textColor)
}
fastScrollerBuilder.setThumbDrawable(
TintHelper.createTintedDrawable(
context,
R.drawable.afs_md2_thumb,
color
)
)
return fastScrollerBuilder.build()
}
}

View file

@ -0,0 +1,155 @@
/*
* Copyright (c) 2020 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic.views;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Matrix;
import android.graphics.Outline;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.graphics.drawable.DrawableCompat;
import code.name.monkey.appthemehelper.ThemeStore;
import code.name.monkey.retromusic.R;
public class PopupBackground extends Drawable {
private final int mPaddingEnd;
private final int mPaddingStart;
@NonNull
private final Paint mPaint;
@NonNull
private final Path mPath = new Path();
@NonNull
private final Matrix mTempMatrix = new Matrix();
public PopupBackground(@NonNull Context context) {
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(ThemeStore.Companion.accentColor(context));
mPaint.setStyle(Paint.Style.FILL);
Resources resources = context.getResources();
mPaddingStart = resources.getDimensionPixelOffset(R.dimen.afs_md2_popup_padding_start);
mPaddingEnd = resources.getDimensionPixelOffset(R.dimen.afs_md2_popup_padding_end);
}
@Override
public void draw(@NonNull Canvas canvas) {
canvas.drawPath(mPath, mPaint);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
@Override
public void getOutline(@NonNull Outline outline) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q && !mPath.isConvex()) {
// The outline path must be convex before Q, but we may run into floating point error
// caused by calculation involving sqrt(2) or OEM implementation difference, so in this
// case we just omit the shadow instead of crashing.
super.getOutline(outline);
return;
}
outline.setConvexPath(mPath);
}
@Override
public boolean getPadding(@NonNull Rect padding) {
if (needMirroring()) {
padding.set(mPaddingEnd, 0, mPaddingStart, 0);
} else {
padding.set(mPaddingStart, 0, mPaddingEnd, 0);
}
return true;
}
@Override
public boolean isAutoMirrored() {
return true;
}
@Override
public boolean onLayoutDirectionChanged(int layoutDirection) {
updatePath();
return true;
}
@Override
public void setAlpha(int alpha) {
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
}
@Override
protected void onBoundsChange(@NonNull Rect bounds) {
updatePath();
}
private boolean needMirroring() {
return DrawableCompat.getLayoutDirection(this) == View.LAYOUT_DIRECTION_RTL;
}
private void updatePath() {
mPath.reset();
Rect bounds = getBounds();
float width = bounds.width();
float height = bounds.height();
float r = height / 2;
float sqrt2 = (float) Math.sqrt(2);
// Ensure we are convex.
width = Math.max(r + sqrt2 * r, width);
pathArcTo(mPath, r, r, r, 90, 180);
float o1X = width - sqrt2 * r;
pathArcTo(mPath, o1X, r, r, -90, 45f);
float r2 = r / 5;
float o2X = width - sqrt2 * r2;
pathArcTo(mPath, o2X, r, r2, -45, 90);
pathArcTo(mPath, o1X, r, r, 45f, 45f);
mPath.close();
if (needMirroring()) {
mTempMatrix.setScale(-1, 1, width / 2, 0);
} else {
mTempMatrix.reset();
}
mTempMatrix.postTranslate(bounds.left, bounds.top);
mPath.transform(mTempMatrix);
}
private static void pathArcTo(@NonNull Path path, float centerX, float centerY, float radius,
float startAngle, float sweepAngle) {
path.arcTo(centerX - radius, centerY - radius, centerX + radius, centerY + radius,
startAngle, sweepAngle, false);
}
}

View file

@ -0,0 +1,57 @@
/*
* Copyright (c) 2020 Hemanth Savarala.
*
* Licensed under the GNU General Public License v3
*
* This is free software: you can redistribute it and/or modify it under
* the terms of the GNU General Public License as published by
* the Free Software Foundation either version 3 of the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.
*/
package code.name.monkey.retromusic.views;
import android.graphics.Rect;
import android.view.View;
import android.view.WindowInsets;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import me.zhanghai.android.fastscroll.FastScroller;
public class ScrollingViewOnApplyWindowInsetsListener implements View.OnApplyWindowInsetsListener {
@NonNull
private final Rect mPadding = new Rect();
@Nullable
private final FastScroller mFastScroller;
public ScrollingViewOnApplyWindowInsetsListener(@Nullable View view,
@Nullable FastScroller fastScroller) {
if (view != null) {
mPadding.set(view.getPaddingLeft(), view.getPaddingTop(), view.getPaddingRight(),
view.getPaddingBottom());
}
mFastScroller = fastScroller;
}
public ScrollingViewOnApplyWindowInsetsListener() {
this(null, null);
}
@NonNull
@Override
public WindowInsets onApplyWindowInsets(@NonNull View view, @NonNull WindowInsets insets) {
view.setPadding(mPadding.left + insets.getSystemWindowInsetLeft(), mPadding.top,
mPadding.right + insets.getSystemWindowInsetRight(),
mPadding.bottom + insets.getSystemWindowInsetBottom());
if (mFastScroller != null) {
mFastScroller.setPadding(insets.getSystemWindowInsetLeft(), 0,
insets.getSystemWindowInsetRight(), insets.getSystemWindowInsetBottom());
}
return insets;
}
}