Created
April 17, 2024 13:48
-
-
Save YohannesTz/e30e03c7890d1e46dc1aee9a646e47c3 to your computer and use it in GitHub Desktop.
Doing this cause I am fucking tired of gradle conflicts... original source belongs to https://github.com/singhangadin/android-toggle/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<resources> | |
<declare-styleable | |
name="Toggle"> | |
<attr | |
name="textOn" | |
format="string"/> | |
<attr | |
name="textOff" | |
format="string"/> | |
<attr | |
name="colorOff" | |
format="color"/> | |
<attr | |
name="colorOn" | |
format="color"/> | |
<attr | |
name="colorBorder" | |
format="color"/> | |
<attr | |
name="colorDisabled" | |
format="color"/> | |
<attr name="on" | |
format="boolean"/> | |
<attr name="android:textSize"/> | |
<attr name="android:enabled"/> | |
</declare-styleable> | |
</resources> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<resources> | |
<color name="colorAccent">#FF4081</color> | |
</resources> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<resources> | |
<dimen name="labeled_default_width">72dp</dimen> | |
<dimen name="labeled_default_height">32dp</dimen> | |
<dimen name="day_night_default_width">84dp</dimen> | |
<dimen name="day_night_default_height">48dp</dimen> | |
</resources> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2024. YohannesTz, Africa Technologies PLC | |
*/ | |
import android.animation.ValueAnimator | |
import android.content.Context | |
import android.graphics.Canvas | |
import android.graphics.Color | |
import android.graphics.Paint | |
import android.graphics.RectF | |
import android.graphics.Typeface | |
import android.os.Build | |
import android.util.AttributeSet | |
import android.view.MotionEvent | |
import android.view.animation.AccelerateDecelerateInterpolator | |
import com.africatech.godriver.R | |
import kotlin.math.min | |
class LabeledSwitch : ToggleableView { | |
private var padding = 0 | |
private var colorOn = 0 | |
private var colorOff = 0 | |
private var colorBorder = 0 | |
private var colorDisabled = 0 | |
private var textSize = 0 | |
private var outerRadii = 0 | |
private var thumbRadii = 0 | |
private var paint: Paint? = null | |
private var startTime: Long = 0 | |
private var labelOn: String? = null | |
private var labelOff: String? = null | |
private var thumbBounds: RectF? = null | |
private var leftBgArc: RectF? = null | |
private var rightBgArc: RectF? = null | |
private var leftFgArc: RectF? = null | |
private var rightFgArc: RectF? = null | |
/** | |
* | |
* Returns the typeface for Switch on/off labels. | |
* | |
* @return the typeface for Switch on/off labels.. | |
*/ | |
var typeface: Typeface? = null | |
set(typeface) { | |
field = typeface | |
paint!!.setTypeface(typeface) | |
invalidate() | |
} | |
private var thumbOnCenterX = 0f | |
private var thumbOffCenterX = 0f | |
/** | |
* Simple constructor to use when creating a switch from code. | |
* @param context The Context the switch is running in, through which it can | |
* access the current theme, resources, etc. | |
*/ | |
constructor(context: Context?) : super(context) { | |
initView() | |
} | |
/** | |
* Constructor that is called when inflating a switch from XML. | |
* | |
* @param context The Context the switch is running in, through which it can | |
* access the current theme, resources, etc. | |
* @param attrs The attributes of the XML tag that is inflating the switch. | |
*/ | |
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) { | |
initView() | |
initProperties(attrs) | |
} | |
/** | |
* Perform inflation from XML and apply a class-specific base style from a | |
* theme attribute. | |
* | |
* @param context The Context the switch is running in, through which it can | |
* access the current theme, resources, etc. | |
* @param attrs The attributes of the XML tag that is inflating the switch. | |
* @param defStyleAttr An attribute in the current theme that contains a | |
* reference to a style resource that supplies default values for | |
* the switch. Can be 0 to not look for defaults. | |
*/ | |
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super( | |
context, | |
attrs, | |
defStyleAttr | |
) { | |
initView() | |
initProperties(attrs) | |
} | |
private fun initView() { | |
isOn = false | |
labelOn = "ON" | |
labelOff = "OFF" | |
enabled = true | |
textSize = (12f * resources.displayMetrics.scaledDensity).toInt() | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |
colorOn = resources.getColor(R.color.colorAccent, context.theme) | |
colorBorder = colorOn | |
} else { | |
colorOn = resources.getColor(R.color.colorAccent) | |
colorBorder = colorOn | |
} | |
paint = Paint() | |
paint!!.isAntiAlias = true | |
leftBgArc = RectF() | |
rightBgArc = RectF() | |
leftFgArc = RectF() | |
rightFgArc = RectF() | |
thumbBounds = RectF() | |
colorOff = Color.parseColor("#FFFFFF") | |
colorDisabled = Color.parseColor("#D3D3D3") | |
} | |
private fun initProperties(attrs: AttributeSet?) { | |
val typedArray = context.theme.obtainStyledAttributes(attrs, R.styleable.Toggle, 0, 0) | |
val indexCount = typedArray.getIndexCount() | |
for (i in 0 until indexCount) { | |
val attr = typedArray.getIndex(i) | |
when (attr) { | |
R.styleable.Toggle_on -> { | |
isOn = typedArray.getBoolean(R.styleable.Toggle_on, false) | |
} | |
R.styleable.Toggle_colorOff -> { | |
colorOff = typedArray.getColor(R.styleable.Toggle_colorOff, Color.parseColor("#FFFFFF")) | |
} | |
R.styleable.Toggle_colorBorder -> { | |
val accentColor: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |
resources.getColor(R.color.colorAccent, context.theme) | |
} else { | |
resources.getColor(R.color.colorAccent) | |
} | |
colorBorder = typedArray.getColor(R.styleable.Toggle_colorBorder, accentColor) | |
} | |
R.styleable.Toggle_colorOn -> { | |
val accentColor: Int = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { | |
resources.getColor(R.color.colorAccent, context.theme) | |
} else { | |
resources.getColor(R.color.colorAccent) | |
} | |
colorOn = typedArray.getColor(R.styleable.Toggle_colorOn, accentColor) | |
} | |
R.styleable.Toggle_colorDisabled -> { | |
colorDisabled = | |
typedArray.getColor(R.styleable.Toggle_colorOff, Color.parseColor("#D3D3D3")) | |
} | |
R.styleable.Toggle_textOff -> { | |
labelOff = typedArray.getString(R.styleable.Toggle_textOff) | |
} | |
R.styleable.Toggle_textOn -> { | |
labelOn = typedArray.getString(R.styleable.Toggle_textOn) | |
} | |
R.styleable.Toggle_android_textSize -> { | |
val defaultTextSize = (12f * resources.displayMetrics.scaledDensity).toInt() | |
textSize = | |
typedArray.getDimensionPixelSize(R.styleable.Toggle_android_textSize, defaultTextSize) | |
} | |
R.styleable.Toggle_android_enabled -> { | |
enabled = typedArray.getBoolean(R.styleable.Toggle_android_enabled, false) | |
} | |
} | |
} | |
} | |
override fun onDraw(canvas: Canvas) { | |
super.onDraw(canvas) | |
paint!!.textSize = textSize.toFloat() | |
// Drawing Switch background here | |
run { | |
if (isEnabled) { | |
paint!!.setColor(colorBorder) | |
} else { | |
paint!!.setColor(colorDisabled) | |
} | |
canvas.drawArc(leftBgArc!!, 90f, 180f, false, paint!!) | |
canvas.drawArc(rightBgArc!!, 90f, -180f, false, paint!!) | |
canvas.drawRect( | |
outerRadii.toFloat(), 0f, (width - outerRadii).toFloat(), height.toFloat(), | |
paint!! | |
) | |
paint!!.setColor(colorOff) | |
canvas.drawArc(leftFgArc!!, 90f, 180f, false, paint!!) | |
canvas.drawArc(rightFgArc!!, 90f, -180f, false, paint!!) | |
canvas.drawRect( | |
outerRadii.toFloat(), | |
(padding / 10).toFloat(), | |
(width - outerRadii).toFloat(), | |
(height - padding / 10).toFloat(), | |
paint!! | |
) | |
var alpha = | |
((thumbBounds!!.centerX() - thumbOffCenterX) / (thumbOnCenterX - thumbOffCenterX) * 255).toInt() | |
alpha = if (alpha < 0) 0 else if (alpha > 255) 255 else alpha | |
val onColor: Int = if (isEnabled) { | |
Color.argb( | |
alpha, | |
Color.red(colorOn), | |
Color.green(colorOn), | |
Color.blue(colorOn) | |
) | |
} else { | |
Color.argb( | |
alpha, | |
Color.red(colorDisabled), | |
Color.green(colorDisabled), | |
Color.blue(colorDisabled) | |
) | |
} | |
paint!!.setColor(onColor) | |
canvas.drawArc(leftBgArc!!, 90f, 180f, false, paint!!) | |
canvas.drawArc(rightBgArc!!, 90f, -180f, false, paint!!) | |
canvas.drawRect( | |
outerRadii.toFloat(), 0f, (width - outerRadii).toFloat(), height.toFloat(), | |
paint!! | |
) | |
alpha = | |
((thumbOnCenterX - thumbBounds!!.centerX()) / (thumbOnCenterX - thumbOffCenterX) * 255).toInt() | |
alpha = if (alpha < 0) 0 else if (alpha > 255) 255 else alpha | |
val offColor = Color.argb( | |
alpha, | |
Color.red(colorOff), | |
Color.green(colorOff), | |
Color.blue(colorOff) | |
) | |
paint!!.setColor(offColor) | |
canvas.drawArc(leftFgArc!!, 90f, 180f, false, paint!!) | |
canvas.drawArc(rightFgArc!!, 90f, -180f, false, paint!!) | |
canvas.drawRect( | |
outerRadii.toFloat(), | |
(padding / 10).toFloat(), | |
(width - outerRadii).toFloat(), | |
(height - padding / 10).toFloat(), | |
paint!! | |
) | |
} | |
// Drawing Switch Labels here | |
val MAX_CHAR = "N" | |
val textCenter = paint!!.measureText(MAX_CHAR) / 2 | |
if (isOn) { | |
var alpha = | |
(((width ushr 1) - thumbBounds!!.centerX()) / ((width ushr 1) - thumbOffCenterX) * 255).toInt() | |
alpha = if (alpha < 0) 0 else if (alpha > 255) 255 else alpha | |
val onColor = | |
Color.argb(alpha, Color.red(colorOn), Color.green(colorOn), Color.blue(colorOn)) | |
paint!!.setColor(onColor) | |
var centerX = | |
(width - padding - (padding + (padding ushr 1) + (thumbRadii shl 1)) ushr 1).toFloat() | |
canvas.drawText( | |
labelOff!!, | |
padding + (padding ushr 1) + (thumbRadii shl 1) + centerX - paint!!.measureText( | |
labelOff | |
) / 2, (height ushr 1) + textCenter, | |
paint!! | |
) | |
alpha = | |
((thumbBounds!!.centerX() - (width ushr 1)) / (thumbOnCenterX - (width ushr 1)) * 255).toInt() | |
alpha = if (alpha < 0) 0 else if (alpha > 255) 255 else alpha | |
val offColor = | |
Color.argb(alpha, Color.red(colorOff), Color.green(colorOff), Color.blue(colorOff)) | |
paint!!.setColor(offColor) | |
val maxSize = width - (padding shl 1) - (thumbRadii shl 1) | |
centerX = ((padding ushr 1) + maxSize - padding ushr 1).toFloat() | |
canvas.drawText( | |
labelOn!!, | |
padding + centerX - paint!!.measureText(labelOn) / 2, | |
(height ushr 1) + textCenter, | |
paint!! | |
) | |
} else { | |
var alpha = | |
((thumbBounds!!.centerX() - (width ushr 1)) / (thumbOnCenterX - (width ushr 1)) * 255).toInt() | |
alpha = if (alpha < 0) 0 else if (alpha > 255) 255 else alpha | |
val offColor = | |
Color.argb(alpha, Color.red(colorOff), Color.green(colorOff), Color.blue(colorOff)) | |
paint!!.setColor(offColor) | |
val maxSize = width - (padding shl 1) - (thumbRadii shl 1) | |
var centerX = ((padding ushr 1) + maxSize - padding ushr 1).toFloat() | |
canvas.drawText( | |
labelOn!!, | |
padding + centerX - paint!!.measureText(labelOn) / 2, | |
(height ushr 1) + textCenter, | |
paint!! | |
) | |
alpha = | |
(((width ushr 1) - thumbBounds!!.centerX()) / ((width ushr 1) - thumbOffCenterX) * 255).toInt() | |
alpha = if (alpha < 0) 0 else if (alpha > 255) 255 else alpha | |
val onColor: Int = if (isEnabled) { | |
Color.argb(alpha, Color.red(colorOn), Color.green(colorOn), Color.blue(colorOn)) | |
} else { | |
Color.argb( | |
alpha, | |
Color.red(colorDisabled), | |
Color.green(colorDisabled), | |
Color.blue(colorDisabled) | |
) | |
} | |
paint!!.setColor(onColor) | |
centerX = | |
(width - padding - (padding + (padding ushr 1) + (thumbRadii shl 1)) ushr 1).toFloat() | |
canvas.drawText( | |
labelOff!!, | |
padding + (padding ushr 1) + (thumbRadii shl 1) + centerX - paint!!.measureText( | |
labelOff | |
) / 2, (height ushr 1) + textCenter, | |
paint!! | |
) | |
} | |
// Drawing Switch Thumb here | |
run { | |
var alpha = | |
((thumbBounds!!.centerX() - thumbOffCenterX) / (thumbOnCenterX - thumbOffCenterX) * 255).toInt() | |
alpha = if (alpha < 0) 0 else if (alpha > 255) 255 else alpha | |
val offColor = Color.argb( | |
alpha, | |
Color.red(colorOff), | |
Color.green(colorOff), | |
Color.blue(colorOff) | |
) | |
paint!!.setColor(offColor) | |
canvas.drawCircle( | |
thumbBounds!!.centerX(), thumbBounds!!.centerY(), thumbRadii.toFloat(), | |
paint!! | |
) | |
alpha = | |
((thumbOnCenterX - thumbBounds!!.centerX()) / (thumbOnCenterX - thumbOffCenterX) * 255).toInt() | |
alpha = if (alpha < 0) 0 else if (alpha > 255) 255 else alpha | |
val onColor: Int = if (isEnabled) { | |
Color.argb( | |
alpha, | |
Color.red(colorOn), | |
Color.green(colorOn), | |
Color.blue(colorOn) | |
) | |
} else { | |
Color.argb( | |
alpha, | |
Color.red(colorDisabled), | |
Color.green(colorDisabled), | |
Color.blue(colorDisabled) | |
) | |
} | |
paint!!.setColor(onColor) | |
canvas.drawCircle( | |
thumbBounds!!.centerX(), thumbBounds!!.centerY(), thumbRadii.toFloat(), | |
paint!! | |
) | |
} | |
} | |
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) { | |
val desiredWidth = resources.getDimensionPixelSize(R.dimen.labeled_default_width) | |
val desiredHeight = resources.getDimensionPixelSize(R.dimen.labeled_default_height) | |
val widthMode = MeasureSpec.getMode(widthMeasureSpec) | |
val widthSize = MeasureSpec.getSize(widthMeasureSpec) | |
val heightMode = MeasureSpec.getMode(heightMeasureSpec) | |
val heightSize = MeasureSpec.getSize(heightMeasureSpec) | |
width = when (widthMode) { | |
MeasureSpec.EXACTLY -> { | |
widthSize | |
} | |
MeasureSpec.AT_MOST -> { | |
min(desiredWidth, widthSize) | |
} | |
else -> { | |
desiredWidth | |
} | |
} | |
height = when (heightMode) { | |
MeasureSpec.EXACTLY -> { | |
heightSize | |
} | |
MeasureSpec.AT_MOST -> { | |
min(desiredHeight, heightSize) | |
} | |
else -> { | |
desiredHeight | |
} | |
} | |
setMeasuredDimension(width, height) | |
outerRadii = min(width, height) ushr 1 | |
thumbRadii = (min(width, height) / 2.88f).toInt() | |
padding = height - thumbRadii ushr 1 | |
thumbBounds!![(width - padding - thumbRadii).toFloat(), padding.toFloat(), (width - padding).toFloat()] = | |
(height - padding).toFloat() | |
thumbOnCenterX = thumbBounds!!.centerX() | |
thumbBounds!![padding.toFloat(), padding.toFloat(), (padding + thumbRadii).toFloat()] = | |
(height - padding).toFloat() | |
thumbOffCenterX = thumbBounds!!.centerX() | |
if (isOn) { | |
thumbBounds!![(width - padding - thumbRadii).toFloat(), padding.toFloat(), (width - padding).toFloat()] = | |
(height - padding).toFloat() | |
} else { | |
thumbBounds!![padding.toFloat(), padding.toFloat(), (padding + thumbRadii).toFloat()] = | |
(height - padding).toFloat() | |
} | |
leftBgArc!![0f, 0f, (outerRadii shl 1).toFloat()] = height.toFloat() | |
rightBgArc!![(width - (outerRadii shl 1)).toFloat(), 0f, width.toFloat()] = height.toFloat() | |
leftFgArc!![(padding / 10).toFloat(), (padding / 10).toFloat(), ((outerRadii shl 1) - padding / 10).toFloat()] = | |
(height - padding / 10).toFloat() | |
rightFgArc!![(width - (outerRadii shl 1) + padding / 10).toFloat(), (padding / 10).toFloat(), (width - padding / 10).toFloat()] = | |
(height - padding / 10).toFloat() | |
} | |
/** | |
* Call this view's OnClickListener, if it is defined. Performs all normal | |
* actions associated with clicking: reporting accessibility event, playing | |
* a sound, etc. | |
* | |
* @return True there was an assigned OnClickListener that was called, false | |
* otherwise is returned. | |
*/ | |
override fun performClick(): Boolean { | |
super.performClick() | |
if (isOn) { | |
val switchColor = | |
ValueAnimator.ofFloat((width - padding - thumbRadii).toFloat(), padding.toFloat()) | |
switchColor.addUpdateListener { animation: ValueAnimator -> | |
val value = animation.getAnimatedValue() as Float | |
thumbBounds!![value, thumbBounds!!.top, value + thumbRadii] = thumbBounds!!.bottom | |
invalidate() | |
} | |
switchColor.interpolator = AccelerateDecelerateInterpolator() | |
switchColor.setDuration(250) | |
switchColor.start() | |
} else { | |
val switchColor = | |
ValueAnimator.ofFloat(padding.toFloat(), (width - padding - thumbRadii).toFloat()) | |
switchColor.addUpdateListener { animation: ValueAnimator -> | |
val value = animation.getAnimatedValue() as Float | |
thumbBounds!![value, thumbBounds!!.top, value + thumbRadii] = thumbBounds!!.bottom | |
invalidate() | |
} | |
switchColor.interpolator = AccelerateDecelerateInterpolator() | |
switchColor.setDuration(250) | |
switchColor.start() | |
} | |
isOn = !isOn | |
if (onToggledListener != null) { | |
onToggledListener!!.onSwitched(this, isOn) | |
} | |
return true | |
} | |
/** | |
* Method to handle touch screen motion events. | |
* | |
* @param event The motion event. | |
* @return True if the event was handled, false otherwise. | |
*/ | |
override fun onTouchEvent(event: MotionEvent): Boolean { | |
return if (isEnabled) { | |
val x = event.x | |
when (event.action) { | |
MotionEvent.ACTION_DOWN -> { | |
startTime = System.currentTimeMillis() | |
true | |
} | |
MotionEvent.ACTION_MOVE -> { | |
if (x - (thumbRadii ushr 1) > padding && x + (thumbRadii ushr 1) < width - padding) { | |
thumbBounds!![x - (thumbRadii ushr 1), thumbBounds!!.top, x + (thumbRadii ushr 1)] = | |
thumbBounds!!.bottom | |
invalidate() | |
} | |
true | |
} | |
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> { | |
val endTime = System.currentTimeMillis() | |
val span = endTime - startTime | |
if (span < 200) { | |
performClick() | |
} else { | |
if (x >= width ushr 1) { | |
val switchColor = ValueAnimator.ofFloat( | |
(if (x > width - padding - thumbRadii) width - padding - thumbRadii else x) as Float, | |
(width - padding - thumbRadii).toFloat() | |
) | |
switchColor.addUpdateListener { animation: ValueAnimator -> | |
val value = | |
animation.getAnimatedValue() as Float | |
thumbBounds!![value, thumbBounds!!.top, value + thumbRadii] = | |
thumbBounds!!.bottom | |
invalidate() | |
} | |
switchColor.interpolator = AccelerateDecelerateInterpolator() | |
switchColor.setDuration(250) | |
switchColor.start() | |
isOn = true | |
} else { | |
val switchColor = ValueAnimator.ofFloat( | |
(if (x < padding) padding else x) as Float, | |
padding.toFloat() | |
) | |
switchColor.addUpdateListener { animation: ValueAnimator -> | |
val value = | |
animation.getAnimatedValue() as Float | |
thumbBounds!![value, thumbBounds!!.top, value + thumbRadii] = | |
thumbBounds!!.bottom | |
invalidate() | |
} | |
switchColor.interpolator = AccelerateDecelerateInterpolator() | |
switchColor.setDuration(250) | |
switchColor.start() | |
isOn = false | |
} | |
if (onToggledListener != null) { | |
onToggledListener!!.onSwitched(this, isOn) | |
} | |
} | |
invalidate() | |
true | |
} | |
else -> { | |
super.onTouchEvent(event) | |
} | |
} | |
} else { | |
false | |
} | |
} | |
/** | |
* | |
* Returns the color value for colorOn. | |
* | |
* @return color value for label and thumb in off state and background in on state. | |
*/ | |
fun getColorOn(): Int { | |
return colorOn | |
} | |
/** | |
* | |
* Changes the on color value of this Switch. | |
* | |
* @param colorOn color value for label and thumb in off state and background in on state. | |
*/ | |
fun setColorOn(colorOn: Int) { | |
this.colorOn = colorOn | |
invalidate() | |
} | |
/** | |
* | |
* Returns the color value for colorOff. | |
* | |
* @return color value for label and thumb in on state and background in off state. | |
*/ | |
fun getColorOff(): Int { | |
return colorOff | |
} | |
/** | |
* | |
* Changes the off color value of this Switch. | |
* | |
* @param colorOff color value for label and thumb in on state and background in off state. | |
*/ | |
fun setColorOff(colorOff: Int) { | |
this.colorOff = colorOff | |
invalidate() | |
} | |
/** | |
* | |
* Returns text label when switch is in on state. | |
* | |
* @return text label when switch is in on state. | |
*/ | |
fun getLabelOn(): String? { | |
return labelOn | |
} | |
/** | |
* | |
* Changes text label when switch is in on state. | |
* | |
* @param labelOn text label when switch is in on state. | |
*/ | |
fun setLabelOn(labelOn: String?) { | |
this.labelOn = labelOn | |
invalidate() | |
} | |
/** | |
* | |
* Returns text label when switch is in off state. | |
* | |
* @return text label when switch is in off state. | |
*/ | |
fun getLabelOff(): String? { | |
return labelOff | |
} | |
/** | |
* | |
* Changes text label when switch is in off state. | |
* | |
* @param labelOff text label when switch is in off state. | |
*/ | |
fun setLabelOff(labelOff: String?) { | |
this.labelOff = labelOff | |
invalidate() | |
} | |
/** | |
* | |
* Changes the boolean state of this Switch. | |
* | |
* @param on true to turn switch on, false to turn it off. | |
*/ | |
fun setOn(on: Boolean) { | |
super.isOn = on | |
if (isOn) { | |
thumbBounds!![(width - padding - thumbRadii).toFloat(), padding.toFloat(), (width - padding).toFloat()] = | |
(height - padding).toFloat() | |
} else { | |
thumbBounds!![padding.toFloat(), padding.toFloat(), (padding + thumbRadii).toFloat()] = | |
(height - padding).toFloat() | |
} | |
invalidate() | |
} | |
/** | |
* | |
* Returns the color value for Switch disabled state. | |
* | |
* @return color value used by background, border and thumb when switch is disabled. | |
*/ | |
fun getColorDisabled(): Int { | |
return colorDisabled | |
} | |
/** | |
* | |
* Changes the color value for Switch disabled state. | |
* | |
* @param colorDisabled color value used by background, border and thumb when switch is disabled. | |
*/ | |
fun setColorDisabled(colorDisabled: Int) { | |
this.colorDisabled = colorDisabled | |
invalidate() | |
} | |
/** | |
* | |
* Returns the color value for Switch border. | |
* | |
* @return color value used by Switch border. | |
*/ | |
fun getColorBorder(): Int { | |
return colorBorder | |
} | |
/** | |
* | |
* Changes the color value for Switch disabled state. | |
* | |
* @param colorBorder color value used by Switch border. | |
*/ | |
fun setColorBorder(colorBorder: Int) { | |
this.colorBorder = colorBorder | |
invalidate() | |
} | |
/** | |
* | |
* Returns the text size for Switch on/off label. | |
* | |
* @return text size for Switch on/off label. | |
*/ | |
fun getTextSize(): Int { | |
return textSize | |
} | |
/** | |
* | |
* Changes the text size for Switch on/off label. | |
* | |
* @param textSize text size for Switch on/off label. | |
*/ | |
fun setTextSize(textSize: Int) { | |
this.textSize = (textSize * resources.displayMetrics.scaledDensity).toInt() | |
invalidate() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2024. YohannesTz, Africa Technologies PLC | |
*/ | |
import android.view.View | |
interface OnStateChangedListener { | |
/** | |
* Called when a view changes it's state. | |
* | |
* @param view The view whose state was changed. | |
* @param state The state of the view. | |
*/ | |
fun onStateChanged(view: View?, state: Int) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2024. YohannesTz, Africa Technologies PLC | |
*/ | |
interface OnToggledListener { | |
/** | |
* Called when a view changes it's state. | |
* | |
* @param toggleableView The view which either is on/off. | |
* @param isOn The on/off state of switch, true when switch turns on. | |
*/ | |
fun onSwitched(toggleableView: ToggleableView?, isOn: Boolean) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright (c) 2024. YohannesTz, Africa Technologies PLC | |
*/ | |
import android.content.Context | |
import android.util.AttributeSet | |
import android.view.View | |
import android.view.ViewDebug.ExportedProperty | |
open class ToggleableView : View { | |
@get:JvmName("ToggleableView_width") | |
@set:JvmName("ToggleableView_width") | |
protected var width = 0 | |
@get:JvmName("ToggleableView_height") | |
@set:JvmName("ToggleableView_height") | |
protected var height = 0 | |
/** | |
* | |
* Returns the boolean state of this Switch. | |
* | |
* @return true if the switch is on, false if it is off. | |
*/ | |
/** | |
* | |
* Changes the boolean state of this Switch. | |
* | |
* @param on true to turn switch on, false to turn it off. | |
*/ | |
/** | |
* Field to determine whether switch is on/off. | |
* | |
* @see .isOn | |
* @see .setOn | |
*/ | |
@get:JvmName("ToggleableView_isOn") | |
@set:JvmName("ToggleableView_isOn") | |
var isOn = false | |
/** | |
* Field to determine whether switch is enabled/disabled. | |
* | |
* @see .isEnabled | |
* @see .setEnabled | |
*/ | |
@get:JvmName("ToggleableView_Enabled") | |
@set:JvmName("ToggleableView_Enabled") | |
protected var enabled = false | |
/** | |
* Listener used to dispatch switch events. | |
* | |
* @see .setOnToggledListener | |
*/ | |
@get:JvmName("onToggleableViewToggledListener") | |
@set:JvmName("onToggleableViewToggledListener") | |
protected var onToggledListener: OnToggledListener? = null | |
/** | |
* Simple constructor to use when creating a switch from code. | |
* @param context The Context the switch is running in, through which it can | |
* access the current theme, resources, etc. | |
*/ | |
constructor(context: Context?) : super(context) | |
/** | |
* Constructor that is called when inflating a switch from XML. | |
* | |
* @param context The Context the switch is running in, through which it can | |
* access the current theme, resources, etc. | |
* @param attrs The attributes of the XML tag that is inflating the switch. | |
*/ | |
constructor(context: Context?, attrs: AttributeSet?) : super(context, attrs) | |
/** | |
* Perform inflation from XML and apply a class-specific base style from a | |
* theme attribute. | |
* | |
* @param context The Context the switch is running in, through which it can | |
* access the current theme, resources, etc. | |
* @param attrs The attributes of the XML tag that is inflating the switch. | |
* @param defStyleAttr An attribute in the current theme that contains a | |
* reference to a style resource that supplies default values for | |
* the switch. Can be 0 to not look for defaults. | |
*/ | |
constructor(context: Context?, attrs: AttributeSet?, defStyleAttr: Int) : super( | |
context, | |
attrs, | |
defStyleAttr | |
) | |
/** | |
* Returns the enabled status for this switch. The interpretation of the | |
* enabled state varies by subclass. | |
* | |
* @return True if this switch is enabled, false otherwise. | |
*/ | |
@ExportedProperty | |
override fun isEnabled(): Boolean { | |
return enabled | |
} | |
/** | |
* Set the enabled state of this switch. The interpretation of the enabled | |
* state varies by subclass. | |
* | |
* @param enabled True if this view is enabled, false otherwise. | |
*/ | |
override fun setEnabled(enabled: Boolean) { | |
this.enabled = enabled | |
} | |
/** | |
* Register a callback to be invoked when the boolean state of switch is changed. If this switch is not | |
* enabled, there won't be any event. | |
* | |
* @param onToggledListener The callback that will run | |
* | |
* @see .setEnabled | |
*/ | |
@JvmName("ToggleableView_setOnToggledListener") | |
fun setOnToggledListener(onToggledListener: OnToggledListener?) { | |
this.onToggledListener = onToggledListener | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment