Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
01dc498
Adds Kotlin to project
jonathan-livly May 10, 2022
73c2206
Updates AndroidManifest.xml with required exported attribute
jonathan-livly May 10, 2022
e64c58c
Converts MainActivity to Kotlin using stale branch's changes
jonathan-livly May 10, 2022
198e919
Converts CircularSeekBar to Kotlin as CircularSeekBarV2.kt
jonathan-livly May 11, 2022
d931014
Deletes old CircularSeekBar.java
jonathan-livly May 11, 2022
d6f7673
Removes Hungarian notation. Should now be backwards compatible with o…
jonathan-livly May 11, 2022
2ebc504
Adds the ability to have an inner fill color on the pointer and speci…
jonathan-livly May 11, 2022
901972d
Merge branch 'master' of https://github.com/tankery/CircularSeekBar i…
jonathan-livly May 18, 2022
1da0714
Removes fill from square pointer example
jonathan-livly May 18, 2022
097d674
Reverts changes to to api names
jonathan-livly May 23, 2022
07060b7
Ensures `pointerFillInnerStrokeWidth` is never negative
jonathan-livly May 23, 2022
0d7c056
Adds name space to README.md
jonathan-livly Jun 1, 2022
ff29588
Reverts name change for DEFAULT_POINTER_STROKE_WIDTH
jonathan-livly Jun 1, 2022
725f951
Renames pointer fill properties to the much clearer name pointer overlay
jonathan-livly Jun 1, 2022
c0634f7
Fixes bug related to using `Paint.Style.FILL_AND_STROKE` instead of `…
jonathan-livly Jun 1, 2022
402a987
Removes * from imports
jonathan-livly Jun 1, 2022
ef92ce3
Adjust imports order
jonathan-livly Jun 20, 2022
7c3e0cc
Saves instance state of pointerOverlayBorderWidth
jonathan-livly Jun 20, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ app:cs_start_angle = "float"
app:cs_end_angle = "float"
app:cs_disable_progress_glow = "boolean"
app:cs_hide_progress_when_empty = "boolean"
app:cs_pointer_overlay_color = "color"
app:cs_pointer_overlay_border_width = "dimension"
```

## Appreciation
Expand Down
4 changes: 3 additions & 1 deletion app/src/main/res/layout/activity_main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,13 @@
android:layout_marginTop="@dimen/seekbar_margin"
android:layout_marginLeft="@dimen/seekbar_margin"
android:layout_marginRight="@dimen/seekbar_margin"
app:cs_pointer_overlay_color="@android:color/white"
app:cs_pointer_overlay_border_width="10dp"
app:cs_negative_enabled="true"
app:cs_circle_style="round"
app:cs_circle_stroke_width="8dp"
app:cs_pointer_stroke_width="24dp"
app:cs_pointer_halo_width="@dimen/seekbar_holo_width"/>
app:cs_pointer_halo_width="@dimen/seekbar_holo_width" />

<TextView
android:layout_width="wrap_content"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,14 @@ package me.tankery.lib.circularseekbar

import android.content.Context
import android.content.res.TypedArray
import android.graphics.BlurMaskFilter
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.Path
import android.graphics.Paint.Cap
Comment thread
jonathan-livly marked this conversation as resolved.
import android.graphics.RectF
import android.graphics.Color
import android.graphics.BlurMaskFilter
import android.graphics.Path
import android.graphics.PathMeasure
import android.graphics.Canvas
import android.graphics.RectF
import android.os.Build
import android.os.Bundle
import android.os.Parcelable
Expand Down Expand Up @@ -85,11 +85,17 @@ class CircularSeekBar @JvmOverloads constructor(
private val circleProgressGlowPaint: Paint = Paint()

/**
* `Paint` instance used to draw the center of the pointer.
* `Paint` instance used to draw the pointer.
* Note: This is broken on 4.0+, as BlurMasks do not work with hardware acceleration.
*/
private val pointerPaint: Paint = Paint()

/**
* `Paint` instance used to draw an overlay over [pointerPaint].
* Will effectively use [pointerPaint] as stroke.
*/
private val pointerOverlayPaint: Paint = Paint()

/**
* `Paint` instance used to draw the halo of the pointer.
* Note: The halo is the part that changes transparency.
Expand Down Expand Up @@ -148,7 +154,7 @@ class CircularSeekBar @JvmOverloads constructor(
/**
* The radius of the pointer (in pixels).
*
* Sets the pointer pointer stroke width.
* Sets the pointer stroke width.
* @param width the width of the pointer
*/
var pointerStrokeWidth = 0f
Expand All @@ -159,6 +165,24 @@ class CircularSeekBar @JvmOverloads constructor(
invalidate()
}

/**
* The border width between the pointer and [pointerOverlayPaint]
* Can not be less than zero, if the border is larger than [pointerStrokeWidth] this will not display
*
* @param width the width of the pointer stroke. Must be a positive number
*/
var pointerOverlayBorderWidth = DEFAULT_POINTER_OVERLAY_BORDER_WIDTH
set(width) {
field = if (width < 0) {
0f
} else {
width
}
initPaints()
recalculateAll()
invalidate()
}

/**
* The width of the pointer halo (in pixels).
*/
Expand Down Expand Up @@ -245,6 +269,13 @@ class CircularSeekBar @JvmOverloads constructor(
invalidate()
}

var pointerOverlayColor = DEFAULT_POINTER_OVERLAY_COLOR
set(color) {
field = color
pointerOverlayPaint.color = color
invalidate()
}

/**
* Holds the color value for `mPointerHaloPaint` before the `Paint` instance is created.
*
Expand Down Expand Up @@ -545,6 +576,7 @@ class CircularSeekBar @JvmOverloads constructor(
R.styleable.cs_CircularSeekBar_cs_circle_y_radius,
DEFAULT_CIRCLE_Y_RADIUS
)

pointerStrokeWidth = attrArray.getDimension(
R.styleable.cs_CircularSeekBar_cs_pointer_stroke_width,
DEFAULT_POINTER_STROKE_WIDTH
Expand All @@ -568,6 +600,16 @@ class CircularSeekBar @JvmOverloads constructor(
R.styleable.cs_CircularSeekBar_cs_pointer_color,
DEFAULT_POINTER_COLOR
)
pointerOverlayColor = attrArray.getColor(
R.styleable.cs_CircularSeekBar_cs_pointer_overlay_color,
DEFAULT_POINTER_OVERLAY_COLOR
)

pointerOverlayBorderWidth = attrArray.getDimension(
R.styleable.cs_CircularSeekBar_cs_pointer_overlay_border_width,
DEFAULT_POINTER_OVERLAY_BORDER_WIDTH
)

pointerHaloColor = attrArray.getColor(
R.styleable.cs_CircularSeekBar_cs_pointer_halo_color,
DEFAULT_POINTER_HALO_COLOR
Expand Down Expand Up @@ -660,6 +702,7 @@ class CircularSeekBar @JvmOverloads constructor(
}
if (disablePointer) {
pointerStrokeWidth = 0f
pointerOverlayBorderWidth = 0f
pointerHaloWidth = 0f
pointerHaloBorderWidth = 0f
}
Expand Down Expand Up @@ -705,6 +748,12 @@ class CircularSeekBar @JvmOverloads constructor(
pointerPaint.strokeJoin = Paint.Join.ROUND
pointerPaint.strokeCap = circleStyle

pointerOverlayPaint.set(pointerPaint)
pointerOverlayPaint.color = pointerOverlayColor
pointerOverlayPaint.style = Paint.Style.STROKE
pointerOverlayPaint.strokeWidth =
(pointerStrokeWidth - pointerOverlayBorderWidth).coerceAtLeast(0f)

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we use the concept of "overlay", than the border width of this overlay looks more like it's own width (circle diameter).

So at here we may directly set the pointerOverlayPaint.strokeWidth = pointerOverlayBorderWidth


pointerHaloPaint.set(pointerPaint)
pointerHaloPaint.color = pointerHaloColor
pointerHaloPaint.alpha = pointerAlpha
Expand Down Expand Up @@ -825,6 +874,7 @@ class CircularSeekBar @JvmOverloads constructor(
canvas.drawPath(circlePointerPath, pointerHaloPaint)
}
canvas.drawPath(circlePointerPath, pointerPaint)
canvas.drawPath(circlePointerPath, pointerOverlayPaint)
// TODO, find a good way to draw halo border.
// if (mUserIsMovingPointer) {
// canvas.drawCircle(mPointerPositionXY[0], mPointerPositionXY[1],
Expand Down Expand Up @@ -1104,6 +1154,8 @@ class CircularSeekBar @JvmOverloads constructor(
state.putInt("circleColor", circleColor)
state.putInt("circleProgressColor", circleProgressColor)
state.putInt("pointerColor", pointerColor)
state.putInt("pointerOverlayColor", pointerOverlayColor)
state.putFloat("pointerOverlayBorderWidth", pointerOverlayBorderWidth)
state.putInt("pointerHaloColor", pointerHaloColor)
state.putInt("pointerHaloColorOnTouch", pointerHaloColorOnTouch)
state.putInt("pointerAlpha", pointerAlpha)
Expand All @@ -1128,6 +1180,8 @@ class CircularSeekBar @JvmOverloads constructor(
circleColor = savedState.getInt("circleColor")
circleProgressColor = savedState.getInt("circleProgressColor")
pointerColor = savedState.getInt("pointerColor")
pointerOverlayColor = savedState.getInt("pointerOverlayColor")
Comment thread
jonathan-livly marked this conversation as resolved.
pointerOverlayBorderWidth = savedState.getFloat("pointerOverlayBorderWidth")
pointerHaloColor = savedState.getInt("pointerHaloColor")
pointerHaloColorOnTouch = savedState.getInt("pointerHaloColorOnTouch")
pointerAlpha = savedState.getInt("pointerAlpha")
Expand Down Expand Up @@ -1194,6 +1248,8 @@ class CircularSeekBar @JvmOverloads constructor(
private const val DEFAULT_CIRCLE_COLOR = Color.DKGRAY
private val DEFAULT_CIRCLE_PROGRESS_COLOR = Color.argb(235, 74, 138, 255)
private val DEFAULT_POINTER_COLOR = Color.argb(235, 74, 138, 255)
private const val DEFAULT_POINTER_OVERLAY_COLOR = Color.TRANSPARENT
private val DEFAULT_POINTER_OVERLAY_BORDER_WIDTH = 0f
private val DEFAULT_POINTER_HALO_COLOR = Color.argb(135, 74, 138, 255)
private val DEFAULT_POINTER_HALO_COLOR_ONTOUCH = Color.argb(135, 74, 138, 255)
private const val DEFAULT_CIRCLE_FILL_COLOR = Color.TRANSPARENT
Expand Down
30 changes: 16 additions & 14 deletions circularSeekBar/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,21 +17,23 @@
<attr name="cs_circle_x_radius" format="dimension" />
<attr name="cs_circle_y_radius" format="dimension" />
<attr name="cs_circle_stroke_width" format="dimension" />
<attr name="cs_disable_pointer" format="boolean"/>
<attr name="cs_disable_pointer" format="boolean" />
<attr name="cs_pointer_stroke_width" format="dimension" />
<attr name="cs_pointer_halo_width" format="dimension" />
<attr name="cs_pointer_halo_border_width" format="dimension"/>
<attr name="cs_circle_fill" format="color"/>
<attr name="cs_circle_color" format="color"/>
<attr name="cs_circle_progress_color" format="color"/>
<attr name="cs_pointer_color" format="color"/>
<attr name="cs_pointer_halo_color" format="color"/>
<attr name="cs_pointer_halo_color_ontouch" format="color"/>
<attr name="cs_pointer_alpha_ontouch" format="integer"/>
<attr name="cs_pointer_angle" format="float"/>
<attr name="cs_start_angle" format="float"/>
<attr name="cs_end_angle" format="float"/>
<attr name="cs_disable_progress_glow" format="boolean"/>
<attr name="cs_hide_progress_when_empty" format="boolean"/>
<attr name="cs_pointer_halo_border_width" format="dimension" />
<attr name="cs_circle_fill" format="color" />
<attr name="cs_circle_color" format="color" />
<attr name="cs_circle_progress_color" format="color" />
<attr name="cs_pointer_color" format="color" />
<attr name="cs_pointer_overlay_color" format="color" />
<attr name="cs_pointer_overlay_border_width" format="dimension" />
<attr name="cs_pointer_halo_color" format="color" />
<attr name="cs_pointer_halo_color_ontouch" format="color" />
<attr name="cs_pointer_alpha_ontouch" format="integer" />
<attr name="cs_pointer_angle" format="float" />
<attr name="cs_start_angle" format="float" />
<attr name="cs_end_angle" format="float" />
<attr name="cs_disable_progress_glow" format="boolean" />
<attr name="cs_hide_progress_when_empty" format="boolean" />
</declare-styleable>
</resources>