LayoutInflater加载布局后无法通过代码设置ConstraintSet约束问题
解决LayoutInflater加载布局后ConstraintSet约束不生效的问题
我明白你遇到的问题了——直接操作父布局的ConstraintSet去设置嵌套子布局里的按钮约束,肯定不会生效,这里的核心问题是视图层级的关系:
你通过LayoutInflater加载的buttonsLayout是runSessionLayout的子View,而btnQuickLog又是buttonsLayout的子View,它们属于嵌套层级。你现在用runSessionLayout的ConstraintSet去设置btnQuickLog的约束,相当于跨了一层父布局,ConstraintSet无法识别这种跨层级的约束绑定。
下面给你两种针对性的解决方案,根据你的需求选择:
方案一:操作子布局(buttonsLayout)的ConstraintSet(推荐)
如果你的session_buttons_layout根布局本身就是ConstraintLayout,直接针对这个子布局的约束进行修改,这样符合视图层级的逻辑:
LayoutInflater linflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); ConstraintLayout runSessionLayout = findViewById(R.id.runSessionLayout); // 直接强转为ConstraintLayout,因为你的子布局根布局是它 ConstraintLayout buttonsLayout = (ConstraintLayout) linflater.inflate(R.layout.session_buttons_layout, runSessionLayout, false); runSessionLayout.addView(buttonsLayout); // 获取子布局的控件 TextView currentTime = buttonsLayout.findViewById(R.id.currentTime); Button btnQuickLog = buttonsLayout.findViewById(R.id.btnSessionQuickLog); Button btnNormalLog = buttonsLayout.findViewById(R.id.btnSessionNormalLog); Button btnLiveLog = buttonsLayout.findViewById(R.id.btnSessionLiveLog); // 操作子布局的ConstraintSet ConstraintSet set = new ConstraintSet(); set.clone(buttonsLayout); // 让btnQuickLog相对于它的直接父布局(buttonsLayout)靠右对齐 set.connect(btnQuickLog.getId(), ConstraintSet.RIGHT, buttonsLayout.getId(), ConstraintSet.RIGHT, 0); set.applyTo(buttonsLayout);
方案二:将按钮移到父布局中设置约束(不推荐,除非必须)
如果你确实需要让btnQuickLog直接相对于runSessionLayout设置约束,那需要先把按钮从子布局中移除,再添加到父布局里,然后设置约束:
LayoutInflater linflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE); ConstraintLayout runSessionLayout = findViewById(R.id.runSessionLayout); View buttonsLayout = linflater.inflate(R.layout.session_buttons_layout, runSessionLayout, false); runSessionLayout.addView(buttonsLayout); // 获取按钮 Button btnQuickLog = buttonsLayout.findViewById(R.id.btnSessionQuickLog); // 从子布局中移除按钮 ((ViewGroup) btnQuickLog.getParent()).removeView(btnQuickLog); // 将按钮直接添加到父布局 runSessionLayout.addView(btnQuickLog); // 现在可以用父布局的ConstraintSet设置约束了 ConstraintSet set = new ConstraintSet(); set.clone(runSessionLayout); set.connect(btnQuickLog.getId(), ConstraintSet.RIGHT, runSessionLayout.getId(), ConstraintSet.RIGHT, 0); set.applyTo(runSessionLayout);
额外提示
如果你的需求只是让整个buttonsLayout在runSessionLayout中靠右,不需要单独调整里面的按钮,那直接约束buttonsLayout即可:
ConstraintSet set = new ConstraintSet(); set.clone(runSessionLayout); set.connect(buttonsLayout.getId(), ConstraintSet.RIGHT, runSessionLayout.getId(), ConstraintSet.RIGHT, 0); // 可以再加上垂直方向的约束,比如居中 set.connect(buttonsLayout.getId(), ConstraintSet.CENTER_VERTICAL, runSessionLayout.getId(), ConstraintSet.CENTER_VERTICAL, 0); set.applyTo(runSessionLayout);
内容的提问来源于stack exchange,提问作者Norbert
相关产品推荐
相关产品推荐

