Android開發 設備橫屏與豎屏的詳解


需要了解橫豎屏切換關鍵知識

  1.在Android設備的橫豎屏幕,每一次切換橫豎屏其實是在重新創建Activity,Activity會重新走一遍生命周期.從onCreate 到 onDestroy

  2.在Activity類里的變量也會重新創建,這點需要注意!

判斷屏幕方向,方式一

判斷屏幕是否豎屏

  @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
            L.e("觸發豎屏");
        }
    }

判斷屏幕是否橫屏

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
            L.e("觸發橫屏");
        }
    }

判斷屏幕是否是未知方向

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_UNDEFINED){
            L.e("未定義方向");
        }
    }

判斷屏幕方向,方式二

這個方式其實是監聽activity的配置變化時的回調

 在activity里重寫onConfigurationChanged方法

 @Override
    public void onConfigurationChanged(Configuration newConfig) {
        L.e("newConfig.orientation="+newConfig.orientation);
        if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
            L.e("觸發豎屏");

        }
        if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE){
            L.e("觸發橫屏");
        }
        super.onConfigurationChanged(newConfig);
    }

注意!,這個方法沒想象這么簡單.這個方法回調的條件:   這個方法要求,切換橫豎屏不在重新創建activity,就是activity不會再次onCreate,才會回調這個方法.所以正常情況下,你無法在橫豎屏后觸發這個回調.

為了觸發這個回調,我們需要在AndroidManifest.xml給目標Activity添加屬性 android:configChanges="orientation|screenSize":

<activity android:name=".test.TestActivity"
          android:configChanges="orientation|screenSize"/>

configChanges這個屬性控制着,我們activity在某些情況下是不需要重新創建activity的,這里的不重新創建意味着activity的生命周期將保持不變,不會重新走任何一個生命周期包括onResume.

這里設置方向orientation和尺寸screenSize,就會讓方向與尺寸改變時不會重新創建activity.當然還有以下幾種情況:

  • “mcc“ 移動國家號碼,由三位數字組成,每個國家都有自己獨立的MCC,可以識別手機用戶所屬國家。
  • “mnc“ 移動網號,在一個國家或者地區中,用於區分手機用戶的服務商。
  • “locale“ 所在地區發生變化。
  • “touchscreen“ 觸摸屏已經改變。(這不應該常發生。)
  • “keyboard“ 鍵盤模式發生變化,例如:用戶接入外部鍵盤輸入。
  • “keyboardHidden“ 用戶打開手機硬件鍵盤
  • “navigation“ 導航型發生了變化。(這不應該常發生。)
  • “orientation“ 設備旋轉,橫向顯示和豎向顯示模式切換。
  • “fontScale“ 全局字體大小縮放發生改變

判斷屏幕方向,方式三

 這個方法其實是最強的,因為它是監聽了方向傳感器的值.所以它能監聽獲取任意方向.

 我們只要new一個OrientationEventListener,開啟就行了.注意它不是接口類,是一個抽象類.

private OrientationEventListener mOrientationEventListener;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_test);
        mOrientationEventListener = new OrientationEventListener(this) {            @Override
            public void onOrientationChanged(int orientation) {
                L.e("onOrientationChanged: " + orientation);
                if (orientation > 350 || orientation < 20) { //0度  90 正豎屏

                } else if (orientation > 70 && orientation < 110) { //90度 右橫屏

                } else if (orientation > 160 && orientation < 200) { //180度 倒豎屏

                } else if (orientation > 250 && orientation < 290) { //270度 左橫屏

                }

            }
        };
        if (mOrientationEventListener.canDetectOrientation()) {
            Log.v(TAG, "可以檢測方向");
            mOrientationEventListener.enable();//開啟
        } else {
            Log.v(TAG, "無法檢測方向");
            mOrientationEventListener.disable();
        }

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mOrientationEventListener.disable();//注銷
    }

最后注意,在退出時需要注銷關閉監聽.

另外還有一個更合適在方向監聽上使用的,配置參數 SensorManager.SENSOR_DELAY_NORMAL:

mOrientationEventListener = new OrientationEventListener(this, SensorManager.SENSOR_DELAY_NORMAL) { //
            @Override
            public void onOrientationChanged(int orientation) {
                L.e("onOrientationChanged: " + orientation);
              
            }
        };

SensorManager.SENSOR_DELAY_NORMAL 的意思是,讓傳感器延遲,更適合在方向的監聽使用.所以如果你只需要方向上面的監聽推薦添加這個參數創建OrientationEventListener.

這樣設置延遲的好處是排除一些中間的波動值,返回的值會更加穩定,這樣你可以在判斷方向時,不會出現在邊界值上反反復復切來切去的問題.

設置當前屏幕方向

在AndroidManifest.xml的Activity里設置Activity

 

android:screenOrientation="portrait"

在activity里寫以下任意一個屬性

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);//設置屏幕為橫屏, 設置后會鎖定方向
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//設置屏幕為豎屏, 設置后會鎖定方向
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);//方向未定義, 設置后放棄鎖定方向

注意,這里的鎖定方向意思是指,用戶將無法自己改變這個activity的方向. 包括自動切換屏幕的方向傳感器.

  • SCREEN_ORIENTATION_UNSPECIFIED 方向未指定
  • SCREEN_ORIENTATION_LANDSCAPE 方向橫屏
  • SCREEN_ORIENTATION_PORTRAIT 方向豎屏
  • SCREEN_ORIENTATION_USER 方向用戶
  • SCREEN_ORIENTATION_BEHIND 方向背后
  • SCREEN_ORIENTATION_SENSOR 方向傳感器
  • SCREEN_ORIENTATION_NOSENSOR  方向沒有傳感器
  • SCREEN_ORIENTATION_SENSOR_LANDSCAPE 傳感器橫向
  • SCREEN_ORIENTATION_SENSOR_PORTRAIT 傳感器豎向
  • SCREEN_ORIENTATION_REVERSE_LANDSCAPE 反轉橫向
  • SCREEN_ORIENTATION_REVERSE_PORTRAIT 反轉豎向
  • SCREEN_ORIENTATION_FULL_SENSOR 全傳感器
  • SCREEN_ORIENTATION_USER_LANDSCAPE 用戶橫向
  • SCREEN_ORIENTATION_USER_PORTRAIT 用戶豎向
  • SCREEN_ORIENTATION_FULL_USER 方向用戶
  • SCREEN_ORIENTATION_LOCKED 方向鎖定

 

end


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM