惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

D
Docker
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
博客园 - 【当耐特】
量子位
博客园 - 叶小钗
有赞技术团队
有赞技术团队
Jina AI
Jina AI
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - Franky
博客园 - 司徒正美
爱范儿
爱范儿
美团技术团队
小众软件
小众软件
酷 壳 – CoolShell
酷 壳 – CoolShell
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
V
V2EX
罗磊的独立博客
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Last Week in AI
Last Week in AI
Hugging Face - Blog
Hugging Face - Blog
I
InfoQ
D
DataBreaches.Net
宝玉的分享
宝玉的分享

博客园 - 翻滚的咸鱼

Ops权限行为记录源码解析 TaskView方案框架原理 视频解码器问题 常用命令 扫光动效 引导记录 性能优化 View共享动效 常用脚本文件 Launcher 卡片框架多模块集成 Launcher 桌面源码笔记二 Launcher 桌面源码笔记一 氛围灯动态屏保取色方案二 氛围灯动态屏保取色方案一 自定义最近任务管理器 anr问题 TV RecyclerView 焦点处理笔记 多类型适配器 多屏下字体自动取色 阻尼拉伸方案 图片区域点击处理 TV RecyclerView 滑动后操作保持落焦在左侧第一个View Fragment翻盖动效 当个View下,使用Drawable入场退场动画
RecyclerView设置默认焦点跟多页面焦点抢占
翻滚的咸鱼 · 2024-06-18 · via 博客园 - 翻滚的咸鱼

场景:多个tab切换,显示不同的Fragment,其中一个Fragment布局是两个RecyclerView,分别位于左右两侧

需求:首次从tabView切换到改tab页时,焦点从tabView首次往下移动时,需要落焦在右侧的第一个item上面

如果按照系统原生逻辑,从tabView下移,可能默认位置不会在右侧,此时需要确保,每次往下移动,焦点都需要在右侧第一个

方案1、初始化时就 requestFocus 肯定行不通,因为切换tab时就会触发

方案2、使用自定义View,重写 addFocusables ,把默认焦点添加进列表,此时系统默认寻找的焦点就是设置的view

方案可行,前提是没有焦点抢占问题(比如多tab同时存在时会有焦点抢占问题)

比如有个切换动效,动效存在时切换的两个页面会同时存在并且显示在前台,这个时候,快速切换tab并且往下移动,会发现动画未结束,落焦会跑到上一个tabView的页面上,然后动画结束,上一个页面隐藏,焦点在回到当前唯一显示的页面,虽然最后焦点回到了当前页面,可是会有一个焦点延迟闪烁的过程;

又或者你在其它地方主动 request 了,导致焦点冲突闪烁问题;

方案3、强行 requestFocus ,行为粗暴,并且有的情况下会多次请求,导致焦点闪烁问题

终极方案、使用父容器控制子容器焦点,哪怕焦点被抢占,依然可以丝滑落焦

不要一下子请求子View的焦点,把焦点定在最外层的父容器上面,系统默认移动是寻找最近的view作为落焦点,父容器无疑是最近的

监听父容器的焦点变化,如果存在焦点,在请求子View焦点(父容器上落焦状态需要隐藏,达到无痕状态)

这个时候你会发现,无论焦点是被其它view抢占,还是其它窗口抢占,都能回到你指定的view上

mBinding.rootView.setOnFocusChangeListener { v, hasFocus ->
            val focusItemView = mBinding.rvMode.getChildAt(0)
            Logger.d("FocusChange hasFocus $hasFocus itemFocus ${focusItemView.hasFocus()}")
            if (hasFocus && !focusItemView.hasFocus()) {
                mBinding.rvMode.post {
                    focusItemView?.requestFocus()
                }
            }
        }