Android中RecyclerView动态设图后上层TextView被遮挡问题
问题根源
你遇到的显示异常,核心触发点是给RoundedImageView配置的android:elevation="8dp"属性,和Android系统的Z轴层级绘制规则产生了冲突。
- FrameLayout本身的默认绘制逻辑,是完全按照XML内的视图声明顺序执行的:先写的视图先绘制,后写的视图叠在更上层。你在Android Studio预览界面能看到正常的层级关系,就是因为预览环境严格遵循了这个逻辑——两个TextView的代码块写在RoundedImageView后面,自然会显示在图片上方。
- 但从Android 5.0开始,系统对同一父容器下的视图,新增了基于elevation值的层级排序规则:只要两个视图的elevation值存在差异,系统会优先按照elevation的高低决定绘制先后,完全覆盖XML的声明顺序。elevation值更高的视图,会被判定为上层元素,哪怕它在XML里是最先声明的。
你写的两个TextView没有配置elevation属性,默认值是0dp,远低于RoundedImageView的8dp。实际运行时系统会把RoundedImageView放在更上层绘制,直接把两个TextView完全遮挡,就出现了设置完动态数据后TextView“消失”的效果。
修复方案
- 如果你不需要给ImageView加悬浮阴影,直接删掉RoundedImageView上的
android:elevation="8dp"属性即可解决。这种情况下所有子View的elevation都是默认0值,系统会回到FrameLayout默认的顺序绘制逻辑,让后声明的TextView自然叠在图片上方。如果确实需要阴影效果,可以改用自定义背景drawable的方式实现,不依赖elevation属性触发。 - 如果你必须保留RoundedImageView的elevation悬浮效果,只需要给两个叠在图片上的TextView配置一个比8dp更高的elevation值即可,比如给TextView加上属性:
只要TextView的elevation值高于下方的ImageView,就会被系统判定为上层元素,正常显示在图片上面。android:elevation="10dp"
额外提醒:布局预览页对elevation的层级渲染和实际运行时的系统行为存在偏差,很多时候不会模拟高elevation视图遮挡低elevation同层元素的效果,这也是为什么你在预览阶段完全没提前发现这个问题。
内容的提问来源于stack exchange,提问作者james04
相关产品推荐
相关产品推荐

