Distrito Telefónica. Hub de Innovación y Talento
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/custom_toggleable_root_layout"
... >
<ImageView
android:id="@+id/custom_toggleable_left_image"
... />
<TextView
android:id="@+id/custom_toggleable_title"
... />
<TextView
android:id="@+id/custom_toggleable_subtitle"
... />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/custom_toggleable_switch"
... />
</androidx.constraintlayout.widget.ConstraintLayout>
<ImageView
android:id="@+id/custom_toggleable_image"
android:importantForAccessibility="no"
... />
<TextView
android:id="@+id/custom_toggleable_title"
android:importantForAccessibility="no"
... />
<TextView
android:id="@+id/custom_toggleable_subtitle"
android:importantForAccessibility="no"
... />
<androidx.appcompat.widget.SwitchCompat
android:id="@+id/custom_toggleable_switch"
android:clickable="false"
android:importantForAccessibility="no"
... />
class CustomSwitchComponent @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null,
defStyle: Int = 0
) : ConstraintLayout(context, attrs, defStyle) {
// Custom accessibility configuration will go here
}
<com.your.package.CustomSwitchComponent
android:id="@+id/custom_toggleable_root_layout"
... >
<!-- Child views -->
</com.your.package.CustomSwitchComponent>
class CustomSwitchComponent(...) {
private lateinit var titleView: TextView
private lateinit var subtitleView: TextView
private lateinit var switchView: SwitchCompat
override fun onFinishInflate() {
super.onFinishInflate()
titleView = findViewById(R.id.custom_toggleable_title)
subtitleView = findViewById(R.id.custom_toggleable_subtitle)
switchView = findViewById(R.id.custom_toggleable_switch)
initAccessibilityConfiguration()
}
private fun initAccessibilityConfiguration() {
contentDescription = "${titleView.text}. ${subtitleView.text}"
}
}
class CustomSwitchComponent(...) {
...
override fun onInitializeAccessibilityEvent(event: AccessibilityEvent?) {
super.onInitializeAccessibilityEvent(event)
event?.className = android.widget.Switch::class.java.name
}
override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo?) {
super.onInitializeAccessibilityNodeInfo(info)
info?.className = android.widget.Switch::class.java.name
}
}
private fun initAccessibilityConfiguration() {
...
ViewCompat.setStateDescription(this@CustomSwitchComponent, ViewCompat.getStateDescription(switchView))
}
El código anterior está bien, y podemos comprobar que Talkback efectivamente anuncia el estado del Interruptor en nuestro componente.
fun changeSwitchState(enable: Boolean) {
switchView.isChecked = enable
ViewCompat.setStateDescription(this@CustomSwitchComponent, ViewCompat.getStateDescription(switchView))
}
fun getSwitchState() = switchView.isChecked
Con estos métodos, podemos cambiar el estado del Interruptor a través de nuestro componente personalizado.
val component: CustomSwitchComponent = findViewById(R.id.custom_toggleable_root_layout)
component.setOnClickListener {
component.changeSwitchState(!component.getSwitchState())
}
override fun onInitializeAccessibilityNodeInfo(info: AccessibilityNodeInfo?) {
...
info?.addAction(
AccessibilityNodeInfo.AccessibilityAction(
AccessibilityNodeInfoCompat.ACTION_CLICK,
"toggle" // Remember to use a stringRes reference instead of hardcoded text.
)
)
}
info?.addAction(
AccessibilityNodeInfo.AccessibilityAction(
AccessibilityNodeInfoCompat.ACTION_CLICK,
if (switchView.isChecked) "turn off" else "turn on"
)
)