对讲在第二次导航后不会聚焦新片段



我有一个使用Android导航的应用程序(单个活动多个片段(
启动时,应用程序会显示一个加载屏幕,一个可选的"新闻"-键入screen,完成后将用户返回到主屏幕,然后返回主屏幕
但是,我在获取主屏幕的可访问性方面遇到了问题。当新闻屏幕没有显示时,它会被很好地聚焦,但当它被包括在内时,主屏幕将不会被聚焦,这似乎仍在加载屏幕上。

我已经能够在一个最小的例子中重现这一点;加载"A";,以及";B";。这里的应用程序行为是:

  • 在主片段上启动
  • 等待5秒钟,导航到片段A
  • 用户按下";继续">
  • 返回到主片段
  • 等待5秒钟,导航到片段B

每次导航后,我都希望文本元素聚焦并读出。然而,对于片段B,它不是。

我尝试过的东西:

  • 在片段B中使用<requestFocus />
  • 请求代码中的焦点
  • 设置"0"的CCD_ 2状态;加载";导航离开前的碎片

如果我将加载片段更改为使用按钮进行导航,而不是自动行为,则焦点确实正确通过,但显然不能提供正确的体验。

class LoadingFragment : Fragment() {
private lateinit var rootView: View
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_main, container, false).also {
rootView = it
}
private var beenHereBefore = false
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// Mimic a delayed loading process
Handler(Looper.getMainLooper()).postDelayed({
// Navigate to the correct screen, based on state
findNavController().navigate(
if (beenHereBefore) {
R.id.action_mainFragment_to_fragmentB
} else {
beenHereBefore = true
R.id.action_mainFragment_to_fragmentA
}
)
}, 5000)
}
}

fragment_main.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.main.LoadingFragment">
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="MainFragment"
android:textColor="@color/black"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
class FragmentA : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_a, container, false)
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
view.findViewById<Button>(R.id.button).setOnClickListener {
findNavController().popBackStack()
}
}
}

fragment_a.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
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">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment A"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="308dp"
android:text="Continue"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
</androidx.constraintlayout.widget.ConstraintLayout>
class FragmentB : Fragment() {
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = inflater.inflate(R.layout.fragment_b, container, false)
}

fragment_b.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
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">
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Fragment B"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>

main_graph.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main_graph"
app:startDestination="@id/mainFragment">
<fragment
android:id="@+id/mainFragment"
android:name="com.example.navigationtestapp.ui.main.LoadingFragment"
android:label="fragment_main"
tools:layout="@layout/fragment_main" >
<action
android:id="@+id/action_mainFragment_to_fragmentA"
app:destination="@id/fragmentA" />
<action
android:id="@+id/action_mainFragment_to_fragmentB"
app:destination="@id/fragmentB" />
</fragment>
<fragment
android:id="@+id/fragmentA"
android:name="com.example.navigationtestapp.ui.main.FragmentA"
android:label="FragmentA" />
<fragment
android:id="@+id/fragmentB"
android:name="com.example.navigationtestapp.ui.main.FragmentB"
android:label="FragmentB" />
</navigation>

如果我是,您将尝试使用可访问性API而不是requestFocus来处理可访问性焦点。您已经提到焦点似乎被加载屏幕占据,所以这应该可以工作,因为a11y焦点将跟随它,但我将尝试使用sendAccessibilityEvent方法来处理这一问题https://developer.android.com/reference/android/view/accessibility/AccessibilityEventSource#sendAccessibilityEvent(int(

// Moving a11y focus from btn1 to btn 2
btn1 = (Button) findViewById(R.id.screen3_btn1);
btn2 = (Button) findViewById(R.id.screen3_btn2);
btn1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
btn2.sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_FOCUSED);
}
});

很好的答案:Android-将TalkBack可访问性焦点设置为特定视图

希望这能帮助

相关内容

  • 没有找到相关文章

最新更新