2010年11月16日 星期二

[Android] 關於螢幕方向翻轉 screenOrientation



通常在螢幕方向改變的時候 , 我們的Layout佈局應該也要跟著改變 , 才能讓使用者有良好的使用體驗和環境
所以通常我們會built兩個不同的Layout檔案因應螢幕方向的改變 , 而這篇文章要提的就是當使用者更改螢幕方向的時候時(橫轉直 , 直轉橫) , 該怎麼載入適當的Layout佈局?




Android 很貼心的幫開發者設計一個方法 , 在原本的res/資料夾下再建立兩個資料夾 , 名稱分別是layout-land , layout-port , 這原理和drawable-hdpi , drawable-ldpi....是一樣的 , 而layout-land裡面放置橫螢幕的Layout檔 , layout-port裡面放置直螢幕的Layout檔 , 當我們進入模擬器的時候 , 他就會根據螢幕的方向自動載入合適的Layout檔案 , 另外在模擬器中翻轉螢幕的方法是按下ctrl + F12 , 另外這邊有一個方法可以設定螢幕的方向






關於android:screenOrientation的屬性Android開發網站這邊有提到
但如果我們想根據螢幕的方向不同 , 而在onCreate的時候執行不同的程式碼該怎麼判斷呢? 這時候我們需要知道螢幕到底是直的還是橫的 , 這邊的一個小技巧是使用 this.getResources().getDisplayMetrics(); 來取得DisplayMetrics物件 , 比較螢幕長和寬來判斷螢幕方向 , 避免混淆 , 分別先把兩個layout資料夾移除 , 在原來的res/layout資料夾下 , 建立 landscape_main , portrait_main檔案 , 而程式碼如下

import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;

public class ScreenOrientationTest extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        
        dm = getResources().getDisplayMetrics();
        //取得螢幕顯示的資料
        ScreenWidth = dm.widthPixels;  
        ScreenHeight = dm.heightPixels; 
        //螢幕寬和高的Pixels
        
        if(ScreenHeight > ScreenWidth) setContentView(R.layout.portrait_main);
       
        else setContentView(R.layout.landscape_main);
    }
    
    DisplayMetrics dm;   
    int ScreenWidth , ScreenHeight;
}

這時候就可以根據螢幕方向的情況來執行不同的程式碼了




另外 , 根據Activity的life cycle的資料 , 當螢幕的方向改變和開關實體鍵盤時 , 都會重新執行onCreate()的部分 , 所以當onCreate()裡的程式碼需要initial許多物件的時候 , 翻轉螢幕的動作就會變得相當的耗費資源和拖累執行速度。

為了不讓每次的螢幕翻轉都重新跑一次onCreate() , 我們必須在AndroidManifest.xml裡activity屬性中做宣告 , 完整檔案如下


    
          
            
                
                
            
        
    
 

這麼一來當螢幕的方向改變或是開關實體鍵盤的時候 , activity就不會再執行onCreate()了 , 取而代之的是執行 public void onConfigurationChanged(Configuration newConfig) , 所以我們必須覆寫裡面的內容


import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
import android.util.DisplayMetrics;

public class ScreenOrientationTest extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        
        dm = getResources().getDisplayMetrics();
        //取得螢幕顯示的資料
        ScreenWidth = dm.widthPixels;  
        ScreenHeight = dm.heightPixels; 
        //螢幕寬和高的Pixels
        
        if(ScreenHeight > ScreenWidth) setContentView(R.layout.portrait_main);
       
        else setContentView(R.layout.landscape_main);
    }
    
    DisplayMetrics dm;   
    int ScreenWidth , ScreenHeight;
    int oldOrientation = -1;
    //Configuration.ORIENTATION_LANDSCAPE Constant Value: 2
    //Configuration.ORIENTATION_PORTRAIT Constant Value: 1 
    
    @Override
    public void onConfigurationChanged(Configuration newConfig)
    {
         
     super.onConfigurationChanged(newConfig);
     
     //橫轉直會多跑一次 , 所以加上判斷過濾
     
     if(oldOrientation != newConfig.orientation)
     {
      if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE)
      {
       setContentView(R.layout.landscape_main);
      }             
         else
         {
          setContentView(R.layout.portrait_main);
         }
      oldOrientation = newConfig.orientation;
     }  
    }
}


接著就可以在判斷式內加上自己要的程式碼了!

沒有留言:

張貼留言

Google Analytics