diff --git a/android/app/src/main/java/app/organicmaps/routing/NavigationController.java b/android/app/src/main/java/app/organicmaps/routing/NavigationController.java index 22fe42c53..e3a6bea9a 100644 --- a/android/app/src/main/java/app/organicmaps/routing/NavigationController.java +++ b/android/app/src/main/java/app/organicmaps/routing/NavigationController.java @@ -26,6 +26,7 @@ import app.organicmaps.sdk.util.StringUtils; import app.organicmaps.util.UiUtils; import app.organicmaps.util.Utils; import app.organicmaps.util.WindowInsetUtils; +import app.organicmaps.widget.CurrentSpeedView; import app.organicmaps.widget.LanesView; import app.organicmaps.widget.SpeedLimitView; import app.organicmaps.widget.menu.NavMenu; @@ -51,6 +52,8 @@ public class NavigationController implements TrafficManager.TrafficCallback, Nav private final LanesView mLanesView; @NonNull private final SpeedLimitView mSpeedLimit; + @NonNull + private final CurrentSpeedView mCurrentSpeed; private final MapButtonsViewModel mMapButtonsViewModel; @@ -94,6 +97,7 @@ public class NavigationController implements TrafficManager.TrafficCallback, Nav mLanesView = topFrame.findViewById(R.id.lanes); mSpeedLimit = topFrame.findViewById(R.id.nav_speed_limit); + mCurrentSpeed = topFrame.findViewById(R.id.nav_current_speed); // Show a blank view below the navbar to hide the menu content final View navigationBarBackground = mFrame.findViewById(R.id.nav_bottom_sheet_nav_bar); @@ -128,7 +132,7 @@ public class NavigationController implements TrafficManager.TrafficCallback, Nav mLanesView.setLanes(info.lanes); - updateSpeedLimit(info); + updateSpeedWidgets(info); } private void updatePedestrian(@NonNull RoutingInfo info) @@ -136,6 +140,7 @@ public class NavigationController implements TrafficManager.TrafficCallback, Nav mNextTurnDistance.setText(Utils.formatDistance(mFrame.getContext(), info.distToTurn)); info.pedestrianTurnDirection.setTurnDrawable(mNextTurnImage); + updateSpeedWidgets(info); } public void updateNorth() @@ -261,16 +266,18 @@ public class NavigationController implements TrafficManager.TrafficCallback, Nav RoutingController.get().cancel(); } - private void updateSpeedLimit(@NonNull final RoutingInfo info) + private void updateSpeedWidgets(@NonNull final RoutingInfo info) { final Location location = MwmApplication.from(mFrame.getContext()).getLocationHelper().getSavedLocation(); if (location == null) { - mSpeedLimit.setSpeedLimit(0, false); + mSpeedLimit.setSpeedLimit(-1, false); + mCurrentSpeed.setCurrentSpeed(-1); return; } final int fSpeedLimit = StringUtils.nativeFormatSpeed(info.speedLimitMps); final boolean speedLimitExceeded = fSpeedLimit < StringUtils.nativeFormatSpeed(location.getSpeed()); mSpeedLimit.setSpeedLimit(fSpeedLimit, speedLimitExceeded); + mCurrentSpeed.setCurrentSpeed(location.getSpeed()); } } diff --git a/android/app/src/main/java/app/organicmaps/widget/BaseSignView.java b/android/app/src/main/java/app/organicmaps/widget/BaseSignView.java new file mode 100644 index 000000000..de87682fd --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/widget/BaseSignView.java @@ -0,0 +1,170 @@ +package app.organicmaps.widget; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.util.AttributeSet; +import android.view.MotionEvent; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +public abstract class BaseSignView extends View +{ + private float mBorderWidthRatio = 0.1f; + protected void setBorderWidthRatio(float ratio) { + mBorderWidthRatio = ratio; + } + + private float mBorderInsetRatio = 0f; + protected void setBorderInsetRatio(float ratio) { + mBorderInsetRatio = ratio; + } + + // colors + protected int mBackgroundColor; + protected int mBorderColor; + protected int mAlertColor; + protected int mTextColor; + protected int mTextAlertColor; + + // paints + protected final Paint mBackgroundPaint; + protected final Paint mBorderPaint; + protected final Paint mTextPaint; + + // geometry + protected float mWidth; + protected float mHeight; + protected float mRadius; + protected float mBorderWidth; + protected float mBorderRadius; + + public BaseSignView(Context ctx, @Nullable AttributeSet attrs) + { + super(ctx, attrs); + mBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mBorderPaint.setStyle(Paint.Style.STROKE); + mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mTextPaint.setTextAlign(Paint.Align.CENTER); + mTextPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD)); + } + + protected void setColors(int backgroundColor, + int borderColor, + int alertColor, + int textColor, + int textAlertColor) + { + mBackgroundColor = backgroundColor; + mBorderColor = borderColor; + mAlertColor = alertColor; + mTextColor = textColor; + mTextAlertColor = textAlertColor; + + mBackgroundPaint.setColor(mBackgroundColor); + mBorderPaint.setColor(mBorderColor); + mTextPaint.setColor(mTextColor); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + float px = getPaddingLeft() + getPaddingRight(); + float py = getPaddingTop() + getPaddingBottom(); + mWidth = w - px; + mHeight = h - py; + mRadius = Math.min(mWidth, mHeight) / 2f; + mBorderWidth = mRadius * mBorderWidthRatio; + // subtract half the stroke PLUS the extra inset + float gap = mRadius * mBorderInsetRatio; + mBorderRadius = mRadius - (mBorderWidth / 2f) - gap; + configureTextSize(); + } + + @Override + protected void onDraw(@NonNull Canvas canvas) + { + super.onDraw(canvas); + String str = getValueString(); + if (str == null) return; + + float cx = mWidth / 2f; + float cy = mHeight / 2f; + + // background & border + boolean alert = isAlert(); + mBackgroundPaint.setColor(alert ? mAlertColor : mBackgroundColor); + canvas.drawCircle(cx, cy, mRadius, mBackgroundPaint); + if (!alert) + { + mBorderPaint.setStrokeWidth(mBorderWidth); + mBorderPaint.setColor(mBorderColor); + canvas.drawCircle(cx, cy, mBorderRadius, mBorderPaint); + } + + // text + mTextPaint.setColor(alert ? mTextAlertColor : mTextColor); + drawValueString(canvas, cx, cy, str); + } + + @Override + public boolean onTouchEvent(@NonNull MotionEvent e) + { + float cx = mWidth / 2f, cy = mHeight / 2f; + float dx = e.getX() - cx, dy = e.getY() - cy; + if (dx*dx + dy*dy <= mRadius*mRadius) + { + performClick(); + return true; + } + return false; + } + + @Override + public boolean performClick() + { + super.performClick(); + return false; + } + + private void drawValueString(Canvas c, float cx, float cy, String str) + { + Rect b = new Rect(); + mTextPaint.getTextBounds(str, 0, str.length(), b); + float y = cy - b.exactCenterY(); + c.drawText(str, cx, y, mTextPaint); + } + + void configureTextSize() + { + String text = getValueString(); + if (text == null) return; + float textRadius = mBorderRadius - mBorderWidth; + float maxSz = 2f * textRadius; + float maxSz2 = maxSz * maxSz; + float lo = 0f, hi = maxSz, sz = maxSz; + Rect b = new Rect(); + while (lo <= hi) + { + sz = (lo + hi) / 2f; + mTextPaint.setTextSize(sz); + mTextPaint.getTextBounds(text, 0, text.length(), b); + float area = b.width()*b.width() + b.height()*b.height(); + if (area <= maxSz2) lo = sz + 1f; + else hi = sz - 1f; + } + mTextPaint.setTextSize(Math.max(1f, sz)); + } + + /** child must return the string to draw, or null if nothing */ + @Nullable + protected abstract String getValueString(); + + /** child decides if this is in “alert” state */ + protected abstract boolean isAlert(); +} diff --git a/android/app/src/main/java/app/organicmaps/widget/CurrentSpeedView.java b/android/app/src/main/java/app/organicmaps/widget/CurrentSpeedView.java new file mode 100644 index 000000000..c414b371a --- /dev/null +++ b/android/app/src/main/java/app/organicmaps/widget/CurrentSpeedView.java @@ -0,0 +1,77 @@ +package app.organicmaps.widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.util.AttributeSet; +import android.util.Pair; + +import androidx.annotation.Nullable; + +import app.organicmaps.R; +import app.organicmaps.sdk.util.StringUtils; + +public class CurrentSpeedView extends BaseSignView +{ + private double mSpeedMps = -1.0; + private String mSpeedStr = "--"; + + public CurrentSpeedView(Context ctx, @Nullable AttributeSet attrs) + { + super(ctx, attrs); + + setBorderWidthRatio(0.1f); + setBorderInsetRatio(0.05f); + + try (TypedArray a = ctx.getTheme() + .obtainStyledAttributes(attrs, R.styleable.CurrentSpeedView /* reuse same attrs or define new */ , 0, 0)) + { + int bg = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBackgroundColor, DefaultValues.BACKGROUND_COLOR); + int bd = a.getColor(R.styleable.CurrentSpeedView_currentSpeedBorderColor, DefaultValues.BORDER_COLOR); + int tc = a.getColor(R.styleable.CurrentSpeedView_currentSpeedTextColor, DefaultValues.TEXT_COLOR); + setColors(bg, bd, 0, tc, 0); + + if (isInEditMode()) + { + mSpeedMps = a.getInt(R.styleable.CurrentSpeedView_currentSpeedEditModeCurrentSpeed, 50); + mSpeedStr = Integer.toString((int)mSpeedMps); + } + } + } + + public void setCurrentSpeed(double mps) + { + mSpeedMps = mps; + if (mps < 0) + { + mSpeedStr = "--"; + } + else + { + Pair su = StringUtils.nativeFormatSpeedAndUnits(mps); + mSpeedStr = su.first; + } + requestLayout(); + configureTextSize(); + invalidate(); + } + + @Nullable + @Override + protected String getValueString() + { + return mSpeedStr; + } + + @Override + protected boolean isAlert() + { + return false; + } + + private interface DefaultValues + { + int BACKGROUND_COLOR = 0xFFFFFFFF; + int BORDER_COLOR = 0xFF000000; + int TEXT_COLOR = 0xFF000000; + } +} diff --git a/android/app/src/main/java/app/organicmaps/widget/SpeedLimitView.java b/android/app/src/main/java/app/organicmaps/widget/SpeedLimitView.java index 12c4f4819..6d6a0aa14 100644 --- a/android/app/src/main/java/app/organicmaps/widget/SpeedLimitView.java +++ b/android/app/src/main/java/app/organicmaps/widget/SpeedLimitView.java @@ -3,225 +3,135 @@ package app.organicmaps.widget; import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; -import android.graphics.Color; import android.graphics.Paint; -import android.graphics.Rect; -import android.graphics.Typeface; import android.util.AttributeSet; -import android.view.MotionEvent; -import android.view.View; -import androidx.annotation.ColorInt; -import androidx.annotation.NonNull; + import androidx.annotation.Nullable; + import app.organicmaps.R; -public class SpeedLimitView extends View +public class SpeedLimitView extends BaseSignView { - private interface DefaultValues + private int mSpeedLimit = -1; + private boolean mAlert = false; + private String mSpeedStr = "-1"; + private final int unlimitedBorderColor; + private final int unlimitedStripeColor; + + public SpeedLimitView(Context ctx, @Nullable AttributeSet attrs) { - @ColorInt - int BACKGROUND_COLOR = Color.WHITE; - @ColorInt - int BORDER_COLOR = Color.RED; - @ColorInt - int ALERT_COLOR = Color.RED; - @ColorInt - int TEXT_COLOR = Color.BLACK; - @ColorInt - int TEXT_ALERT_COLOR = Color.WHITE; + super(ctx, attrs); - float BORDER_WIDTH_RATIO = 0.1f; - } + setBorderWidthRatio(0.2f); + setBorderInsetRatio(0.05f); - @ColorInt - private final int mBackgroundColor; - - @ColorInt - private final int mBorderColor; - - @ColorInt - private final int mAlertColor; - - @ColorInt - private final int mTextColor; - - @ColorInt - private final int mTextAlertColor; - - @NonNull - private final Paint mSignBackgroundPaint; - @NonNull - private final Paint mSignBorderPaint; - @NonNull - private final Paint mTextPaint; - - private float mWidth; - private float mHeight; - private float mBackgroundRadius; - private float mBorderRadius; - private float mBorderWidth; - - private int mSpeedLimit = 0; - @NonNull - private String mSpeedLimitStr = "0"; - private boolean mAlert = false; - - public SpeedLimitView(Context context, @Nullable AttributeSet attrs) - { - super(context, attrs); - - try (TypedArray data = context.getTheme().obtainStyledAttributes(attrs, R.styleable.SpeedLimitView, 0, 0)) + try (TypedArray a = ctx.getTheme() + .obtainStyledAttributes(attrs, R.styleable.SpeedLimitView, 0, 0)) { - mBackgroundColor = - data.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR); - mBorderColor = data.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_COLOR); - mAlertColor = data.getColor(R.styleable.SpeedLimitView_speedLimitAlertColor, DefaultValues.ALERT_COLOR); - mTextColor = data.getColor(R.styleable.SpeedLimitView_speedLimitTextColor, DefaultValues.TEXT_COLOR); - mTextAlertColor = - data.getColor(R.styleable.SpeedLimitView_speedLimitTextAlertColor, DefaultValues.TEXT_ALERT_COLOR); + int bg = a.getColor(R.styleable.SpeedLimitView_speedLimitBackgroundColor, DefaultValues.BACKGROUND_COLOR); + int bd = a.getColor(R.styleable.SpeedLimitView_speedLimitBorderColor, DefaultValues.BORDER_COLOR); + int al = a.getColor(R.styleable.SpeedLimitView_speedLimitAlertColor, DefaultValues.ALERT_COLOR); + int tc = a.getColor(R.styleable.SpeedLimitView_speedLimitTextColor, DefaultValues.TEXT_COLOR); + int tac = a.getColor(R.styleable.SpeedLimitView_speedLimitTextAlertColor, DefaultValues.TEXT_ALERT_COLOR); + setColors(bg, bd, al, tc, tac); + + unlimitedBorderColor = a.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedBorderColor, DefaultValues.UNLIMITED_BORDER_COLOR); + unlimitedStripeColor = a.getColor(R.styleable.SpeedLimitView_speedLimitUnlimitedStripeColor, DefaultValues.UNLIMITED_STRIPE_COLOR); + if (isInEditMode()) { - mSpeedLimit = data.getInt(R.styleable.SpeedLimitView_speedLimitEditModeSpeedLimit, 60); - mSpeedLimitStr = Integer.toString(mSpeedLimit); - mAlert = data.getBoolean(R.styleable.SpeedLimitView_speedLimitEditModeAlert, false); + mSpeedLimit = a.getInt(R.styleable.SpeedLimitView_speedLimitEditModeSpeedLimit, 60); + mAlert = a.getBoolean(R.styleable.SpeedLimitView_speedLimitEditModeAlert, false); + mSpeedStr = Integer.toString(mSpeedLimit); } } - - mSignBackgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mSignBackgroundPaint.setColor(mBackgroundColor); - - mSignBorderPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mSignBorderPaint.setColor(mBorderColor); - mSignBorderPaint.setStrokeWidth(mBorderWidth); - mSignBorderPaint.setStyle(Paint.Style.STROKE); - - mTextPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mTextPaint.setColor(mTextColor); - mTextPaint.setTextAlign(Paint.Align.CENTER); - mTextPaint.setTypeface(Typeface.create(Typeface.DEFAULT, Typeface.BOLD)); } - public void setSpeedLimit(final int speedLimit, boolean alert) + public void setSpeedLimit(int limit, boolean alert) { - final boolean speedLimitChanged = mSpeedLimit != speedLimit; - - mSpeedLimit = speedLimit; - mAlert = alert; - - if (speedLimitChanged) + if (mSpeedLimit != limit) { - mSpeedLimitStr = Integer.toString(mSpeedLimit); - configureTextSize(); + mSpeedLimit = limit; + mSpeedStr = Integer.toString(limit); + requestLayout(); } - + mAlert = alert; + configureTextSize(); invalidate(); } + @Nullable @Override - protected void onDraw(@NonNull Canvas canvas) + protected String getValueString() { - super.onDraw(canvas); - - final boolean validSpeedLimit = mSpeedLimit > 0; - if (!validSpeedLimit) - return; - - final float cx = mWidth / 2; - final float cy = mHeight / 2; - - drawSign(canvas, cx, cy, mAlert); - drawText(canvas, cx, cy, mAlert); + return (mSpeedLimit > 0 ? mSpeedStr : null); } - private void drawSign(@NonNull Canvas canvas, float cx, float cy, boolean alert) + @Override + protected boolean isAlert() { - if (alert) - mSignBackgroundPaint.setColor(mAlertColor); + return mAlert; + } + + @Override + protected void onDraw(Canvas canvas) + { + float cx = mWidth/2f, cy = mHeight/2f; + + if (mSpeedLimit == 0) + { + // background + mBackgroundPaint.setColor(mBackgroundColor); + canvas.drawCircle(cx, cy, mRadius, mBackgroundPaint); + + // black border + mBorderPaint.setColor(unlimitedBorderColor); + mBorderPaint.setStrokeWidth(mBorderWidth); + canvas.drawCircle(cx, cy, mBorderRadius, mBorderPaint); + + // draw 5 diagonal stripes + drawUnlimitedStripes(canvas, cx, cy); + } else - mSignBackgroundPaint.setColor(mBackgroundColor); - - canvas.drawCircle(cx, cy, mBackgroundRadius, mSignBackgroundPaint); - if (!alert) { - mSignBorderPaint.setStrokeWidth(mBorderWidth); - canvas.drawCircle(cx, cy, mBorderRadius, mSignBorderPaint); + // delegate to BaseSignView’s onDraw + super.onDraw(canvas); } } - private void drawText(@NonNull Canvas canvas, float cx, float cy, boolean alert) + private void drawUnlimitedStripes(Canvas c, float cx, float cy) { - if (alert) - mTextPaint.setColor(mTextAlertColor); - else - mTextPaint.setColor(mTextColor); + Paint stripe = new Paint(Paint.ANTI_ALIAS_FLAG); + stripe.setColor(unlimitedStripeColor); + stripe.setStrokeWidth(mBorderWidth * 0.4f); - final Rect textBounds = new Rect(); - mTextPaint.getTextBounds(mSpeedLimitStr, 0, mSpeedLimitStr.length(), textBounds); - final float textY = cy - textBounds.exactCenterY(); - canvas.drawText(mSpeedLimitStr, cx, textY, mTextPaint); - } + float r = mRadius * 0.8f; // shorten to 80% of full radius + float diag = (float)(1/Math.sqrt(2)); + float dx = -diag, dy = +diag; + float px = -dy, py = +dx; // perpendicular + float step = r * 0.15f; // spacing - @Override - public boolean onTouchEvent(@NonNull MotionEvent event) - { - final float cx = mWidth / 2; - final float cy = mHeight / 2; - if (Math.pow(event.getX() - cx, 2) + Math.pow(event.getY() - cy, 2) <= Math.pow(mBackgroundRadius, 2)) + for (int i = -2; i <= 2; i++) { - performClick(); - return true; + float ox = px * step * i; + float oy = py * step * i; + float sx = cx + dx * r + ox; + float sy = cy + dy * r + oy; + float ex = cx - dx * r + ox; + float ey = cy - dy * r + oy; + c.drawLine(sx, sy, ex, ey, stripe); } - return false; } - @Override - public boolean performClick() + + private interface DefaultValues { - super.performClick(); - return false; - } - - @Override - protected void onSizeChanged(int w, int h, int oldw, int oldh) - { - super.onSizeChanged(w, h, oldw, oldh); - - final float paddingX = (float) (getPaddingLeft() + getPaddingRight()); - final float paddingY = (float) (getPaddingTop() + getPaddingBottom()); - - mWidth = (float) w - paddingX; - mHeight = (float) h - paddingY; - mBackgroundRadius = Math.min(mWidth, mHeight) / 2; - mBorderWidth = mBackgroundRadius * 2 * DefaultValues.BORDER_WIDTH_RATIO; - mBorderRadius = mBackgroundRadius - mBorderWidth / 2; - configureTextSize(); - } - - // Apply binary search to determine the optimal text size that fits within the circular boundary. - private void configureTextSize() - { - final String text = mSpeedLimitStr; - final float textRadius = mBorderRadius - mBorderWidth; - final float textMaxSize = 2 * textRadius; - final float textMaxSizeSquared = (float) Math.pow(textMaxSize, 2); - - float lowerBound = 0; - float upperBound = textMaxSize; - float textSize = textMaxSize; - final Rect textBounds = new Rect(); - - while (lowerBound <= upperBound) - { - textSize = (lowerBound + upperBound) / 2; - mTextPaint.setTextSize(textSize); - mTextPaint.getTextBounds(text, 0, text.length(), textBounds); - - if (Math.pow(textBounds.width(), 2) + Math.pow(textBounds.height(), 2) <= textMaxSizeSquared) - lowerBound = textSize + 1; - else - upperBound = textSize - 1; - } - - mTextPaint.setTextSize(Math.max(1, textSize)); + int BACKGROUND_COLOR = 0xFFFFFFFF; + int BORDER_COLOR = 0xFFFF0000; + int ALERT_COLOR = 0xFFFF0000; + int TEXT_COLOR = 0xFF000000; + int TEXT_ALERT_COLOR = 0xFFFFFFFF; + int UNLIMITED_BORDER_COLOR = 0xFF000000; + int UNLIMITED_STRIPE_COLOR = 0xFF000000; } } diff --git a/android/app/src/main/res/layout-land/layout_nav_top.xml b/android/app/src/main/res/layout-land/layout_nav_top.xml index 4636a4159..8ee90433e 100644 --- a/android/app/src/main/res/layout-land/layout_nav_top.xml +++ b/android/app/src/main/res/layout-land/layout_nav_top.xml @@ -123,12 +123,24 @@ app:lanesEditModeLanesCount="10" tools:visibility="visible" /> + + + app:layout_constraintTop_toBottomOf="@id/nav_current_speed" + android:translationY="-21dp" + android:translationX="-12dp" + android:translationZ="1dp"/> diff --git a/android/app/src/main/res/layout/layout_nav_top.xml b/android/app/src/main/res/layout/layout_nav_top.xml index c75d9a8f6..e71475c1e 100644 --- a/android/app/src/main/res/layout/layout_nav_top.xml +++ b/android/app/src/main/res/layout/layout_nav_top.xml @@ -124,13 +124,26 @@ app:lanesEditModeLanesCount="5" tools:visibility="visible" /> + + + app:layout_constraintTop_toBottomOf="@id/nav_current_speed" + android:translationY="-23dp" + android:translationX="-23dp" + android:translationZ="1dp"/> diff --git a/android/app/src/main/res/values/attrs.xml b/android/app/src/main/res/values/attrs.xml index b69c40559..4db620a25 100644 --- a/android/app/src/main/res/values/attrs.xml +++ b/android/app/src/main/res/values/attrs.xml @@ -3,6 +3,8 @@ + + @@ -11,6 +13,14 @@ + + + + + + + + diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 042316a80..9740cc67e 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -10,6 +10,10 @@ @color/base_red + +