Android布局通过include标签获取内部ImageView引用的方法
核心原因
给<include>标签设置android:id属性时,该id会直接覆盖被引入布局根节点的原有id。你代码中通过R.id.includeID获取到的viewf本身就是目标CoordinatorLayout(原id为theroot_)实例,此时视图树中已经不存在id为theroot_的控件,继续调用findViewById(R.id.theroot_)必然返回null。
可行方案
方案1:直接通过include实例查找目标控件(性能最优,推荐)
跳过查找被覆盖id的根布局步骤,直接在已获取的include根实例上查找目标ImageView即可:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 拿到include对应的根布局(即原id为theroot_的CoordinatorLayout) View includeRoot = view.findViewById(R.id.includeID); // 直接查找目标ImageView AppCompatImageView imageview = (AppCompatImageView) includeRoot.findViewById(R.id.my_image_view); }
方案2:通过tag查找
如果你需要通过tag匹配,注意不要在tag属性中使用@+id/格式赋值(该写法会将id对应的int值作为tag存储,容易出现匹配失败),直接传入字符串tag查找即可:
@Override public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); // 通过include设置的tag找到根布局 View includeRoot = view.findViewWithTag("big_game_card_tag"); // 通过ImageView设置的tag找到目标控件 AppCompatImageView imageview = (AppCompatImageView) includeRoot.findViewWithTag("thegamepiece_"); }
方案3:保留被引入布局根id
如果你需要直接通过theroot_这个id查找根布局,删除<include>标签上的android:id="@+id/includeID"属性即可,此时被引入布局的根id不会被覆盖,原有查找逻辑就能正常运行。但该方案不适合页面中多次引入同一个布局的场景,容易出现id冲突。
性能说明
上述findViewById/findViewWithTag都是同步遍历当前已加载视图树的方法,在onViewCreated生命周期中视图已经完成inflate,调用不会有额外性能损耗,完全不需要使用ViewTreeObserver。
内容的提问来源于stack exchange,提问作者i_o
相关产品推荐
相关产品推荐

