您好,登錄后才能下訂單哦!
Android橫豎屏要解決的問題應該就兩個:
一.布局問題
二.重新載入問題
1.布局問題:如果不想讓軟件在橫豎屏之間切換,最簡單的辦法就是在項目的AndroidManifest.xml中找到你所指定的activity中加上android:screenOrientation屬性,他有以下幾個參數:
"unspecified":默認值 由系統來判斷顯示方向.判定的策略是和設備相關的,所以不同的設備會有不同的顯示方向.
"landscape":橫屏顯示(寬比高要長)
"portrait":豎屏顯示(高比寬要長)
"user":用戶當前首選的方向
"behind":和該Activity下面的那個Activity的方向一致(在Activity堆棧中的)
"sensor":有物理的感應器來決定。如果用戶旋轉設備這屏幕會橫豎屏切換。
"nosensor":忽略物理感應器,這樣就不會隨著用戶旋轉設備而更改了("unspecified"設置除外)。
也可以在Java代碼中通過setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)來設置。
如果要讓軟件在橫豎屏之間切換,由于橫豎屏的高寬會發生轉換,有可能會要求不同的布局。可以通過以下方法來切換布局:
1)在res目錄下建立layout-land和layout-port目錄,相應的layout文件不變,比如main.xml。layout-land是橫屏的layout,layout-port是豎屏的layout,其他的不用管,模擬器會自動尋找。
2)通過 this.getResources().getConfiguration().orientation來判斷當前是橫屏還是豎屏然后來加載相應的 xml布局文件。因為當屏幕變為橫屏的時候,系統會重新呼叫當前Activity的onCreate方法,你可以把以下方法放在你的onCreate中來檢查當前的方向,然后可以讓你的setContentView來載入不同的layout xml.
1 | if ( this .getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){ |
2 | Log.i( "info" , "landscape" ); // 橫屏 |
3 | } |
4 | else if ( this .getResources().getConfiguration().orientation ==Configuration.ORIENTATION_PORTRAIT) { |
5 | Log.i( "info" , "portrait" ); // 豎屏 |
6 | } |
在onConfigurationChanged()方法中也可以檢測擁有硬鍵盤的鍵盤狀態
1 | //檢測實體鍵盤的狀態:推出或者合上 |
2 | if (newConfig.hardKeyboardHidden ==Configuration.HARDKEYBOARDHIDDEN_NO){ |
3 | //實體鍵盤處于推出狀態,在此處添加額外的處理代碼 |
4 | } |
5 | else if (newConfig.hardKeyboardHidden ==Configuration.HARDKEYBOARDHIDDEN_YES){ |
6 | //實體鍵盤處于合上狀態,在此處添加額外的處理代碼 |
7 | } |
2.重新載入問題。如果不需要從新載入,可以在AndroidManifest.xml中加入配置 android:configChanges="orientation|keyboardHidden",配置 android:configChanges的作用就是如文檔所說的:Specify one or more configuration changesthat the activity will handle itself. If not specified, the activity will berestarted if any of these configuration changes happen in the system。這樣在程序中Activity就不會重復的調用onCreate()甚至不會調用onPause、onResume.只會調用一個 onConfigurationChanged(Configuration newConfig)。如果需要重新載入,則不需要做任何修改。不過如果需要在重新載入過程中保存之前的操作內容或數據,則需要保存之前的數據。然后在 activity的onCreate()中取出來。當然,如此就不能設置android:configChanges()了,否則就不會調用 onCreate()方法。
如果要徹底禁止翻轉,可以設置android:screenOrientation的屬性為nosensor,如此就可以忽略重力感應帶來的麻煩了。不過在模擬器上不管用,在真機上是正確的。android:screenOrientation="portrait"
則無論手機如何變動,擁有這個屬性的activity都將是豎屏顯示。
android:screenOrientation="landscape",為橫屏顯示。
這里提一個小知識,Android模擬器中,快捷鍵"Ctrl+F11/F12"可以實現轉屏
一、禁止橫豎屏轉換
Android橫豎屏切換在手機開發中比較常見,很多軟件在開發過程中為了避免橫豎屏切換時引發不必要的麻煩,通常禁止掉橫豎屏的切換,
通過在AndroidManifest.xml中設置activity中的android:screenOrientation屬性值來實現。
比如下列設置
android:screenOrientation="portrait"
則無論手機如何變動,擁有這個屬性的activity都將是豎屏顯示。
android:screenOrientation="landscape",為橫屏顯示。
上述修改也可以在Java代碼中通過類似如下代碼來設置
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
另外,android中每次屏幕的切換動會重啟Activity,所以應該在Activity銷毀前保存當前活動的狀態,在Activity再次Create的時候載入配置,那樣,進行中的游戲就不會自動重啟了!
二、橫豎屏切換
如果要讓軟件在橫豎屏之間切換,由于橫豎屏的高寬會發生轉換,有可能會要求不同的布局。可以通過以下兩種方法來切換布局:
1)在res目錄下建立layout-land和layout-port目錄,相應的layout文件名不變,比如main.xml。layout-land是橫屏的layout,layout-port是豎屏的layout,其他的不用管,橫豎屏切換時程序為調用Activity的onCreate方法,從而加載相應的布局。
2)假如布局資源不按照如上設置,則可以通過java代碼來判斷當前是橫屏還是豎屏然后來加載相應的xml布局文件。因為當屏幕變為橫屏的時候,系統會重新呼叫當前Activity的onCreate方法,你可以把以下方法放在你的onCreate中來檢查當前的方向,然后可以讓你的setContentView來載入不同的layout xml。
if(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_LANDSCAPE)
{
Log.i("info", "landscape"); // 橫屏
} elseif(this.getResources().getConfiguration().orientation==Configuration.ORIENTATION_PORTRAIT)
{
Log.i("info", "portrait"); // 豎屏
}
三、通過onConfigurationChanged攔截橫豎屏變換
按照二的操作,Activity每次橫豎屏切換都會重新調用onPause->onStop-> onDestory->onCreate->onStart->onResume,為此涉及到內容和數據的保存和讀取,否則轉屏之前的內容就會消失了。很多時候這樣的結果讓程序繁瑣,為此Android提供了在manifest中設置android:configChanges屬性,從而讓Activity不延續上述的重建流程。在Android工程的Mainfest.xml中配置Activity:android:configChanges="keyboardHidden|orientation",橫豎屏切換之后就不會去執行OnCreat函數了,而是會去調用onConfigurationChanged()這樣就能控制橫豎屏的切換了。用戶可以在Activity或View的onConfigurationChanged(ConfigurationnewConfig)函數中獲取當前橫豎屏參數。至于其調用順序跟touch時間的傳遞順序相似,不過他沒有消費事件的概念,會順次調用到每一個onConfigurationChanged函數。
需要重寫Activity的onConfigurationChanged方法。實現方式如下,不需要做太多的內容:
@Override
public voidonConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if(this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_LANDSCAPE) {
// land donothing is ok
} else if(this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_PORTRAIT) {
// port donothing is ok
}
}
需要注意的是,onConfigurationChanged函數中只能獲得橫豎屏切換后的參數,在該函數中獲取不到新的Layout和控件的尺寸位置信息,如果要處理尺寸和位置信息,必須通過消息異步或者延時調用。
四、徹底禁止翻轉
當然如果要徹底禁止翻轉,可以設置android:screenOrientation的屬性為nosensor,如此就可以忽略重力感應帶來的麻煩了。不過在模擬器上不管用,在真機上是正確的。
這里提一個小知識,Android模擬器中,快捷鍵"Ctrl+F11/F12"可以實現轉屏
五,自適應轉換
如果想讓它啟動的時候是橫屏的話就橫屏表示,縱屏的話就縱屏表示,然后手機切換橫豎屏就不能用了該怎么解決呢?
首先:在Mainfest.xml中追加
android:screenOrientation="sensor"android:configChanges="orientation|keyboardHidden"
這兩個屬性。
第二步:取得屏幕的長和寬,進行比較設置橫豎屏的變量。
1. Display display = getWindowManager().getDefaultDisplay();
2. int width = display.getWidth();
3. int height = display.getHeight();
4. if (width > height) {
5. orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; //橫屏
6. } else {
7. orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT; //豎屏
8. }
第三步:在onConfigurationChanged()函數中追加this.setRequestedOrientation(orientation)就行了
1. public void onConfigurationChanged(Configuration newConfig) {
2. super.onConfigurationChanged(newConfig);
3. this.setRequestedOrientation(orientation);
4. }
但是這樣的話你切到別的畫面的時候再回到原畫面,它就仍然是橫的或者是縱的。怎么讓它從別的屏幕回來后,又重新橫豎屏布局呢?
只要在OnResume()中在設定下就行了。但是這個只支持橫豎屏只有一個layout的。橫豎屏分別對應layout的還不知道該怎么解決。
1. protected void onResume() {
2. orientation = ActivityInfo.SCREEN_ORIENTATION_USER;
3. this.setRequestedOrientation(orientation);
4. Display display = getWindowManager().getDefaultDisplay();
5. int width = display.getWidth();
6. int height = display.getHeight();
7. if (width > height) {
8. orientation = ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
9. } else {
10. orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
11. }
12. super.onResume();
13.}
六、總結
總之,對于橫豎屏切換的問題,統計了下,大家的解決辦法是:
①不理會。。
②只豎屏顯示(android:screenOrientation="portrait")
只橫屏顯示(android:screenOrientation="landscape")
③簡單的防止重載:
在 AndroidManifest.xml中加入:android:configChanges="orientation|keyboardHidden"
在activity中重載onConfigurationChanged事件
@Override
publicvoid onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
}
④橫豎屏分別布局
橫豎屏分別布局的方法是:
在res下新建
layout-land 橫屏
layout-port 豎屏
然后把layout中的xml文件分別考到以上目錄,修改布局就可以了代碼中不做任何更改。
在 AndroidManifest.xml文件中的主Activity中加入
android:configChanges="orientation|keyboardHidden"
然后在主Activity中的onConfigurationChanged加入
@Override
public void onConfigurationChanged(Configuration config) {
super.onConfigurationChanged(config);
if (config.orientation == Configuration.ORIENTATION_PORTRAIT){
setContentView(R.layout.main); //布局
tv = (TextView) findViewById(R.id.EditText01);//控件
}
if (config.orientation == Configuration.ORIENTATION_LANDSCAPE){
setContentView(R.layout.main); //布局
tv = (TextView) findViewById(R.id.EditText01);//控件
}
}
七、示例詳細步驟
//------ 第一步:獲得許可
需要在中添加相應許可
//------ 第二步:根據不同的目標,針對Activity進行設置
目標1:屏蔽橫豎屏的切換
步驟:為Activity設置一個默認的屏幕方向方法如下:
在AndroidManifest.xml中找到該Activity 添加代碼:
android:name=".ActivityName"
android:screenOrientation="landscape"
>
設置Activity的默認方向為“橫向”
此處的screenOrientation有如下選項:
==================================================================
= unspecified 默認值,由系統判斷狀態自動切換
= landscape 橫屏
= portrait 豎屏
=user 用戶當前設置的orientation值
= behind 下一個要顯示的Activity的orientation值
= sensor 使用傳感器 傳感器的方向
= nosensor 不使用傳感器 基本等同于unspecified
==================================================================
目標2:防止Activity的銷毀
步驟:為Activity設置configChanges屬性
在AndroidManifest.xml中找到該Activity 添加代碼:
android:name=".ActivityName"
android:configChanges="orientation|keyboardHidden"
>
此處的configChanges有如下選項:
==================================================================
= orientation 屏幕在縱向和橫向間旋轉
= keyboardHidden 鍵盤顯示或隱藏
= fontScale 用戶變更了首選的字體大小
= locale 用戶選擇了不同的語言設定
= keyboard 鍵盤類型變更,例如手機從12鍵盤切換到全鍵盤
= touchscreen或navigation 鍵盤或導航方式變化,一般不會發生這樣的事件
==================================================================
如果需要多個選項用"|"隔開
此處注意:如果是在實體機上測試橫豎屏切換需要orientation選項
【重點】如果要使得程序可以在Android模擬器上測試需要寫orientation|keyboardHidden
如果缺少了keyboardHidden選項不能防止Activity的銷毀
并且在之后提到的onConfigurationChanged事件中只能捕獲豎屏變橫屏的事件 不能捕獲橫屏變豎屏
目標3:捕獲橫豎屏切換的事件
步驟:在Activity中(ActivityName.java)重寫onConfigurationChanged事件
@Override
public void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
switch (newConfig.orientation)
{
//更改為LANDSCAPE
case (Configuration.ORIENTATION_LANDSCAPE):
//如果轉換為橫向屏時,有要做的事,請寫在這里
break;
//更改為PORTRAIT
case (Configuration.ORIENTATION_PORTRAIT):
//如果轉換為豎向屏時,有要做的事,請寫在這里
break;
}
}
八、備注:
1、不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行兩次
2、設置Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次
3、設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,只會執行onConfigurationChanged方法
一:不同的layout
Android手機屏幕大小不一,有480x320, 640x360, 800x480.怎樣才能讓App自動適應不同的屏幕呢?
其實很簡單,只需要在res目錄下創建不同的layout文件夾,比如layout-640x360,layout-800x480,所有的layout文件在編譯之后都會寫入R.Java里,而系統會根據屏幕的大小自己選擇合適的layout進行使用。
二:hdpi、mdpi、ldpi
在之前的版本中,只有一個drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三個,這三個主要是為了支持多分辨率。
drawable- hdpi、drawable- mdpi、drawable-ldpi的區別:
(1)drawable-hdpi里面存放高分辨率的圖片,如WVGA (480x800),FWVGA (480x854)
(2)drawable-mdpi里面存放中等分辨率的圖片,如HVGA (320x480)
(3)drawable-ldpi里面存放低分辨率的圖片,如QVGA (240x320)
系統會根據機器的分辨率來分別到這幾個文件夾里面去找對應的圖片。
三:橫屏豎屏
在開發程序時為了兼容不同平臺不同屏幕,建議各自文件夾根據需求均存放不同版本圖片。以下步驟是網上流傳的,不過我自己之前是通過圖形化界面實現這個配置,算是殊途同歸,有空我會把圖片貼上來。
還要說明一點:每個activity都有這個屬性screenOrientation,每個activity都需要設置,可以設置為豎屏(portrait),也可以設置為無重力感應(nosensor)。
要讓程序界面保持一個方向,不隨手機方向轉動而變化的處理辦法:
在AndroidManifest.xml里面配置一下就可以了。加入這一行
android:screenOrientation="landscape"
例如(landscape是橫向,portrait是縱向):
Java代碼:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.ray.linkit"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".GamePlay"
android:screenOrientation="portrait"></activity>
<activity android:name=".OptionView"
android:screenOrientation="portrait"></activity>
</application>
<uses-sdk android:minSdkVersion="3" />
</manifest>
另外,android中每次屏幕的切換動會重啟Activity,所以應該在Activity銷毀前保存當前活動的狀態,在Activity再次Create的時候載入配置,那樣,進行中的游戲就不會自動重啟了!
有的程序適合從豎屏切換到橫屏,或者反過來,這個時候怎么辦呢?可以在配置Activity的地方進行如下的配置android:screenOrientation="portrait"。這樣就可以保證是豎屏總是豎屏了,或者landscape橫向。
而有的程序是適合橫豎屏切換的。如何處理呢?首先要在配置Activity的時候進行如下的配置:android:configChanges="keyboardHidden|orientation",另外需要重寫Activity的onConfigurationChanged方法。實現方式如下,不需要做太多的內容:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
// land do nothing is ok
} else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
// port do nothing is ok
}
}
1.
總體來說有兩種方案:
1.Android系統自動切換
利用Android系統每次屏幕切換會重啟Activity的特性,在OnCreat處自動加載不同顯示狀態下的layout。
例:main.xml是豎屏狀態下的layout,文件保存于res/layout文件夾中。為實現橫屏切換,建立文件夾res/layout-land,在里面創建新的界面文件main.xml,與res/layout文件夾中文件同名。則當設備由豎屏切換到橫屏,或者反之時,在onCreate()函數中直接執行setContentView(R.layout.main)即可自動加載不同的界面文件。
另外,在res/layout-land中建立同名文件是用系統自動判斷加載,也可以手動判斷加載。如在res/layout文件夾中有豎屏界面main-P.xml及橫屏界面main-L.xml,則可以在onCreate()函數中通過判斷橫豎屏狀態以顯式加載不同界面,代碼:
int mCurrentOrientation =getResources().getConfiguration().orientation;
if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ){
// If current screen isportrait
setContentView(R.layout.main-P);
} else if ( mCurrentOrientation ==Configuration.ORIENTATION_LANDSCAPE ) {
//If current screen islandscape
setContentView(R.layout.main-L);
}
由于android系統屏幕切換會重啟Activity,所以應該在Activity銷毀前保存當前活動的狀態,在Activity再次Create的時候載入配置。
2.利用Activity的onConfigurationChanged()方法手動切換
為避免Android系統自動重啟activity,需要在Androidmanifest.xml中相應Activity加上android:configChanges="keyboardHidden|orientation"屬性,使相應的Activity不重啟而是調用onConfigurationChanged(ConfigurationnewConfig)。
例:res/layout下有豎屏界面main-P.xml及橫屏界面main-L.xml。onCreate()時同理判斷以顯示不同的界面:
@Override
protectedvoid onCreate(Bundle icicle) {
super.onCreate(icicle);
int mCurrentOrientation =getResources().getConfiguration().orientation;
if ( mCurrentOrientation ==Configuration.ORIENTATION_PORTRAIT ) {
// Ifcurrent screen is portrait
setContentView(R.layout.main-P);
} else if ( mCurrentOrientation ==Configuration.ORIENTATION_LANDSCAPE ) {
//Ifcurrent screen is landscape
setContentView(R.layout.main-L);
}
init();//初始化,賦值等操作
findViews();//獲得控件
setListensers();//設置控件的各種監聽方法
}
重載onConfigurationChanged():
@Override
publicvoid onConfigurationChanged (Configuration newConfig){
super.onConfigurationChanged(newConfig);
int mCurrentOrientation =getResources().getConfiguration().orientation;
if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ){
// If current screen isportrait
setContentView(R.layout.main-P);
//注意,這里刪除了init(),否則又初始化了,狀態就丟失
findViews();
setListensers();
} else if ( mCurrentOrientation ==Configuration.ORIENTATION_LANDSCAPE ) {
//If current screen islandscape
setContentView(R.layout.main-L);
//注意,這里刪除了init(),否則又初始化了,狀態就丟失
findViews();
setListensers();
}
}
以上代碼中需要注意init()函數,若需要保存其它的狀態,如Button及各種View的顯示文字已經改變,在setListensers()務必進行恢復操作。
同樣,也可以使用res/layout/main.xml和res/layout-land/main.xml方式,則不需判斷,直接使用setContentView(R.layout.main)即可。看代碼:
@Override
protectedvoid onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
init();//初始化,賦值等操作
findViews();//獲得控件
setListensers();//設置控件的各種監聽方法
}
重載onConfigurationChanged():
@Override
publicvoid onConfigurationChanged (Configuration newConfig){
super.onConfigurationChanged(newConfig);
int mCurrentOrientation =getResources().getConfiguration().orientation;
if ( mCurrentOrientation == Configuration.ORIENTATION_PORTRAIT ){
// If current screen isportrait
setContentView(R.layout.main);
//注意,這里刪除了init(),否則又初始化了,狀態就丟失
findViews();
setListensers();
} else if ( mCurrentOrientation ==Configuration.ORIENTATION_LANDSCAPE ) {
//If current screen islandscape
setContentView(R.layout.main);
//注意,這里刪除了init(),否則又初始化了,狀態就丟失
findViews();
setListensers();
}
}
其實在這種模式下,由于Android系統自動尋找不同界面文件,而Androidmanifest.xml中已定義了android:configChanges="keyboardHidden|orientation"只監聽方向改變,因此onConfigurationChanged()方法還可以繼續精簡(除非在橫豎屏下狀態不同),直接設置界面、恢復狀態即可:
@Override
publicvoid onConfigurationChanged (Configuration newConfig){
super.onConfigurationChanged(newConfig);
setContentView(R.layout.main);
//注意,這里刪除了init(),否則又初始化了,狀態就丟失
findViews();
setListensers();
}
體驗新版博客
http://lishao378.blog.sohu.com/165342431.html
2.
橫豎屏切換的響應
如果沒有設置強制橫屏或者豎屏那么每次橫豎屏切換的時候Activity都會被重新創建一次,這樣就會存在一個問題橫屏后會把圖片拉伸可能在豎屏時感覺很協調的界面切換到橫屏以后會被拉伸的很難看,比較好的解決辦法是為橫豎屏做兩套圖做兩個布局文件,這樣子程序中只需要監聽屏幕切換的結果設置不同的布局 繪制不同的圖片即可。
AndroidManifest.xml 中設置屬性禁止重新創建Activity,并且添加屏幕切換監聽。
<activity android:name=".HandlerActivity"android:configChanges="orientation|keyboardHidden"/>
復制代碼
設置后屏幕切換后就不會再次調用OnCreate()方法重新創建這個Activity,切換屏幕之前程序中的一些數據或者內容就不會因為重新創建Activity導致重置清空。每當切換橫豎屏的時候系統會自己調用onConfigurationChanged()方法這樣子就可以拿到當前屏幕的橫豎屏狀態,根據狀態就可以做我們想做的事。
import android.app.Activity;
import android.content.res.Configuration;
import android.os.Bundle;
public class HandlerActivity extends Activity {
@Override
protected voidonCreate(Bundle savedInstanceState) {
setContentView(R.layout.handler);
super.onCreate(savedInstanceState);
}
@Override
public voidonConfigurationChanged(Configuration newConfig) {
int type =this.getResources().getConfiguration().orientation;
if (type ==Configuration.ORIENTATION_LANDSCAPE) {
//切換到了橫屏
} else if(type == Configuration.ORIENTATION_PORTRAIT) {
//切換到了豎屏
}
super.onConfigurationChanged(newConfig);
}
}
http://dev.10086.cn/cmdn/bbs/thread-61127-1-1.html
3.一:不同的layout
Android手機屏幕大小不一,有480x320,640x360, 800x480.怎樣才能讓App自動適應不同的屏幕呢?
其實很簡單,只需要在res目錄下創建不同的layout文件夾,比如layout-640x360,layout-800x480,所有的layout文件在編譯之后都會寫入R.Java里,而系統會根據屏幕的大小自己選擇合適的layout進行使用。
二:hdpi、mdpi、ldpi
在之前的版本中,只有一個drawable,而2.1版本中有drawable-mdpi、drawable-ldpi、drawable-hdpi三個,這三個主要是為了支持多分辨率。
drawable- hdpi、drawable- mdpi、drawable-ldpi的區別:
(1)drawable-hdpi里面存放高分辨率的圖片,如WVGA (480x800),FWVGA (480x854)
(2)drawable-mdpi里面存放中等分辨率的圖片,如HVGA (320x480)
(3)drawable-ldpi里面存放低分辨率的圖片,如QVGA (240x320)
系統會根據機器的分辨率來分別到這幾個文件夾里面去找對應的圖片。
三:橫屏豎屏
在開發程序時為了兼容不同平臺不同屏幕,建議各自文件夾根據需求均存放不同版本圖片。以下步驟是網上流傳的,不過我自己之前是通過圖形化界面實現這個配置,算是殊途同歸,有空我會把圖片貼上來。
還要說明一點:每個activity都有這個屬性screenOrientation,每個activity都需要設置,可以設置為豎屏(portrait),也可以設置為無重力感應(nosensor)。
要讓程序界面保持一個方向,不隨手機方向轉動而變化的處理辦法:
在AndroidManifest.xml里面配置一下就可以了。加入這一行
android:screenOrientation="landscape"
例如(landscape是橫向,portrait是縱向):
Java代碼:
<?xml version="1.0"encoding="utf-8"?>
<manifestxmlns:android="http://schemas.android.com/apk/res/android"
package="com.ray.linkit"
android:versionCode="1"
android:versionName="1.0">
<applicationandroid:icon="@drawable/icon"android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<actionandroid:name="android.intent.action.MAIN"/>
<categoryandroid:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activityandroid:name=".GamePlay"
android:screenOrientation="portrait"></activity>
<activityandroid:name=".OptionView"
android:screenOrientation="portrait"></activity>
</application>
<uses-sdkandroid:minSdkVersion="3" />
</manifest>
另外,android中每次屏幕的切換動會重啟Activity,所以應該在Activity銷毀前保存當前活動的狀態,在Activity再次Create的時候載入配置,那樣,進行中的游戲就不會自動重啟了!
有的程序適合從豎屏切換到橫屏,或者反過來,這個時候怎么辦呢?可以在配置Activity的地方進行如下的配置android:screenOrientation="portrait"。這樣就可以保證是豎屏總是豎屏了,或者landscape橫向。
而有的程序是適合橫豎屏切換的。如何處理呢?首先要在配置Activity的時候進行如下的配置:android:configChanges="keyboardHidden|orientation",另外需要重寫Activity的onConfigurationChanged方法。實現方式如下,不需要做太多的內容:
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
if (this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_LANDSCAPE) {
// land do nothing is ok
} else if (this.getResources().getConfiguration().orientation== Configuration.ORIENTATION_PORTRAIT) {
// port do nothing is ok
}
}
http://www.3gtarena.com/danapeixunjishu/androidpeixun/471.html
Android橫豎屏要解決的問題應該就兩個:一。布局問題;二。重新載入問題。
1.布局問題:如果不想讓軟件在橫豎屏之間切換,最簡單的辦法就是在項目的 AndroidManifest.xml中找到你所指定的activity中加上android:screenOrientation屬性,他有以下幾個參數:
"unspecified"
默認值 由系統來判斷顯示方向.判定的策略是和設備相關的,所以不同的設備會有不同的顯示方向.
"landscape"
橫屏顯示(寬比高要長)
"portrait"
豎屏顯示(高比寬要長)
"user"
用戶當前首選的方向
"behind"
和該Activity下面的那個Activity的方向一致(在Activity堆棧中的)
"sensor"
有物理的感應器來決定。如果用戶旋轉設備這屏幕會橫豎屏切換。
"nosensor"
忽略物理感應器,這樣就不會隨著用戶旋轉設備而更改了 ( "unspecified"設置除外 )。
也可以在Java代碼中通過setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);來設置。
如果要讓軟件在橫豎屏之間切換,由于橫豎屏的高寬會發生轉換,有可能會要求不同的布局。可以通過以下方法來切換布局:
1)在res目錄下建立layout-land和layout-port目錄,相應的layout文件不變,比如main.xml。layout-land是橫屏的layout,layout-port是豎屏的layout,其他的不用管,模擬器會自動尋找。
2)通過this.getResources().getConfiguration().orientation來判斷當前是橫屏還是豎屏然后來加載相應的xml布局文件。因為當屏幕變為橫屏的時候,系統會重新呼叫當前Activity的OnCreate方法,你可以把以下方法放在你的 OnCreate中來檢查當前的方向,然后可以讓你的SetContentView來載入不同的Layout xml.
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
Log.i("info", "landscape");
}
else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
Log.i("info", "portrait");
}
2.重新載入問題。如果不需要從新載入,可以在androidmanifest.xml中加入配置 android:configChanges="orientation",配置android:configChanges的作用就是如文檔所說的:Specify one or more configuration changes that the activity will handle itself. If not specified, the activity will be restarted if any of these configuration changes happen in the system。這樣在程序中. Activity就不會重復的調用onCreate()甚至不會調用onPause.onResume.只會調用一個 onConfigurationChanged(Configuration newConfig)。
–*************其實在這里我遇到兩個奇怪的問題,那就是
1.如果我在android:configChanges中只設置orientation,他依然會重新加載,只有設置了 orientation|keyboardHidden它才會只調用一個onConfigurationChanged(Configuration newConfig)
2.當橫屏變豎屏的時候,他會調用兩次onConfigurationChanged,而豎屏轉橫屏時他只調用一次onConfigurationChanged,真是太奇怪了。如果你知道,歡迎留言共同探討*************–
如果需要重新載入,則不需要做任何修改。不過如果需要在重新載入過程中保存之前的操作內容或數據,則需要保存之前的數據。然后在activity的 onCreate()中取出來。當然,如此就不能設置android:configChanges()了,否則就不會調用onCreate()方法。那么數據可以保存在哪呢?Android中四種存儲方法都可以,另外,還可以用Android為我們提供了 onRetainNonConfigurationInstance()方法來暫時保存數據。
下面為此舉個例子:
保存臨時圖片:
1. @Override
2. public Object onRetainNonConfigurationInstance() {
3. final LoadedPhoto[] list = new LoadedPhoto[numberOfPhotos];
4. keepPhotos(list);
5. return list;
6. }
之后便可以在activity的onCreate()函數中實現重新調用臨時文件,在代碼中需要判斷系統是否需要重新加載臨時文件。以下是放在OnCreate()函數中加載臨時文件的代碼:
1. private void loadPhotos() {
2. final Object data = getLastNonConfigurationInstance();
3.
4. // The activity is starting for the first time, load the photos from Flickr
5. if (data == null) {
6. mTask = new GetPhotoListTask().execute(mCurrentPage);
7. } else {
8. // The activity was destroyed/created automatically, populate the grid
9. // of photos with the p_w_picpaths loaded by the previous activity
10. final LoadedPhoto[] photos = (LoadedPhoto[]) data;
11. for (LoadedPhoto photo : photos) {
12. addPhoto(photo);
13. }
14. }
15. }
對于大多數的情況并不需要做如上的操作,所以需要謹慎使用這個行文,畢竟最好的行為也并不適用于所有情況,如果應用的不好反而會給程序帶來不必要的麻煩。
如果要徹底禁止翻轉,可以設置android:screenOrientation的屬性為nosensor,如此就可以忽略重力感應帶來的麻煩了。不過不知道為什么,在模擬器上不管用,聽別人說在真機上是正確的,我沒有真機,等有了真機再試試看。
Android模擬器橫屏切換方法
如果android模擬器已經啟動后,可以使用快捷鍵F12或Ctrl+F11來切換。當然是用命令行僅僅啟動模擬器可以使用參數emulator.exe -skinHVGA-L 來啟動。
需要注意的是,程序會重載onCreate,避免的方法可通過androidmanifest.xml文件中重新定義方向,以及根據Activity的重寫onConfigurationChanged(Configuration newConfig)方法來控制。
Activity 的 ConfigChanges 屬性
官方解釋: 通過設置這個屬性可以使Activity捕捉設備狀態變化,以下是可以被識別的內容:
CONFIG_FONT_SCALE CONFIG_MCC CONFIG_MNC CONFIG_LOCALE CONFIG_TOUCHSCREEN CONFIG_KEYBOARD CONFIG_NAVIGATION CONFIG_ORIENTATION
設置方法:將下列字段用“|”符號分隔開,例如:“locale|navigation|orientation”
Value
Description
“mcc“
The IMSI mobile country code (MCC) has changed — that is, a SIM hasbeen detected and updated the MCC.移動國家號碼,由三位數字組成,每個國家都有自己獨立的MCC,可以識別手機用戶所屬國家。
“mnc“
The IMSI mobile network code (MNC) has changed — that is, a SIM hasbeen detected and updated the MNC.移動網號,在一個國家或者地區中,用于區分手機用戶的服務商。
“locale“
The locale has changed — for example, the user has selected a new language that text should be displayed in.用戶所在地區發生變化。
“touchscreen“
The touchscreen has changed. (This should never normally happen.)
“keyboard“
The keyboard type has changed — for example, the user has plugged in an external keyboard.鍵盤模式發生變化,例如:用戶接入外部鍵盤輸入。
“keyboardHidden“
The keyboard accessibility has changed — for example, the user has slid the keyboard out to expose it.用戶打開手機硬件鍵盤
“navigation“
The navigation type has changed. (This should never normally happen.)
“orientation“
The screen orientation has changed — that is, the user has rotated the device.設備旋轉,橫向顯示和豎向顯示模式切換。
“fontScale“
The font scaling factor has changed — that is, the user has selected a new global font size.全局字體大小縮放發生改變
1、不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,切橫屏時會執行一次,切豎屏時會執行一次,網上有的說是,切豎屏會執行兩次,我在android2.3的模擬器和2.3手機上都試了,只有一次。但是在android2.2的模擬器上測試了,切豎屏的時候,會執行兩次聲明周期。
2、設置Activity的android:configChanges="orientation"時,切屏還是會重新調用各個生命周期,切橫、豎屏時只會執行一次,而且,切豎屏的時候,最后還會調用onConfigurationChanged 。模擬器會按照以上說的執行,手機的話,不會執行聲明周期,只會執行 onConfigurationChanged
3、設置Activity的android:configChanges="orientation|keyboardHidden"時,切屏不會重新調用各個生命周期,只會執行onConfigurationChanged方法
Android 禁止橫屏豎屏切換模式解析,android 橫屏布局,android 橫屏切換,android 橫屏事件,android 禁止橫屏,對于可能需要禁止橫屏和豎屏模式之間的切換,我們可以在Android 布局中加入相關語句,并間接鎖定 activity 不讓它重啟。
對于可能需要禁止橫屏和豎屏模式之間的切換,我們可以在 AndroidManifest.xml 里面加入這一行
以下為引用內容: android :screenOrientation="landscape "
其中 landscape 是橫向,portrait 是縱向,不過 android 中每次屏幕的切換動會重啟 Activity ,所以應該在 Activity 銷毀前保存當前活動的狀態,在 Activity 再次 Create 的時候載入配置。在 activity 加下面的屬性,將不會重啟 activity :
以下為引用內容: android:configChanges="keyboardHidden|orientation".
而是去調用
以下為引用內容: onConfigurationChanged(Configuration newConfig).
這樣就可以在這個方法里調整顯示方式。
Java 文件代碼
以下為引用內容: @Override public void onConfigurationChanged(Configuration newConfig) { try { super.onConfigurationChanged(newConfig); if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { // land } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { // port } } catch (Exception ex) { } }
http://www.desteps.com/application/mobile/0100216.html
Android 判斷橫屏還是豎屏,并且根據方向改變背景,android 橫屏布局,android 判斷橫屏,android 判斷橫屏豎屏,android 切換背景,android 更換背景。
Android 判斷橫屏還是豎屏
android 判斷橫屏還是豎屏可以使用兩種方式:
1、getSystemService
以下為引用內容: /* First, get the Display from the WindowManager */ Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); /* Now we can retrieve all display-related infos */ int width = display.getWidth(); int height = display.getHeight(); int orientation = display.getOrientation();
2、getWindowManager
以下為引用內容: public int getScreenOrientation(){ Display getOrient = getWindowManager().getDefaultDisplay(); int orientation = getOrient.getOrientation(); // Sometimes you may get undefined orientation Value is 0 // simple logic solves the problem compare the screen // X,Y Co-ordinates and determine the Orientation in such cases if(orientation==Configuration.ORIENTATION_UNDEFINED){ Configuration config = getResources().getConfiguration(); orientation = config.orientation; if(orientation==Configuration.ORIENTATION_UNDEFINED){ //if height and widht of screen are equal then // it is square orientation if(getOrient.getWidth()==getOrient.getHeight()){ orientation = Configuration.ORIENTATION_SQUARE; }else{ //if widht is less than height than it is portrait if(getOrient.getWidth() < getOrient.getHeight()){ orientation = Configuration.ORIENTATION_PORTRAIT; }else{ // if it is not any of the above it will defineitly be landscape orientation = Configuration.ORIENTATION_LANDSCAPE; } } } } return orientation; // return value 1 is portrait and 2 is Landscape Mode }
android 判斷橫屏豎屏并切換背景
以下為引用內容: public static void AutoBackground(Activity activity,View view,int Background_v, int Background_h) { int orient=ScreenOrient(activity); if (orient == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) { view.setBackgroundResource(Background_v); // 縱向 }else{ view.setBackgroundResource(Background_h); // 橫向 } }
其中 Background_v 是縱向時的背景圖,Background_h 為橫向時的背景圖
然后在 activity 的 oncreate 方法中去調用
以下為引用內容: LinearLayout layout=(LinearLayout)findViewById(R.id.layout); androidUtil.AutoBackground(this, layout, R.drawable.bg_v, R.drawable.bg_h); // 背景自適應
Android橫豎屏切換小結
一、禁止橫豎屏切換
Android橫豎屏切換在手機開發中比較常見,很多軟件在開發過程中為了避免橫豎屏切換時引發不必要的麻煩,通常禁止掉橫豎屏的切換,即通過在AndroidManifest.xml中設置activity中的android:screenOrientation屬性值來實現。
該android:screenOrientation屬性,他有以下幾個參數:
"unspecified":默認值 由系統來判斷顯示方向.判定的策略是和設備相關的,所以不同的設備會有不同的顯示方向.
"landscape":橫屏顯示(寬比高要長)
"portrait":豎屏顯示(高比寬要長)
"user":用戶當前首選的方向
"behind":和該Activity下面的那個Activity的方向一致(在Activity堆棧中的)
"sensor":有物理的感應器來決定。如果用戶旋轉設備這屏幕會橫豎屏切換。
"nosensor":忽略物理感應器,這樣就不會隨著用戶旋轉設備而更改了("unspecified"設置除外)。
比如下列設置
android:screenOrientation="portrait"
則無論手機如何變動,擁有這個屬性的activity都將是豎屏顯示。
android:screenOrientation="landscape",為橫屏顯示。
上述修改也可以在Java代碼中通過類似如下代碼來設置
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)
二、橫豎屏切換更改布局
如果要讓軟件在橫豎屏之間切換,由于橫豎屏的高寬會發生轉換,有可能會要求不同的布局。可以通過以下兩種方法來切換布局:
1)在res目錄下建立layout-land和layout-port目錄,相應的layout文件名不變,比如main.xml。layout-land是橫屏的layout,layout-port是豎屏的layout,其他的不用管,橫豎屏切換時程序為調用Activity的onCreate方法,從而加載響應的布局。
2)假如布局資源不按照如上設置,則可以通過java代碼來判斷當前是橫屏還是豎屏然后來加載相應的xml布局文件。因為當屏幕變為橫屏的時候,系統會重新呼叫當前Activity的onCreate方法,你可以把以下方法放在你的onCreate中來檢查當前的方向,然后可以讓你的setContentView來載入不同的layout xml。
if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE){
Log.i("info", "landscape"); // 橫屏
}
else if (this.getResources().getConfiguration().orientation ==Configuration.ORIENTATION_PORTRAIT) {
Log.i("info", "portrait"); // 豎屏
}
三、通過onConfigurationChanged攔截橫豎屏變換
按照二的操作,Activity每次橫豎屏切換都會重新調用onPause-> onStop-> onDestory-> onCreate->onStart->onResume,為此涉及到內容和數據的保存和讀取,否則轉屏之前的內容就會消失了。很多時候這樣的結果讓程序繁瑣,為此Android提供了在manifest中設置android:configChanges屬性,從而讓Activity不延續上述的重建流程。假如用戶關心橫豎屏的切換,可以在Activity或View的onConfigurationChanged(Configuration newConfig)函數中獲取當前橫豎屏參數。至于其調用順序跟touch時間的傳遞順序相似,不過他沒有消費事件的概念,會順次調用到每一個onConfigurationChanged函數。
需要注意的是,onConfigurationChanged函數中只能獲得橫豎屏切換后的參數,在該函數中獲取不到新的Layout和控件的尺寸位置信息,如果要處理尺寸和位置信息,必須通過消息異步或者延時調用,下面是我在項目需要橫豎屏切換時需要重新設置popupWindow位置的代碼:
@Override
protected void onConfigurationChanged(Configuration newConfig) {
// TODO Auto-generated method stub
super.onConfigurationChanged(newConfig);
//View中不用創建Handler,可直接調用post操作
// new Handler().postDelayed(new Runnable() {
// @Override
// public void run() {
// updatePopup();
// }
// }, 500);
postDelayed(new Runnable() {
@Override
public void run() {
updatePopup(); //
}
}, 500);//嘗試過直接使用post操作,在updatePopup函數中也能獲取正確位置
}
至于橫豎屏翻轉時,系統如何讓窗口翻轉并重新繪制,我也沒有具體去細究源碼,所以也不得而知,有了解的可以告知下小弟。
當然如果要徹底禁止翻轉,可以設置android:screenOrientation的屬性為nosensor,如此就可以忽略重力感應帶來的麻煩了。不過在模擬器上不管用,在真機上是正確的。
這里提一個小知識,Android模擬器中,快捷鍵"Ctrl+F11/F12"可以實現轉屏
小結是對網上博文的簡單修改
http://www.open-open.com/lib/view/open1328069449468.html
橫豎屏切換時候Activity的生命周期--常考題目
2012-10-18 14:57:42 我來說兩句 作者:JoeBaby_
收藏 我要投稿
橫豎屏切換時候Activity的生命周期
曾經遇到過一個面試題,讓你寫出橫屏切換豎屏Activity的生命周期。現
在給大家分析一下他切換時具體的生命周期是怎么樣的:
1、新建一個Activity,并把各個生命周期打印出來
2、運行Activity,得到如下信息
onCreate-->
onStart-->
onResume-->
3、按crtl+f12切換成橫屏時
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
4、再按crtl+f12切換成豎屏時,發現打印了兩次相同的log
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
5、修改AndroidManifest.xml,把該Activity添加
android:configChanges="orientation",執行步驟3
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
6、再執行步驟4,發現不會再打印相同信息,但多打印了一行onConfigChanged
onSaveInstanceState-->
onPause-->
onStop-->
onDestroy-->
onCreate-->
onStart-->
onRestoreInstanceState-->
onResume-->
onConfigurationChanged-->
7、把步驟5的android:configChanges="orientation" 改成
android:configChanges="orientation|keyboardHidden",執行步驟3,就只打印
onConfigChanged
onConfigurationChanged-->
8、執行步驟4
onConfigurationChanged-->
onConfigurationChanged-->
總結:
1、不設置Activity的android:configChanges時,切屏會重新調用各個生命周期,
切橫屏時會執行一次,切豎屏時會執行兩次
2、設置Activity的android:configChanges="orientation"時,切屏還是會重新調
用各個生命周期,切橫、豎屏時只會執行一次
3、設置Activity的android:configChanges="orientation|keyboardHidden"時,
切屏不會重新調用各個生命周期,只會執行onConfigurationChanged方法
總結一下整個Activity的生命周期
補充一點,當前Activity產生事件彈出Toast和AlertDialog的時候Activity的生命
周期不會有改變
Activity運行時按下HOME鍵(跟被完全覆蓋是一樣的):onSaveInstanceState -->
onPause --> onStop onRestart -->onStart--->onResume
Activity未被完全覆蓋只是失去焦點:onPause--->onResume
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。