Skip to content

Commit

Permalink
ReactSwitch.java → Kotlin (facebook#45931)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: facebook#45931

Migration to Kotlin.

Changelog: [Android][Changed] Migrated ReactSwitch to Kotlin

Reviewed By: cortinico

Differential Revision: D60898267

fbshipit-source-id: 530e240a071deb3eff3e463f04edc590de03c594
  • Loading branch information
blakef authored and facebook-github-bot committed Aug 8, 2024
1 parent b722123 commit 03c0e5e
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 124 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.react.views.switchview

import android.content.Context
import android.content.res.ColorStateList
import android.graphics.PorterDuff
import android.graphics.PorterDuffColorFilter
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.RippleDrawable
import androidx.appcompat.widget.SwitchCompat

/**
* Switch that has its value controlled by JS. Whenever the value of the switch changes, we do not
* allow any other changes to that switch until JS sets a value explicitly. This stops the Switch
* from changing its value multiple times, when those changes have not been processed by JS first.
*/
internal class ReactSwitch(context: Context) : SwitchCompat(context) {

private var allowChange = true
private var trackColorForFalse: Int? = null
private var trackColorForTrue: Int? = null

override fun setChecked(checked: Boolean) {
if (allowChange && isChecked != checked) {
allowChange = false
super.setChecked(checked)
setTrackColor(checked)
} else {
// Even if mAllowChange is set to false or the checked value hasn't changed, we still must
// call the super method, since it will make sure the thumb is moved back to the correct edge.
// Without calling the super method, the thumb might stuck in the middle of the switch.
super.setChecked(isChecked)
}
}

override fun setBackgroundColor(color: Int) {
background =
RippleDrawable(createRippleDrawableColorStateList(color), ColorDrawable(color), null)
}

public fun setColor(drawable: Drawable, color: Int?): Unit {
if (color == null) {
drawable.clearColorFilter()
} else {
drawable.setColorFilter(PorterDuffColorFilter(color, PorterDuff.Mode.MULTIPLY))
}
}

public fun setTrackColor(color: Int?): Unit {
setColor(super.getTrackDrawable(), color)
}

public fun setThumbColor(color: Int?): Unit {
setColor(super.getThumbDrawable(), color)

// Set the ripple color if background is instance of RippleDrawable
if (color != null && super.getBackground() is RippleDrawable) {
val customColorState = createRippleDrawableColorStateList(color)
(super.getBackground() as RippleDrawable).setColor(customColorState)
}
}

public fun setOn(on: Boolean): Unit {
// If the switch has a different value than the value sent by JS, we must change it.
if (isChecked != on) {
super.setChecked(on)
setTrackColor(on)
}
allowChange = true
}

public fun setTrackColorForTrue(color: Int?): Unit {
if (color == trackColorForTrue) {
return
}
trackColorForTrue = color
if (isChecked) {
setTrackColor(trackColorForTrue)
}
}

public fun setTrackColorForFalse(color: Int?): Unit {
if (color == trackColorForFalse) {
return
}
trackColorForFalse = color
if (!isChecked) {
setTrackColor(trackColorForFalse)
}
}

private fun setTrackColor(checked: Boolean) {
if (trackColorForTrue != null || trackColorForFalse != null) {
// Update the track color to reflect the new value. We only want to do this if these
// props were actually set from JS; otherwise we'll just reset the color to the default.
val currentTrackColor = if (checked) trackColorForTrue else trackColorForFalse
setTrackColor(currentTrackColor)
}
}

private fun createRippleDrawableColorStateList(color: Int): ColorStateList =
ColorStateList(arrayOf(intArrayOf(android.R.attr.state_pressed)), intArrayOf(color))
}

0 comments on commit 03c0e5e

Please sign in to comment.