Android Kotlin实现TalkBack朗读进度条项目数而非百分比
实现TalkBack朗读故事进度(当前/总数)而非百分比
要让Android的TalkBack功能像Instagram故事那样朗读“第X个故事,共Y个”,而非默认的百分比进度,需要修改进度条的可访问性配置,并动态更新朗读内容。以下是具体实现步骤:
1. 禁用单个进度条的默认可访问性播报
每个LinearProgressIndicator默认会播报自身的进度百分比,我们需要让TalkBack忽略这些单个进度条,转而关注整体的故事进度信息。
修改createProgressBars函数,在创建每个进度条时添加可访问性设置:
private fun storyState.createProgressBars() { var progressBarWidth = context?.resources?.displayMetrics?.widthPixels?.div(stories.size) ?: STORY_PROGRESS_BAR progressBarWidth -= (STORY_PROGRESS_BAR_SPACING * 2) (0 until stories.size).forEach { _ -> val progressBar = LinearProgressIndicator(requireContext()) // 禁用单个进度条的可访问性播报 progressBar.importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_NO progressBar.layoutParams = LinearLayout.LayoutParams(progressBarWidth, STORY_PROGRESS_BAR_SPACING, 1f) progressBar.setIndicatorColor(getColorByMode(currentStoryScreen.mode.value)) progressBar.trackCornerRadius = STORY_PROGRESS_BAR_SPACING progressBar.trackThickness = STORY_PROGRESS_BAR_SPACING progressBar.trackColor = Color.parseColor("#A79AA9") progressBar.alpha = STORY_PROGRESS_BAR_ALPHA progressBar.setPadding(STORY_PROGRESS_BAR_SPACING, 0, STORY_PROGRESS_BAR_SPACING, 0) binding.linearLayoutStoryProgressBar.addView(progressBar) } // 设置父布局可聚焦,让TalkBack能识别并朗读内容描述 binding.linearLayoutStoryProgressBar.isFocusable = true binding.linearLayoutStoryProgressBar.isFocusableInTouchMode = true binding.linearLayoutStoryProgressBar.requestLayout() }
2. 添加动态更新可访问性播报的函数
创建一个专门的函数,用于生成并更新当前故事进度的朗读内容,必要时可主动触发TalkBack播报:
private fun updateStoryAccessibilityAnnouncement() { val currentPosition = viewModel.getCurrentPosition() + 1 // 转换为1-based索引 val totalStories = stories.size val announcementText = "第${currentPosition}个故事,共${totalStories}个" // 更新父布局的内容描述 binding.linearLayoutStoryProgressBar.contentDescription = announcementText // 主动触发TalkBack播报(可选,确保内容变化时即时朗读) context?.let { ctx -> val accessibilityManager = ctx.getSystemService(Context.ACCESSIBILITY_SERVICE) as AccessibilityManager if (accessibilityManager.isEnabled) { val event = AccessibilityEvent.obtain(AccessibilityEvent.TYPE_ANNOUNCEMENT) event.text.add(announcementText) accessibilityManager.sendAccessibilityEvent(event) } } }
3. 在故事切换时调用更新函数
需要在故事进度变化的关键节点调用上述函数,确保TalkBack能及时朗读最新的进度信息:
3.1 初始化进度条时调用
修改setupStoryProgressBar函数,在设置动画后添加播报更新:
private fun storyState.setupStoryProgressBar() { if (binding.linearLayoutStoryProgressBar.childCount == 0) { createProgressBars() } setProgressBarAnimation( binding.linearLayoutStoryProgressBar.getChildAt(currentPosition) as LinearProgressIndicator, currentStoryScreen.storyTimeout.toLong(), getColorByMode(currentStoryScreen.mode.value) ) // 更新可访问性播报 updateStoryAccessibilityAnnouncement() }
3.2 切换到下一个故事时调用
在goToNextStory函数执行完成后(即当前故事位置更新后),调用更新函数:
private fun goToNextStory() { // 原有切换逻辑... // 更新可访问性播报 updateStoryAccessibilityAnnouncement() }
3.3 手动切换故事时调用
如果支持手动左右滑动切换故事,同样需要在切换完成后调用updateStoryAccessibilityAnnouncement()。
4. 可选:处理TalkBack焦点
如果希望用户通过TalkBack导航时能聚焦到进度条区域并朗读内容,确保父布局的focusable和focusableInTouchMode已设置为true(步骤1中已添加)。
这样修改后,TalkBack就会忽略单个进度条的百分比播报,转而朗读当前故事的位置和总数量,与Instagram的故事进度提示一致。
内容的提问来源于stack exchange,提问作者Rayssa Vanessa
相关产品推荐
相关产品推荐

