When a view is made VISIBLE a certain way, Talkback can no longer select / click / focus on that view, see: https://github.com/kai-vala/DemoForAccessibilityBugs/blob/master/images/animation.gif
(Not enough rep to embed images)
Full example app is here: https://github.com/kai-vala/DemoForAccessibilityBugs
Realized that its caused by the transition, if we remove: TransitionManager.beginDelayedTransition(it)
, the view is always selectable.
I'm looking for a way to get the focus / clickable to work consistently even with the delayed transition.
The following should occur consistently with Android 11 on simulator:
Fresh start the app
Tap the button to perform transition
Try to select 'Edit text 2' view, notice it cannot be clicked (swipe navigation with Talkback will also bypass it)
For completenesses sake I'll add a minimal code example below, but I recommend checking out from the repo directly.
EDIT: Modified example code to be simpler after I realized this is caused by the transition.
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<data>
<variable
name="vm"
type="com.valagroup.demoforaccessibilitybugs.MainViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginStart="12.5dp"
android:layout_marginTop="12.5dp"
android:layout_marginEnd="12.5dp"
android:layout_marginBottom="12.5dp"
tools:context=".MainActivity">
<TextView
android:id="@+id/title_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minWidth="44dp"
android:minHeight="44dp"
android:text="Remember to enable Talkback"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<!-- See MainActivity.kt where the transition is started -->
<androidx.appcompat.widget.AppCompatButton
android:id="@+id/toggleButton"
style="@style/Widget.AppCompat.Button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="44dp"
android:text="Transition between text boxes"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/title_text" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/editTextByButton1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12.5dp"
android:text="Edit text other 1"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/toggleButton"
app:visible="@{vm.buttonState == true}" />
<androidx.appcompat.widget.AppCompatEditText
android:id="@+id/editTextByButton2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12.5dp"
android:text="Edit text other 2"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/editTextByButton1"
app:visible="@{vm.buttonState == false}" />
<TextView
android:id="@+id/bottom_text2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12.5dp"
android:text="Above text boxes are not enabled correctly \nWhen transitions are used with Talkback enabled"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toBottomOf="@id/editTextByButton2" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
MainViewModel.kt
class MainViewModel : ViewModel() {
val buttonState = MutableLiveData<Boolean>().apply { value = true }
fun toggleButtonState() {
buttonState.value = !buttonState.value!!
}
init {
Log.d("MainViewModel", "init")
}
}
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding: ActivityMainBinding =
DataBindingUtil.setContentView(this, R.layout.activity_main)
binding.vm = ViewModelProvider(this).get(MainViewModel::class.java)
binding.lifecycleOwner = this
binding.toggleButton.setOnClickListener { v ->
if (v != null) {
Log.d("OnClick", "toggleButton")
val viewModel = binding.vm as MainViewModel
viewModel.toggleButtonState()
binding.toggleButton.findParent<ConstraintLayout>()?.let {
// TODO/FIXME: The issue where edit texts are not enabled is caused by the transition
TransitionManager.beginDelayedTransition(it)
}
}
}
}
}
@BindingAdapter("visible")
fun visible(view: View, visible: Boolean?) {
Log.d("BindingAdapter", "Changing visibility of view '${view.id}' to: $visible")
view.visibility = if (visible == true) View.VISIBLE else View.GONE
}
private inline fun <reified T : ViewGroup> View.findParent(): T? {
var view = this.parent
while (view != null) {
if (view is T)
return view
view = view.parent
}
return null
}
Workaround for this as answered by an AOSP developer: https://issuetracker.google.com/185532478
We fixed a bug in S related to visibility changes that I think has to be the cause of this bug, although there are a few details I can't quite explain.
The issue is that we didn't sent an accessibility event when a view became invisible, because we don't permit invisible views to send events. The fix was to have the parent sent a subtree changed event.
I think if you check if AccessibilityManager#isEnabled, and if so call notifySubtreeAccessibilityStateChanged on the parent, you will force the correct event to be sent and alert services that the old view has disappeared.
parent= view.parent
// null check, etc
parent.notifySubtreeAccessibilityStateChanged(parent, parent, AccessibilityEvent#CONTENT_CHANGE_TYPE_SUBTREE)
In principle, you should only need to do this if the view has become invisible, as the view becoming visible does send an event. But following that reasoning, I don't see why making the second edit text visible doesn't resolve the issue. Either way, I think notifying that the subtree changed should resolve the issue.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.