Skip to content

Instantly share code, notes, and snippets.

View RotaryKnobView.kt
override fun onTouchEvent(event: MotionEvent): Boolean {
return if (gestureDetector.onTouchEvent(event))
true
else
super.onTouchEvent(event)
}
override fun onDown(event: MotionEvent): Boolean {
return true
}
View MainActivity.kt
package geva.oren.rotaryknobdemo
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import kotlinx.android.synthetic.main.activity_main.*
class MainActivity : AppCompatActivity(), RotaryKnobView.RotaryKnobListener {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
View activity_main.xml
<geva.oren.rotaryknobdemo.RotaryKnobView
android:id="@+id/knob"
class="geva.oren.rotaryknobdemo.RotaryKnobView"
android:layout_width="@dimen/knob_width"
android:layout_height="@dimen/knob_height"
android:layout_marginBottom="312dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView"
@o4oren
o4oren / RotaryKnobView.kt
Last active May 2, 2020
Rotary knob constructor
View RotaryKnobView.kt
class RotaryKnobView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : RelativeLayout(context, attrs, defStyleAttr), GestureDetector.OnGestureListener {
private val gestureDetector: GestureDetectorCompat
private var maxValue = 99
private var minValue = 0
var listener: RotaryKnobListener? = null
var value = 50
private var knobDrawable: Drawable? = null
private var divider = 300f / (maxValue - minValue)
View RotaryKnobView.kt
private fun setKnobPosition(angle: Float) {
val matrix = Matrix()
knobImageView.scaleType = ScaleType.MATRIX
matrix.postRotate(angle, width.toFloat() / 2, height.toFloat() / 2)
knobImageView.imageMatrix = matrix
}
View RotaryKnobView.kt
private fun calculateAngle(x: Float, y: Float): Float {
val px = (x / width.toFloat()) - 0.5
val py = ( 1 - y / height.toFloat()) - 0.5
var angle = -(Math.toDegrees(atan2(py, px)))
.toFloat() + 90
if (angle > 180) angle -= 360
return angle
}
View RotaryKnobView.kt
interface RotaryKnobListener {
fun onRotate(value: Int)
}
@o4oren
o4oren / RotaryKnobView.kt
Created May 2, 2020
RotartyKnob initialization
View RotaryKnobView.kt
init {
this.maxValue = maxValue + 1
LayoutInflater.from(context)
.inflate(R.layout.rotary_knob_view, this, true)
context.theme.obtainStyledAttributes(
attrs,
R.styleable.RotaryKnobView,
0,
View RotaryKnobView.kt
override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float)
: Boolean {
val rotationDegrees = calculateAngle(e2.x, e2.y)
// use only -150 to 150 range (knob min/max points
if (rotationDegrees >= -150 && rotationDegrees <= 150) {
setKnobPosition(rotationDegrees)
// Calculate rotary value
// The range is the 300 degrees between -150 and 150, so we'll add 150 to adjust the
View RotaryKnobView.kt
override fun onScroll(e1: MotionEvent, e2: MotionEvent, distanceX: Float, distanceY: Float)
: Boolean {
return true
}
override fun onTouchEvent(event: MotionEvent): Boolean {
return if (gestureDetector.onTouchEvent(event))
true
else
super.onTouchEvent(event)
You can’t perform that action at this time.