首先橫豎屏切換不重建Activity的問題: 修改manifest文件將不但願重建的Activity標籤添加以下設置android
android:configChanges="orientation|keyboardHidden|screenSize"
複製代碼
這樣在屏幕旋轉的時候Activity就不會重建了。bash
若是橫豎屏佈局相同的狀況下,到此爲止便可。app
固然,通常狀況下橫豎屏的佈局確定要根據屏幕進行調整的。使用多佈局文件來適配橫屏和豎屏的方法,其餘文章有介紹,這裏就不記錄了。ide
自從開始用了ConstraintLayout佈局以後,就不多再用LinearLayout,RelativeLayout等舊的方法,實在是約束佈局用起來太方便了,佈局層級能夠很是容易的保次比較低的狀態,甚至不少時候就只有一層。佈局
今天在作視頻播放頁面的時候要對橫豎屏適配,其中有控制部分,須要動態設置控件間的依賴關係。 首先,既然要根據橫豎屏來從新設置新的約束關係,就須要重寫Activity的onConfigurationChanged方法,判斷目標屏幕狀態,並根據該狀態對約束進行相應的調整測試
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
int mCurrentOrientation = getResources().getConfiguration().orientation;
//豎屏
if (mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT) {
changeToPortraitLayout();
} else {
changeToLandscapeLayout();
}
}
複製代碼
/**
* 動態設置豎屏狀態下佈局約束
*/
private void changeToPortraitLayout() {
ConstraintSet cs = new ConstraintSet();
//獲取當前目標控件的約束集合
cs.clone(clRootContainer);
//修改surfaceView約束
//清除約束
cs.clear(surfaceView.getId());
cs.connect(surfaceView.getId(), ConstraintSet.LEFT, clRootContainer.getId(), ConstraintSet.LEFT);
cs.connect(surfaceView.getId(), ConstraintSet.TOP, findViewById(R.id.topTitle).getId(), ConstraintSet.BOTTOM);
cs.connect(surfaceView.getId(), ConstraintSet.RIGHT, clRootContainer.getId(), ConstraintSet.RIGHT);
cs.connect(surfaceView.getId(), ConstraintSet.BOTTOM, findViewById(R.id.guideCenter).getId(), ConstraintSet.TOP);
//修改控制切換按鈕的約束,這裏不能調用cs的clear方法清除約束,否者沒法正常顯示該控件
cs.connect(rgRobotControl.getId(), ConstraintSet.LEFT, clRootContainer.getId(), ConstraintSet.LEFT);
cs.connect(rgRobotControl.getId(), ConstraintSet.TOP, findViewById(R.id.guideCenter).getId(), ConstraintSet.BOTTOM);
cs.connect(rgRobotControl.getId(), ConstraintSet.RIGHT, clRootContainer.getId(), ConstraintSet.RIGHT);
//修改控制Fragment的約束
cs.clear(controlContainer.getId());
cs.connect(controlContainer.getId(), ConstraintSet.TOP, rgRobotControl.getId(), ConstraintSet.BOTTOM);
cs.connect(controlContainer.getId(), ConstraintSet.LEFT, rgRobotControl.getId(), ConstraintSet.LEFT);
cs.connect(controlContainer.getId(), ConstraintSet.RIGHT, rgRobotControl.getId(), ConstraintSet.RIGHT);
cs.connect(controlContainer.getId(), ConstraintSet.BOTTOM, clRootContainer.getId(), ConstraintSet.BOTTOM);
//將修改過的約束從新應用到ConstrainLayout
cs.applyTo(clRootContainer);
}
複製代碼
其中,必須先clone目標ConstraintLayout的約束,在現有約束上修改,否者新的約束會覆蓋已有約束。 通過測試,若是其中一個方向上的約束沒有顯示設置,就不能調用clear方法清除舊的約束,我這裏出現了控件沒法顯示的現象;ui
changeToLandscapeLayout方法和changeToPortraitLayout方法實現類似;spa
關於ConstraintSet的connect方法:code
connect方法有兩個重載方法,分別有四個參數和五個參數(多一個margin參數);多的那個參數可讓咱們設置該方向的margin;視頻
另外四個參數以下: