如何在Activity不重建、不重复调用API的前提下适配横竖屏不同UI设计
解决方案
核心思路
保留android:configChanges配置阻止Activity重建,方向变更时手动加载对应方向布局,通过成员变量/ViewModel持久化API结果与界面状态,避免重复请求。
具体实现步骤
- 第一步:保留Manifest中的配置不要移除,该配置是阻止Activity重建的核心
android:configChanges="orientation|screenSize|keyboardHidden"
- 第二步:持久化非UI状态与API结果
将API返回的业务数据、用户输入内容、列表滚动位置、适配器数据源等需要保留的内容,定义为Activity的成员变量,或者存到ViewModel中。因为Activity不会重建,这些数据会一直保留,无需重复调用API。
示例:
// 定义为成员变量,存储API返回的业务数据 private List<Goods> mGoodsList; private String mUserInputContent; private int mListScrollPosition;
- 第三步:修改
onConfigurationChanged逻辑,手动加载对应布局并恢复状态
当方向变更触发该回调时,根据新的方向手动调用setContentView加载对应横竖屏布局,之后重新绑定控件,将之前存储的状态回写到新的布局控件上即可。
修改后的示例代码:
@Override public void onConfigurationChanged(@NonNull Configuration newConfig) { super.onConfigurationChanged(newConfig); if (getResources().getBoolean(R.bool.portrait_only)) { setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); return; } // 手动加载对应方向布局,系统会自动匹配对应orientation资源目录下的同名布局 setContentView(R.layout.activity_your_page); // 重新绑定当前布局的控件 initView(); // 恢复之前存储的状态,无需重新调用API restorePageState(); } // 示例:恢复页面状态 private void restorePageState() { etInput.setText(mUserInputContent); goodsAdapter.setData(mGoodsList); rvGoods.scrollToPosition(mListScrollPosition); }
优化建议
如果项目引入了Jetpack ViewModel组件,建议将所有业务数据、页面状态都存储到ViewModel中,后续即使有其他配置变更导致Activity重建,也能自动恢复数据,无需额外处理存储逻辑。
内容的提问来源于stack exchange,提问作者Malhotra
相关产品推荐
相关产品推荐

