Android 橫豎屏切換,約束佈局動態修改約束

首先橫豎屏切換不重建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;視頻

另外四個參數以下:

  • startID:須要設置約束的控件的ID,經過控件View#getId()方法獲取;
  • startSide:要設置哪一個方向的約束,對應xml文件中layout_constraintLeft_toRightOf等屬性下劃線左邊的Left部分;
  • endID:約束參考控件的ID,設置與哪個控件的約束,對應xml文件中layout_constraintLeft_toLeftOf="parent"等屬性的參數;
  • endSide:設置參考控件提供的約束的方向:對應xml文件中layout_constraintLeft_toRightOf等屬性下劃線右邊的Right部分;
相關文章
相關標籤/搜索