mirror of
https://github.com/cmclark00/RetroMusicPlayer.git
synced 2025-05-20 00:55:20 +01:00
Code refactor and Flat, Fit, Full, Circle theme toolbar shadow fixes
This commit is contained in:
parent
954dfb6327
commit
724f743627
304 changed files with 3874 additions and 3524 deletions
|
@ -19,10 +19,13 @@ import android.content.res.TypedArray;
|
|||
import android.graphics.Paint;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
|
||||
import androidx.annotation.FontRes;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
import com.google.android.material.textview.MaterialTextView;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
public class BaselineGridTextView extends MaterialTextView {
|
||||
|
||||
private final float FOUR_DIP;
|
||||
|
|
|
@ -41,8 +41,16 @@ class BottomNavigationBarTinted @JvmOverloads constructor(
|
|||
|
||||
val iconColor = ATHUtil.resolveColor(context, android.R.attr.colorControlNormal)
|
||||
val accentColor = ThemeStore.accentColor(context)
|
||||
NavigationViewUtil.setItemIconColors(this, ColorUtil.withAlpha(iconColor, 0.5f), accentColor)
|
||||
NavigationViewUtil.setItemTextColors(this, ColorUtil.withAlpha(iconColor, 0.5f), accentColor)
|
||||
NavigationViewUtil.setItemIconColors(
|
||||
this,
|
||||
ColorUtil.withAlpha(iconColor, 0.5f),
|
||||
accentColor
|
||||
)
|
||||
NavigationViewUtil.setItemTextColors(
|
||||
this,
|
||||
ColorUtil.withAlpha(iconColor, 0.5f),
|
||||
accentColor
|
||||
)
|
||||
itemBackground = RippleDrawable(
|
||||
RippleUtils.convertToRippleDrawableColor(
|
||||
ColorStateList.valueOf(
|
||||
|
|
|
@ -26,156 +26,35 @@ import android.widget.HorizontalScrollView;
|
|||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.ColorInt;
|
||||
import androidx.annotation.NonNull;
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import code.name.monkey.appthemehelper.util.ATHUtil;
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
/**
|
||||
* @author Aidan Follestad (afollestad), modified for Phonograph by Karim Abou Zeid (kabouzeid)
|
||||
*/
|
||||
public class BreadCrumbLayout extends HorizontalScrollView implements View.OnClickListener {
|
||||
|
||||
public static class Crumb implements Parcelable {
|
||||
|
||||
public static final Creator<Crumb> CREATOR = new Creator<Crumb>() {
|
||||
@Override
|
||||
public Crumb createFromParcel(Parcel source) {
|
||||
return new Crumb(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Crumb[] newArray(int size) {
|
||||
return new Crumb[size];
|
||||
}
|
||||
};
|
||||
|
||||
private final File file;
|
||||
|
||||
private int scrollPos;
|
||||
|
||||
public Crumb(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
protected Crumb(Parcel in) {
|
||||
this.file = (File) in.readSerializable();
|
||||
this.scrollPos = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof Crumb) && ((Crumb) o).getFile() != null &&
|
||||
((Crumb) o).getFile().equals(getFile());
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public int getScrollPosition() {
|
||||
return scrollPos;
|
||||
}
|
||||
|
||||
public void setScrollPosition(int scrollY) {
|
||||
this.scrollPos = scrollY;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return file.getPath().equals("/") ? "root" : file.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Crumb{" +
|
||||
"file=" + file +
|
||||
", scrollPos=" + scrollPos +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeSerializable(this.file);
|
||||
dest.writeInt(this.scrollPos);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SavedStateWrapper implements Parcelable {
|
||||
|
||||
public static final Creator<SavedStateWrapper> CREATOR = new Creator<SavedStateWrapper>() {
|
||||
public SavedStateWrapper createFromParcel(Parcel source) {
|
||||
return new SavedStateWrapper(source);
|
||||
}
|
||||
|
||||
public SavedStateWrapper[] newArray(int size) {
|
||||
return new SavedStateWrapper[size];
|
||||
}
|
||||
};
|
||||
|
||||
public final int mActive;
|
||||
|
||||
public final List<Crumb> mCrumbs;
|
||||
|
||||
public final int mVisibility;
|
||||
|
||||
public SavedStateWrapper(BreadCrumbLayout view) {
|
||||
mActive = view.mActive;
|
||||
mCrumbs = view.mCrumbs;
|
||||
mVisibility = view.getVisibility();
|
||||
}
|
||||
|
||||
protected SavedStateWrapper(Parcel in) {
|
||||
this.mActive = in.readInt();
|
||||
this.mCrumbs = in.createTypedArrayList(Crumb.CREATOR);
|
||||
this.mVisibility = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(this.mActive);
|
||||
dest.writeTypedList(mCrumbs);
|
||||
dest.writeInt(this.mVisibility);
|
||||
}
|
||||
}
|
||||
|
||||
public interface SelectionCallback {
|
||||
|
||||
void onCrumbSelection(Crumb crumb, int index);
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
private int contentColorActivated;
|
||||
|
||||
@ColorInt
|
||||
private int contentColorDeactivated;
|
||||
|
||||
private int mActive;
|
||||
|
||||
private SelectionCallback mCallback;
|
||||
|
||||
private LinearLayout mChildFrame;
|
||||
|
||||
// Stores currently visible crumbs
|
||||
private List<Crumb> mCrumbs;
|
||||
|
||||
// Stores user's navigation history, like a fragment back stack
|
||||
private List<Crumb> mHistory;
|
||||
|
||||
// Used in setActiveOrAdd() between clearing crumbs and adding the new set, nullified afterwards
|
||||
private List<Crumb> mOldCrumbs;
|
||||
|
||||
|
@ -422,7 +301,7 @@ public class BreadCrumbLayout extends HorizontalScrollView implements View.OnCli
|
|||
}
|
||||
|
||||
private TextView invalidateActivated(View view, final boolean isActive, final boolean noArrowIfAlone,
|
||||
final boolean allowArrowVisible) {
|
||||
final boolean allowArrowVisible) {
|
||||
int contentColor = isActive ? contentColorActivated : contentColorDeactivated;
|
||||
LinearLayout child = (LinearLayout) view;
|
||||
TextView tv = (TextView) child.getChildAt(0);
|
||||
|
@ -448,4 +327,121 @@ public class BreadCrumbLayout extends HorizontalScrollView implements View.OnCli
|
|||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
public interface SelectionCallback {
|
||||
|
||||
void onCrumbSelection(Crumb crumb, int index);
|
||||
}
|
||||
|
||||
public static class Crumb implements Parcelable {
|
||||
|
||||
public static final Creator<Crumb> CREATOR = new Creator<Crumb>() {
|
||||
@Override
|
||||
public Crumb createFromParcel(Parcel source) {
|
||||
return new Crumb(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Crumb[] newArray(int size) {
|
||||
return new Crumb[size];
|
||||
}
|
||||
};
|
||||
|
||||
private final File file;
|
||||
|
||||
private int scrollPos;
|
||||
|
||||
public Crumb(File file) {
|
||||
this.file = file;
|
||||
}
|
||||
|
||||
protected Crumb(Parcel in) {
|
||||
this.file = (File) in.readSerializable();
|
||||
this.scrollPos = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return (o instanceof Crumb) && ((Crumb) o).getFile() != null &&
|
||||
((Crumb) o).getFile().equals(getFile());
|
||||
}
|
||||
|
||||
public File getFile() {
|
||||
return file;
|
||||
}
|
||||
|
||||
public int getScrollPosition() {
|
||||
return scrollPos;
|
||||
}
|
||||
|
||||
public void setScrollPosition(int scrollY) {
|
||||
this.scrollPos = scrollY;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return file.getPath().equals("/") ? "root" : file.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Crumb{" +
|
||||
"file=" + file +
|
||||
", scrollPos=" + scrollPos +
|
||||
'}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeSerializable(this.file);
|
||||
dest.writeInt(this.scrollPos);
|
||||
}
|
||||
}
|
||||
|
||||
public static class SavedStateWrapper implements Parcelable {
|
||||
|
||||
public static final Creator<SavedStateWrapper> CREATOR = new Creator<SavedStateWrapper>() {
|
||||
public SavedStateWrapper createFromParcel(Parcel source) {
|
||||
return new SavedStateWrapper(source);
|
||||
}
|
||||
|
||||
public SavedStateWrapper[] newArray(int size) {
|
||||
return new SavedStateWrapper[size];
|
||||
}
|
||||
};
|
||||
|
||||
public final int mActive;
|
||||
|
||||
public final List<Crumb> mCrumbs;
|
||||
|
||||
public final int mVisibility;
|
||||
|
||||
public SavedStateWrapper(BreadCrumbLayout view) {
|
||||
mActive = view.mActive;
|
||||
mCrumbs = view.mCrumbs;
|
||||
mVisibility = view.getVisibility();
|
||||
}
|
||||
|
||||
protected SavedStateWrapper(Parcel in) {
|
||||
this.mActive = in.readInt();
|
||||
this.mCrumbs = in.createTypedArrayList(Crumb.CREATOR);
|
||||
this.mVisibility = in.readInt();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int describeContents() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
dest.writeInt(this.mActive);
|
||||
dest.writeTypedList(mCrumbs);
|
||||
dest.writeInt(this.mVisibility);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,10 +25,11 @@ import android.graphics.Paint;
|
|||
import android.graphics.Shader;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.appcompat.widget.AppCompatImageView;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
public class CircularImageView extends AppCompatImageView {
|
||||
|
|
|
@ -25,6 +25,7 @@ import android.widget.TextView;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
import static code.name.monkey.retromusic.util.RetroUtil.openUrl;
|
||||
|
|
|
@ -37,7 +37,11 @@ class ListItemView : FrameLayout {
|
|||
init(context, attrs)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
||||
constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr
|
||||
) {
|
||||
init(context, attrs)
|
||||
}
|
||||
|
||||
|
|
|
@ -36,15 +36,21 @@ class MetalRecyclerViewPager : RecyclerView {
|
|||
init(context, attrs)
|
||||
}
|
||||
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
|
||||
constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(
|
||||
context,
|
||||
attrs,
|
||||
defStyleAttr
|
||||
) {
|
||||
init(context, attrs)
|
||||
}
|
||||
|
||||
private var itemMargin: Int = 0
|
||||
|
||||
fun init(context: Context, attrs: AttributeSet?) {
|
||||
val typedArray = context.obtainStyledAttributes(attrs, R.styleable.MetalRecyclerViewPager, 0, 0)
|
||||
itemMargin = typedArray.getDimension(R.styleable.MetalRecyclerViewPager_itemMargin, 0f).toInt()
|
||||
val typedArray =
|
||||
context.obtainStyledAttributes(attrs, R.styleable.MetalRecyclerViewPager, 0, 0)
|
||||
itemMargin =
|
||||
typedArray.getDimension(R.styleable.MetalRecyclerViewPager_itemMargin, 0f).toInt()
|
||||
typedArray.recycle()
|
||||
|
||||
layoutManager = LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false)
|
||||
|
@ -62,7 +68,8 @@ class MetalRecyclerViewPager : RecyclerView {
|
|||
super.setAdapter(adapter)
|
||||
}
|
||||
|
||||
abstract class MetalAdapter<VH : MetalViewHolder>(@NonNull val displayMetrics: DisplayMetrics) : RecyclerView.Adapter<VH>() {
|
||||
abstract class MetalAdapter<VH : MetalViewHolder>(@NonNull val displayMetrics: DisplayMetrics) :
|
||||
RecyclerView.Adapter<VH>() {
|
||||
private var itemMargin: Int = 0
|
||||
private var itemWidth: Int = 0
|
||||
|
||||
|
|
|
@ -27,9 +27,11 @@ 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;
|
||||
|
||||
|
@ -58,6 +60,12 @@ public class PopupBackground extends Drawable {
|
|||
mPaddingEnd = resources.getDimensionPixelOffset(R.dimen.afs_md2_popup_padding_end);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(@NonNull Canvas canvas) {
|
||||
canvas.drawPath(mPath, mPaint);
|
||||
|
@ -146,10 +154,4 @@ public class PopupBackground extends Drawable {
|
|||
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);
|
||||
}
|
||||
}
|
|
@ -20,6 +20,7 @@ import android.view.WindowInsets;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import me.zhanghai.android.fastscroll.FastScroller;
|
||||
|
||||
public class ScrollingViewOnApplyWindowInsetsListener implements View.OnApplyWindowInsetsListener {
|
||||
|
|
|
@ -24,11 +24,12 @@ import android.util.AttributeSet;
|
|||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
|
||||
import code.name.monkey.retromusic.R;
|
||||
|
||||
/**
|
||||
* SeekArc.java
|
||||
*
|
||||
* <p>
|
||||
* This is a class that functions much like a SeekBar but
|
||||
* follows a circle path instead of a straight line.
|
||||
*
|
||||
|
@ -36,129 +37,70 @@ import code.name.monkey.retromusic.R;
|
|||
*/
|
||||
public class SeekArc extends View {
|
||||
|
||||
public interface OnSeekArcChangeListener {
|
||||
|
||||
/**
|
||||
* Notification that the progress level has changed. Clients can use the
|
||||
* fromUser parameter to distinguish user-initiated changes from those
|
||||
* that occurred programmatically.
|
||||
*
|
||||
* @param seekArc The SeekArc whose progress has changed
|
||||
* @param progress The current progress level. This will be in the range
|
||||
* 0..max where max was set by
|
||||
* {@link ProgressArc#setMax(int)}. (The default value for
|
||||
* max is 100.)
|
||||
* @param fromUser True if the progress change was initiated by the user.
|
||||
*/
|
||||
void onProgressChanged(SeekArc seekArc, int progress, boolean fromUser);
|
||||
|
||||
/**
|
||||
* Notification that the user has started a touch gesture. Clients may
|
||||
* want to use this to disable advancing the seekbar.
|
||||
*
|
||||
* @param seekArc The SeekArc in which the touch gesture began
|
||||
*/
|
||||
void onStartTrackingTouch(SeekArc seekArc);
|
||||
|
||||
/**
|
||||
* Notification that the user has finished a touch gesture. Clients may
|
||||
* want to use this to re-enable advancing the seekarc.
|
||||
*
|
||||
* @param seekArc The SeekArc in which the touch gesture began
|
||||
*/
|
||||
void onStopTrackingTouch(SeekArc seekArc);
|
||||
}
|
||||
|
||||
private static final String TAG = SeekArc.class.getSimpleName();
|
||||
|
||||
private static int INVALID_PROGRESS_VALUE = -1;
|
||||
|
||||
// The initial rotational offset -90 means we start at 12 o'clock
|
||||
private final int mAngleOffset = -90;
|
||||
|
||||
private Paint mArcPaint;
|
||||
|
||||
// Internal variables
|
||||
private int mArcRadius = 0;
|
||||
|
||||
private RectF mArcRect = new RectF();
|
||||
|
||||
/**
|
||||
* The Width of the background arc for the SeekArc
|
||||
*/
|
||||
private int mArcWidth = 2;
|
||||
|
||||
/**
|
||||
* Will the progress increase clockwise or anti-clockwise
|
||||
*/
|
||||
private boolean mClockwise = true;
|
||||
|
||||
/**
|
||||
* is the control enabled/touchable
|
||||
*/
|
||||
private boolean mEnabled = true;
|
||||
|
||||
/**
|
||||
* The Maximum value that this SeekArc can be set to
|
||||
*/
|
||||
private int mMax = 100;
|
||||
|
||||
private OnSeekArcChangeListener mOnSeekArcChangeListener;
|
||||
|
||||
/**
|
||||
* The Current value that the SeekArc is set to
|
||||
*/
|
||||
private int mProgress = 0;
|
||||
|
||||
private Paint mProgressPaint;
|
||||
|
||||
private float mProgressSweep = 0;
|
||||
|
||||
/**
|
||||
* The width of the progress line for this SeekArc
|
||||
*/
|
||||
private int mProgressWidth = 4;
|
||||
|
||||
/**
|
||||
* The rotation of the SeekArc- 0 is twelve o'clock
|
||||
*/
|
||||
private int mRotation = 0;
|
||||
|
||||
/**
|
||||
* Give the SeekArc rounded edges
|
||||
*/
|
||||
private boolean mRoundedEdges = false;
|
||||
|
||||
/**
|
||||
* The Angle to start drawing this Arc from
|
||||
*/
|
||||
private int mStartAngle = 0;
|
||||
|
||||
/**
|
||||
* The Angle through which to draw the arc (Max is 360)
|
||||
*/
|
||||
private int mSweepAngle = 360;
|
||||
|
||||
/**
|
||||
* The Drawable for the seek arc thumbnail
|
||||
*/
|
||||
private Drawable mThumb;
|
||||
|
||||
private int mThumbXPos;
|
||||
|
||||
private int mThumbYPos;
|
||||
|
||||
private double mTouchAngle;
|
||||
|
||||
private float mTouchIgnoreRadius;
|
||||
|
||||
/**
|
||||
* Enable touch inside the SeekArc
|
||||
*/
|
||||
private boolean mTouchInside = true;
|
||||
|
||||
private int mTranslateX;
|
||||
|
||||
private int mTranslateY;
|
||||
|
||||
public SeekArc(Context context) {
|
||||
|
@ -574,4 +516,37 @@ public class SeekArc extends View {
|
|||
private float valuePerDegree() {
|
||||
return (float) mMax / mSweepAngle;
|
||||
}
|
||||
|
||||
public interface OnSeekArcChangeListener {
|
||||
|
||||
/**
|
||||
* Notification that the progress level has changed. Clients can use the
|
||||
* fromUser parameter to distinguish user-initiated changes from those
|
||||
* that occurred programmatically.
|
||||
*
|
||||
* @param seekArc The SeekArc whose progress has changed
|
||||
* @param progress The current progress level. This will be in the range
|
||||
* 0..max where max was set by
|
||||
* {@link ProgressArc#setMax(int)}. (The default value for
|
||||
* max is 100.)
|
||||
* @param fromUser True if the progress change was initiated by the user.
|
||||
*/
|
||||
void onProgressChanged(SeekArc seekArc, int progress, boolean fromUser);
|
||||
|
||||
/**
|
||||
* Notification that the user has started a touch gesture. Clients may
|
||||
* want to use this to disable advancing the seekbar.
|
||||
*
|
||||
* @param seekArc The SeekArc in which the touch gesture began
|
||||
*/
|
||||
void onStartTrackingTouch(SeekArc seekArc);
|
||||
|
||||
/**
|
||||
* Notification that the user has finished a touch gesture. Clients may
|
||||
* want to use this to re-enable advancing the seekarc.
|
||||
*
|
||||
* @param seekArc The SeekArc in which the touch gesture began
|
||||
*/
|
||||
void onStopTrackingTouch(SeekArc seekArc);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue