Implemented app-theme-helper. Needs to be cleaned up.
This commit is contained in:
parent
178c15dafb
commit
8b98a9be85
39 changed files with 275 additions and 1370 deletions
|
|
@ -1,76 +0,0 @@
|
|||
package com.kabouzeid.gramophone.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.util.AttributeSet;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.util.ColorUtil;
|
||||
|
||||
public class ColorView extends FrameLayout {
|
||||
|
||||
private final Paint paint;
|
||||
private final Paint paintBorder;
|
||||
private final int borderWidth;
|
||||
|
||||
public ColorView(@NonNull Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
|
||||
public ColorView(@NonNull Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public ColorView(@NonNull Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
borderWidth = getResources().getDimensionPixelSize(R.dimen.color_view_border);
|
||||
|
||||
paint = new Paint();
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
paintBorder = new Paint();
|
||||
paintBorder.setAntiAlias(true);
|
||||
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
|
||||
public void setColor(int color) {
|
||||
paint.setColor(color);
|
||||
paintBorder.setColor(ColorUtil.shiftColorDown(color));
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
if (widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) {
|
||||
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
//noinspection SuspiciousNameCombination
|
||||
int height = width;
|
||||
if (heightMode == MeasureSpec.AT_MOST) {
|
||||
height = Math.min(height, MeasureSpec.getSize(heightMeasureSpec));
|
||||
}
|
||||
setMeasuredDimension(width, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(@NonNull Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
int canvasSize = canvas.getWidth();
|
||||
if (canvas.getHeight() < canvasSize)
|
||||
canvasSize = canvas.getHeight();
|
||||
|
||||
int circleCenter = (canvasSize - (borderWidth * 2)) / 2;
|
||||
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) + borderWidth - 4.0f, paintBorder);
|
||||
canvas.drawCircle(circleCenter + borderWidth, circleCenter + borderWidth, ((canvasSize - (borderWidth * 2)) / 2) - 4.0f, paint);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package com.kabouzeid.gramophone.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.AppCompatCheckBox;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.afollestad.materialdialogs.internal.MDTintHelper;
|
||||
import com.afollestad.materialdialogs.internal.ThemeSingleton;
|
||||
|
||||
/**
|
||||
* @author Aidan Follestad (afollestad)
|
||||
*/
|
||||
public class DynamicCheckBox extends AppCompatCheckBox {
|
||||
|
||||
public DynamicCheckBox(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public DynamicCheckBox(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public DynamicCheckBox(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
final int color = ThemeSingleton.get().positiveColor.getDefaultColor();
|
||||
MDTintHelper.setTint(this, color);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
package com.kabouzeid.gramophone.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v7.widget.AppCompatEditText;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
import com.afollestad.materialdialogs.internal.MDTintHelper;
|
||||
import com.afollestad.materialdialogs.internal.ThemeSingleton;
|
||||
|
||||
/**
|
||||
* @author Aidan Follestad (afollestad)
|
||||
*/
|
||||
public class DynamicEditText extends AppCompatEditText {
|
||||
|
||||
public DynamicEditText(Context context) {
|
||||
super(context);
|
||||
init();
|
||||
}
|
||||
|
||||
public DynamicEditText(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
init();
|
||||
}
|
||||
|
||||
public DynamicEditText(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
init();
|
||||
}
|
||||
|
||||
private void init() {
|
||||
final int color = ThemeSingleton.get().positiveColor.getDefaultColor();
|
||||
MDTintHelper.setTint(this, color);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,212 +0,0 @@
|
|||
package com.kabouzeid.gramophone.views;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.InsetDrawable;
|
||||
import android.graphics.drawable.StateListDrawable;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewPropertyAnimator;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.kabouzeid.gramophone.R;
|
||||
import com.kabouzeid.gramophone.util.ColorUtil;
|
||||
import com.kabouzeid.gramophone.util.Util;
|
||||
|
||||
import static android.support.v7.widget.RecyclerView.OnScrollListener;
|
||||
|
||||
public class FastScroller extends FrameLayout {
|
||||
private static final int HANDLE_HIDE_DELAY = 1500;
|
||||
private static final int HANDLE_ANIMATION_DURATION = 300;
|
||||
|
||||
private View handle;
|
||||
private View bar;
|
||||
|
||||
private RecyclerView recyclerView;
|
||||
|
||||
private final HandleHider handleHider = new HandleHider();
|
||||
private final ScrollListener scrollListener = new ScrollListener();
|
||||
|
||||
private boolean isHidden;
|
||||
private int hideTranslationX;
|
||||
|
||||
@Nullable
|
||||
private ViewPropertyAnimator currentAnimator = null;
|
||||
|
||||
public FastScroller(@NonNull Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
initialise(context);
|
||||
}
|
||||
|
||||
public FastScroller(@NonNull Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
initialise(context);
|
||||
}
|
||||
|
||||
private void initialise(@NonNull Context context) {
|
||||
hideTranslationX = getContext().getResources().getDimensionPixelSize(R.dimen.scrollbar_width) * (Util.isRTL(context) ? -1 : 1);
|
||||
setClipChildren(false);
|
||||
inflate(context, R.layout.vertical_recycler_fast_scroller_layout, this);
|
||||
handle = findViewById(R.id.scroll_handle);
|
||||
bar = findViewById(R.id.scroll_bar);
|
||||
handle.setEnabled(true);
|
||||
setPressedHandleColor(ColorUtil.resolveColor(getContext(), R.attr.colorControlActivated));
|
||||
setUpBarBackground();
|
||||
postDelayed(handleHider, HANDLE_HIDE_DELAY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onTouchEvent(@NonNull MotionEvent event) {
|
||||
if (event.getAction() == MotionEvent.ACTION_DOWN || event.getAction() == MotionEvent.ACTION_MOVE) {
|
||||
handle.setPressed(true);
|
||||
setRecyclerViewPosition(event.getY());
|
||||
showIfHidden();
|
||||
return true;
|
||||
} else if (event.getAction() == MotionEvent.ACTION_UP) {
|
||||
handle.setPressed(false);
|
||||
scheduleHide();
|
||||
return true;
|
||||
}
|
||||
return super.onTouchEvent(event);
|
||||
}
|
||||
|
||||
public void setRecyclerView(@NonNull RecyclerView recyclerView) {
|
||||
this.recyclerView = recyclerView;
|
||||
recyclerView.addOnScrollListener(scrollListener);
|
||||
}
|
||||
|
||||
private void setRecyclerViewPosition(float y) {
|
||||
if (recyclerView != null) {
|
||||
int itemCount = recyclerView.getAdapter().getItemCount();
|
||||
float proportion = y / (float) getHeightMinusPadding();
|
||||
int targetPos = getValueInRange(0, itemCount - 1, Math.round(proportion * (float) itemCount));
|
||||
recyclerView.scrollToPosition(targetPos);
|
||||
}
|
||||
}
|
||||
|
||||
private int getValueInRange(int min, int max, int value) {
|
||||
int minimum = Math.max(min, value);
|
||||
return Math.min(minimum, max);
|
||||
}
|
||||
|
||||
private void setHandlePosition(float y) {
|
||||
float position = y / getHeightMinusPadding();
|
||||
int handleHeight = handle.getHeight();
|
||||
handle.setY(getValueInRange(0, getHeightMinusPadding() - handleHeight, Math.round((getHeightMinusPadding() - handleHeight) * position)));
|
||||
}
|
||||
|
||||
private void showImpl() {
|
||||
isHidden = false;
|
||||
if (currentAnimator != null) {
|
||||
currentAnimator.cancel();
|
||||
}
|
||||
currentAnimator = animate().translationX(0).setDuration(HANDLE_ANIMATION_DURATION);
|
||||
currentAnimator.start();
|
||||
}
|
||||
|
||||
private void hideImpl() {
|
||||
isHidden = true;
|
||||
if (currentAnimator != null) {
|
||||
currentAnimator.cancel();
|
||||
}
|
||||
currentAnimator = animate().translationX(hideTranslationX).setDuration(HANDLE_ANIMATION_DURATION);
|
||||
currentAnimator.setListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
super.onAnimationEnd(animation);
|
||||
currentAnimator = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
super.onAnimationCancel(animation);
|
||||
currentAnimator = null;
|
||||
}
|
||||
});
|
||||
currentAnimator.start();
|
||||
}
|
||||
|
||||
private class HandleHider implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
hideImpl();
|
||||
}
|
||||
}
|
||||
|
||||
private void showIfHidden() {
|
||||
if (isHidden) {
|
||||
getHandler().removeCallbacks(handleHider);
|
||||
showImpl();
|
||||
}
|
||||
}
|
||||
|
||||
private void scheduleHide() {
|
||||
getHandler().removeCallbacks(handleHider);
|
||||
getHandler().postDelayed(handleHider, HANDLE_HIDE_DELAY);
|
||||
}
|
||||
|
||||
private int getHeightMinusPadding() {
|
||||
return getHeight() - getPaddingBottom() - getPaddingTop();
|
||||
}
|
||||
|
||||
private float computeHandlePosition() {
|
||||
View firstVisibleView = recyclerView.getChildAt(0);
|
||||
int firstVisiblePosition = recyclerView.getChildAdapterPosition(firstVisibleView);
|
||||
int itemCount = recyclerView.getAdapter().getItemCount();
|
||||
|
||||
float proportion = (float) firstVisiblePosition / (float) itemCount;
|
||||
return getHeightMinusPadding() * proportion + recyclerView.getChildCount() * proportion;
|
||||
}
|
||||
|
||||
public void updateHandlePosition() {
|
||||
setHandlePosition(computeHandlePosition());
|
||||
}
|
||||
|
||||
public void setPressedHandleColor(int accent) {
|
||||
StateListDrawable drawable = new StateListDrawable();
|
||||
|
||||
int colorControlNormal = ColorUtil.resolveColor(getContext(), R.attr.colorControlNormal);
|
||||
|
||||
if (!Util.isRTL(getContext())) {
|
||||
drawable.addState(View.PRESSED_ENABLED_STATE_SET,
|
||||
new InsetDrawable(new ColorDrawable(accent), getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0, 0, 0));
|
||||
drawable.addState(View.EMPTY_STATE_SET,
|
||||
new InsetDrawable(new ColorDrawable(colorControlNormal), getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0, 0, 0));
|
||||
} else {
|
||||
drawable.addState(View.PRESSED_ENABLED_STATE_SET,
|
||||
new InsetDrawable(new ColorDrawable(accent), 0, 0, getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0));
|
||||
drawable.addState(View.EMPTY_STATE_SET,
|
||||
new InsetDrawable(new ColorDrawable(colorControlNormal), 0, 0, getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0));
|
||||
}
|
||||
handle.setBackground(drawable);
|
||||
}
|
||||
|
||||
private void setUpBarBackground() {
|
||||
Drawable drawable;
|
||||
|
||||
int colorControlNormal = ColorUtil.resolveColor(getContext(), R.attr.colorControlNormal);
|
||||
|
||||
if (!Util.isRTL(getContext())) {
|
||||
drawable = new InsetDrawable(new ColorDrawable(colorControlNormal), getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0, 0, 0);
|
||||
} else {
|
||||
drawable = new InsetDrawable(new ColorDrawable(colorControlNormal), 0, 0, getResources().getDimensionPixelSize(R.dimen.scrollbar_inset), 0);
|
||||
}
|
||||
bar.setBackground(drawable);
|
||||
}
|
||||
|
||||
private class ScrollListener extends OnScrollListener {
|
||||
@Override
|
||||
public void onScrolled(RecyclerView rv, int dx, int dy) {
|
||||
updateHandlePosition();
|
||||
showIfHidden();
|
||||
scheduleHide();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,157 +0,0 @@
|
|||
package com.kabouzeid.gramophone.views;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.Resources;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.graphics.drawable.RippleDrawable;
|
||||
import android.graphics.drawable.ShapeDrawable;
|
||||
import android.graphics.drawable.StateListDrawable;
|
||||
import android.graphics.drawable.shapes.OvalShape;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.ColorInt;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.TypedValue;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import com.afollestad.materialdialogs.internal.ThemeSingleton;
|
||||
import com.kabouzeid.gramophone.util.ColorUtil;
|
||||
|
||||
|
||||
public class SelectableColorView extends FrameLayout {
|
||||
|
||||
private boolean selected;
|
||||
|
||||
private final int borderWidthExtraSmall;
|
||||
private final int borderWidthSmall;
|
||||
private final int borderWidthLarge;
|
||||
|
||||
private Paint outerPaint;
|
||||
private Paint gapPaint;
|
||||
private Paint innerPaint;
|
||||
|
||||
public SelectableColorView(Context context) {
|
||||
this(context, null, 0);
|
||||
}
|
||||
|
||||
public SelectableColorView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public SelectableColorView(Context context, AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
final Resources r = getResources();
|
||||
borderWidthExtraSmall = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 1, r.getDisplayMetrics());
|
||||
borderWidthSmall = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 3, r.getDisplayMetrics());
|
||||
borderWidthLarge = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 5, r.getDisplayMetrics());
|
||||
|
||||
gapPaint = new Paint();
|
||||
gapPaint.setAntiAlias(true);
|
||||
gapPaint.setColor(ThemeSingleton.get().darkTheme ? Color.parseColor("#444444") : Color.WHITE);
|
||||
|
||||
innerPaint = new Paint();
|
||||
innerPaint.setAntiAlias(true);
|
||||
|
||||
outerPaint = new Paint();
|
||||
outerPaint.setAntiAlias(true);
|
||||
|
||||
setWillNotDraw(false);
|
||||
}
|
||||
|
||||
private void updateColor(@ColorInt int color) {
|
||||
innerPaint.setColor(color);
|
||||
outerPaint.setColor(ColorUtil.shiftColorDown(color));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||
int[][] states = new int[][]{
|
||||
new int[]{android.R.attr.state_pressed}
|
||||
};
|
||||
int[] colors = new int[]{createSelectedColor(color)};
|
||||
ColorStateList rippleColors = new ColorStateList(states, colors);
|
||||
Drawable mask = new ShapeDrawable(new OvalShape());
|
||||
RippleDrawable rippleDrawable = new RippleDrawable(rippleColors, null, mask);
|
||||
|
||||
setForeground(rippleDrawable);
|
||||
} else {
|
||||
ShapeDrawable pressedDrawable = new ShapeDrawable(new OvalShape());
|
||||
pressedDrawable.getPaint().setColor(createSelectedColor(color));
|
||||
StateListDrawable stateListDrawable = new StateListDrawable();
|
||||
stateListDrawable.addState(new int[]{android.R.attr.state_pressed}, pressedDrawable);
|
||||
|
||||
setForeground(stateListDrawable);
|
||||
}
|
||||
}
|
||||
|
||||
@ColorInt
|
||||
private static int createSelectedColor(int color) {
|
||||
if (ColorUtil.useDarkTextColorOnBackground(color)) {
|
||||
return ColorUtil.shiftColor(color, 0.8f);
|
||||
} else {
|
||||
return ColorUtil.shiftColor(color, 1.2f);
|
||||
}
|
||||
}
|
||||
|
||||
public void setColor(@ColorInt int color) {
|
||||
updateColor(color);
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSelected(boolean selected) {
|
||||
this.selected = selected;
|
||||
requestLayout();
|
||||
invalidate();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
|
||||
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
|
||||
if (widthMode == MeasureSpec.EXACTLY && heightMode != MeasureSpec.EXACTLY) {
|
||||
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
//noinspection SuspiciousNameCombination
|
||||
int height = width;
|
||||
if (heightMode == MeasureSpec.AT_MOST)
|
||||
height = Math.min(height, MeasureSpec.getSize(heightMeasureSpec));
|
||||
setMeasuredDimension(width, height);
|
||||
} else {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
final int outerRadius = getMeasuredWidth() / 2;
|
||||
if (selected) {
|
||||
final int whiteRadius = outerRadius - borderWidthLarge;
|
||||
final int innerRadius = whiteRadius - borderWidthSmall;
|
||||
canvas.drawCircle(getMeasuredWidth() / 2,
|
||||
getMeasuredHeight() / 2,
|
||||
outerRadius,
|
||||
outerPaint);
|
||||
canvas.drawCircle(getMeasuredWidth() / 2,
|
||||
getMeasuredHeight() / 2,
|
||||
whiteRadius,
|
||||
gapPaint);
|
||||
canvas.drawCircle(getMeasuredWidth() / 2,
|
||||
getMeasuredHeight() / 2,
|
||||
innerRadius,
|
||||
innerPaint);
|
||||
} else {
|
||||
final int innerRadius = outerRadius - borderWidthExtraSmall;
|
||||
canvas.drawCircle(getMeasuredWidth() / 2,
|
||||
getMeasuredHeight() / 2,
|
||||
outerRadius,
|
||||
outerPaint);
|
||||
canvas.drawCircle(getMeasuredWidth() / 2,
|
||||
getMeasuredHeight() / 2,
|
||||
innerRadius,
|
||||
innerPaint);
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue