如何无需手动调整宽度,通过ConstraintSet实现ConstraintLayout横竖屏自适应
Android横竖屏布局适配修复方案
问题根源
横屏时contentAct右侧未与广告布局绑定,是因为未清除竖屏模式下contentAct绑定到根布局右侧的旧约束,且没有建立contentAct与广告布局的双向约束关联,导致控件位置逻辑冲突。
修复代码实现
private void applyLandscapeConstraints() { ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(mainAct); // 重置两个控件的所有旧约束,避免横竖屏约束残留 constraintSet.clear(contentAct.getId(), ConstraintSet.ALL); constraintSet.clear(frameLayout_googleads.getId(), ConstraintSet.ALL); // 配置内容区域:填充根布局左/上/下侧,右侧绑定广告布局左侧 constraintSet.connect(contentAct.getId(), ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 0); constraintSet.connect(contentAct.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0); constraintSet.connect(contentAct.getId(), ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0); constraintSet.connect(contentAct.getId(), ConstraintSet.RIGHT, frameLayout_googleads.getId(), ConstraintSet.LEFT, 0); // 让内容区域宽度随约束自动分配(对应布局中的0dp) constraintSet.constrainWidth(contentAct.getId(), ConstraintSet.MATCH_CONSTRAINT); constraintSet.constrainHeight(contentAct.getId(), ConstraintSet.MATCH_CONSTRAINT); // 配置广告区域:填充根布局右/上/下侧,左侧绑定内容区域右侧 constraintSet.connect(frameLayout_googleads.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0); constraintSet.connect(frameLayout_googleads.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0); constraintSet.connect(frameLayout_googleads.getId(), ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0); constraintSet.connect(frameLayout_googleads.getId(), ConstraintSet.LEFT, contentAct.getId(), ConstraintSet.RIGHT, 0); // 固定广告宽度(可根据需求调整尺寸) constraintSet.constrainWidth(frameLayout_googleads.getId(), (int) getResources().getDimension(R.dimen.ad_width)); constraintSet.constrainHeight(frameLayout_googleads.getId(), ConstraintSet.MATCH_CONSTRAINT); constraintSet.applyTo(mainAct); } private void applyPortraitConstraints() { ConstraintSet constraintSet = new ConstraintSet(); constraintSet.clone(mainAct); // 重置所有旧约束 constraintSet.clear(contentAct.getId(), ConstraintSet.ALL); constraintSet.clear(frameLayout_googleads.getId(), ConstraintSet.ALL); // 配置内容区域:填充根布局左/上/右侧,底部绑定广告布局顶部 constraintSet.connect(contentAct.getId(), ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 0); constraintSet.connect(contentAct.getId(), ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0); constraintSet.connect(contentAct.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0); constraintSet.connect(contentAct.getId(), ConstraintSet.BOTTOM, frameLayout_googleads.getId(), ConstraintSet.TOP, 0); constraintSet.constrainWidth(contentAct.getId(), ConstraintSet.MATCH_CONSTRAINT); constraintSet.constrainHeight(contentAct.getId(), ConstraintSet.MATCH_CONSTRAINT); // 配置广告区域:填充根布局左/右/底部,顶部绑定内容区域底部 constraintSet.connect(frameLayout_googleads.getId(), ConstraintSet.LEFT, ConstraintSet.PARENT_ID, ConstraintSet.LEFT, 0); constraintSet.connect(frameLayout_googleads.getId(), ConstraintSet.RIGHT, ConstraintSet.PARENT_ID, ConstraintSet.RIGHT, 0); constraintSet.connect(frameLayout_googleads.getId(), ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0); constraintSet.connect(frameLayout_googleads.getId(), ConstraintSet.TOP, contentAct.getId(), ConstraintSet.BOTTOM, 0); // 固定广告高度(可根据需求调整尺寸) constraintSet.constrainHeight(frameLayout_googleads.getId(), (int) getResources().getDimension(R.dimen.ad_height)); constraintSet.constrainWidth(frameLayout_googleads.getId(), ConstraintSet.MATCH_CONSTRAINT); constraintSet.applyTo(mainAct); }
关键修复说明
- 清除旧约束:切换横竖屏时用
clear()重置控件所有约束,避免旧布局逻辑干扰新配置。 - 自动分配空间:给
contentAct设置MATCH_CONSTRAINT,让ConstraintLayout根据约束自动填充剩余空间,无需手动调整尺寸。 - 双向约束绑定:横屏时同时建立
contentAct右侧与广告左侧、广告左侧与contentAct右侧的关联,确保位置逻辑闭环。 - 固定广告尺寸:根据广告控件要求固定宽/高,保证广告正常展示的同时,让内容区域自适应剩余空间。
内容的提问来源于stack exchange,提问作者MinhNV
相关产品推荐
相关产品推荐

