【移動應(yīng)用開發(fā)技術(shù)】Activity橫豎屏切換_第1頁
【移動應(yīng)用開發(fā)技術(shù)】Activity橫豎屏切換_第2頁
【移動應(yīng)用開發(fā)技術(shù)】Activity橫豎屏切換_第3頁
【移動應(yīng)用開發(fā)技術(shù)】Activity橫豎屏切換_第4頁
【移動應(yīng)用開發(fā)技術(shù)】Activity橫豎屏切換_第5頁
已閱讀5頁,還剩6頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

【移動應(yīng)用開發(fā)技術(shù)】Activity橫豎屏切換

默認(rèn)情況下,當(dāng)“屏幕方向”或“鍵盤顯示隱藏”變化時(shí)都會銷毀當(dāng)前Activity,創(chuàng)建新的Activity。如果不希望重新創(chuàng)建Activity實(shí)例,可以按如下配置Activity:<activityandroid:name=".MainActivity"android:configChanges="keyboardHidden|orientation">注意Android3.2橫豎屏幕切換時(shí)以上配置configChanges要加上screenSize,要不還會調(diào)用onCreate<activityandroid:name=".MainActivity"android:configChanges="orientation|keyboardHidden|screenSize"/>

上面的android:configChanges屬性指定了要捕獲“屏幕方向”和“鍵盤顯示隱藏”變化,當(dāng)捕獲到這些變化后會調(diào)用Activity的onConfigurationChanged()方法。默認(rèn)情況下(沒有配置android:configChanges屬性):豎屏切橫屏,銷毀當(dāng)前Activity之后,創(chuàng)建一個(gè)新Activity實(shí)例。橫屏切豎屏,銷毀當(dāng)前Activity之后,創(chuàng)建一個(gè)新Activity實(shí)例,新的Activity實(shí)例很快就被銷毀,接著又會創(chuàng)建一個(gè)新Activity實(shí)例。如果只希望創(chuàng)建一個(gè)實(shí)例,可以配置android:configChanges="orientation"

<activity

android:screenOrientation="portrait"

//豎屏

android:screenOrientation="landscape"

//橫屏

/>

上述修改也可以在Java代碼中通過類似如下代碼來設(shè)置setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE)android:screenOrientation屬性他有以下幾個(gè)參數(shù):

"unspecified":默認(rèn)值由系統(tǒng)來判斷顯示方向.判定的策略是和設(shè)備相關(guān)的,所以不同的設(shè)備會有不同的顯示方向.

"landscape":橫屏顯示(寬比高要長)

"portrait":豎屏顯示(高比寬要長)

"user":用戶當(dāng)前首選的方向

"behind":和該Activity下面的那個(gè)Activity的方向一致(在Activity堆棧中的)

"sensor":有物理的感應(yīng)器來決定。如果用戶旋轉(zhuǎn)設(shè)備這屏幕會橫豎屏切換。

"nosensor":忽略物理感應(yīng)器,這樣就不會隨著用戶旋轉(zhuǎn)設(shè)備而更改了("unspecified"設(shè)置除外)。APP的橫豎屏切換手動觸發(fā)

由上面描述可知,當(dāng)android:screenOrientation為默認(rèn)值"unspecified"或"sensor"等時(shí),就會有系統(tǒng)根據(jù)設(shè)備的旋轉(zhuǎn)情況來觸發(fā)橫豎屏的切換,那么有沒有方法我們手動在程序中觸發(fā)橫豎屏的變換呢,顯然上面為我們提供的setRequestedOrientation就是系統(tǒng)提供的一個(gè)入口,下面我們給出一個(gè)按鍵的方式來觸發(fā)的案列:

publicclassMainActivityextendsActivityimplementsOnClickListener{

privateButtonmBtnLandscape;

privateButtonmBtnPortrait;

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

mBtnLandscape=(Button)findViewById(R.id.but_landscape);

mBtnPortrait=(Button)findViewById(R.id.but_portrait);

mBtnLandscape.setOnClickListener(this);

mBtnPortrait.setOnClickListener(this);

}

@Override

publicvoidonClick(Viewv){

if(v==mBtnLandscape){

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);

}else{

setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

}

}

@Override

publicvoidonConfigurationChanged(ConfigurationnewConfig){

super.onConfigurationChanged(newConfig);

Stringmessage=newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE?"屏幕設(shè)置為:橫屏":"屏幕設(shè)置為:豎屏";

Toast.makeText(this,message,Toast.LENGTH_LONG).show();

}

}

需要注意的是,手動調(diào)用時(shí),無視AndroidManifest中關(guān)于screenOrientation的設(shè)置;另外上述代碼中的onConfigurationChanged要被調(diào)用到也是需要條件的,在這里,只給代碼,不做討論,后面再給出一個(gè)相關(guān)的補(bǔ)充說明。重啟Activity的橫豎屏切換

在上面的案列中,缺省狀態(tài)下,Activity每次橫豎屏切換(包括用setRequestedOrientation調(diào)用)都會重新調(diào)用一輪onPause->onStop->onDestory->onCreate->onStart->onResume操作,從而銷毀原來的Activity對象,創(chuàng)建新的Activity對象,這是因?yàn)橥ǔG闆r下軟件在橫豎屏之間切換,界面的高寬會發(fā)生轉(zhuǎn)換,從而可能會要求不同的布局。具體的布局切換可以通過如下兩種方法來實(shí)現(xiàn):

1)在res目錄下建立layout-land和layout-port目錄,相應(yīng)的layout文件名不變,比如都為main.xml。layout-land是橫屏的layout,layout-port是豎屏的layout,其他的不用管,橫豎屏切換時(shí)模擬器自動尋找main.xml文件。

2)假如布局資源是不一樣又不按照如上設(shè)置,則需要通過java代碼來判斷當(dāng)前是橫屏還是豎屏然后來加載相應(yīng)的xml布局文件(比如mainP為豎屏mainL為橫屏)。因?yàn)楫?dāng)屏幕變?yōu)闄M屏的時(shí)候,系統(tǒng)會重新呼叫當(dāng)前Activity的onCreate方法,你可以把以下方法放在你的onCreate中來檢查當(dāng)前的方向,然后可以讓你的setContentView來載入不同的layoutxml。

@Override

protectedvoidonCreate(Bundleicicle){

super.onCreate(icicle);

intmCurrentOrientation=getResources().getConfiguration().orientation;

if(mCurrentOrientation==Configuration.ORIENTATION_PORTRAIT){

Log.i("info","portrait");//豎屏

setContentView(R.layout.mainP);

}elseif(mCurrentOrientation==Configuration.ORIENTATION_LANDSCAPE){

Log.i("info","landscape");//橫屏

setContentView(R.layout.mainL);

}

init();//初始化,賦值等操作

findViews();//獲得控件

setListensers();//設(shè)置控件的各種監(jiān)聽方法

}

上面只是對布局切換做了描述,實(shí)際上由于重啟Activity在未加處理的情況下必然導(dǎo)致數(shù)據(jù)的丟失和重新獲取,這樣用戶體驗(yàn)會非常差。為此就要在切換前對數(shù)據(jù)進(jìn)行保存,切換重啟后對數(shù)據(jù)進(jìn)行恢復(fù),具體操作的步驟如下:

重寫Activity.onRetainNonConfigurationInstance(),用戶橫豎屏切換前保存數(shù)據(jù)

@Override

publicObjectonRetainNonConfigurationInstance(){

finalMyDataObjectdata=collectMyLoadedData();

returndata;

}

在onCreate()函數(shù)中調(diào)用getLastNonConfigurationInstance(),獲取onRetainNonConfigurationInstance()保存的數(shù)據(jù)

@Override

publicvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

finalMyDataObjectdata=(MyDataObject)getLastNonConfigurationInstance();

if(data==null){

data=loadMyData();

}

...

}非重啟Activity的橫豎屏切換

雖然重啟Activity為我們提供了保存數(shù)據(jù)和讀取數(shù)據(jù)的方式,但是如此一來程序會顯得有些繁瑣,所以有時(shí)候程序員往往就不想讓Activity重啟,Android也為我們提供了解決方案,就是通過onConfigurationChanged攔截橫豎屏變換,從而進(jìn)行必要的重新布局和切換操作。操作步驟如下:

首先,manifest中為相應(yīng)的Activity設(shè)置android:configChanges屬性,從而讓Activity不延續(xù)上述的重建流程,具體如下:

Andorid3.2以前的SDK可以使用如下配置

android:configChanges="orientation|keyboardHidden"

而Adnroid3.2以后的SDK必須添加一個(gè)screenSize屬性,具體如下

android:configChanges="keyboardHidden|orientation|screenSize"

或者

android:configChanges="orientation|screenSize"

其次,在Activity或View的onConfigurationChanged(ConfigurationnewConfig)函數(shù)中獲取當(dāng)前橫豎屏參數(shù)。至于其調(diào)用順序跟touch事件的傳遞順序相似,不過他沒有消費(fèi)事件的概念,會順次調(diào)用到每一個(gè)onConfigurationChanged函數(shù)。下面是重寫Activity的例子:

//布局分別在layout-land和layout-port目錄中的同名main.xml時(shí)

@Override

publicvoidonConfigurationChanged(ConfigurationnewConfig){

super.onConfigurationChanged(newConfig);

setContentView(R.layout.main);

//注意,這里刪除了init(),否則又初始化了,狀態(tài)就丟失

findViews();

setListensers();

}

//布局為不按照layout-land和layout-port目錄,而自定義名字時(shí)

@Override

publicvoidonConfigurationChanged(ConfigurationnewConfig){

super.onConfigurationChanged(newConfig);

intmCurrentOrientation=getResources().getConfiguration().orientation;

if(mCurrentOrientation==Configuration.ORIENTATION_PORTRAIT){

setContentView(R.layout.mainP);

//注意,這里刪除了init(),否則又初始化了,狀態(tài)就丟失

findViews();

setListensers();

}elseif(mCurrentOrientation==Configuration.ORIENTATION_LANDSCAPE){

setContentView(R.layout.mainL);

//注意,這里刪除了init(),否則又初始化了,狀態(tài)就丟失

findViews();

setListensers();

}

}

當(dāng)然有時(shí)候連布局都不用更改的話,就可以直接對原有控件進(jìn)行調(diào)用操作了,比如:

publicclassMainActivityextendsActivity{

privateTextViewtextView;

@Override

publicvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

Log.i("--Main--","onCreate");

textView=(TextView)findViewById(R.id.tv_id);

}

@Override

publicvoidonConfigurationChanged(ConfigurationnewConfig){

super.onConfigurationChanged(newConfig);

Log.i("--Main--","onConfigurationChanged");

if(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE){

textView.setText("當(dāng)前屏幕為橫屏");

}else{

textView.setText("當(dāng)前屏幕為豎屏");

}

}

}

需要注意的是,onConfigurationChanged函數(shù)中只能獲得橫豎屏切換后的參數(shù),在該函數(shù)中獲取不到新的Layout和控件的尺寸位置信息,如果要處理尺寸和位置信息,必須通過消息異步或者延時(shí)調(diào)用,下面是一個(gè)App在橫豎屏切換時(shí)需要重新設(shè)置popupWindow位置的代碼:

@Override

protectedvoidonConfigurationChanged(ConfigurationnewConfig){

super.onConfigurationChanged(newConfig);

//View中不用創(chuàng)建Handler,可直接調(diào)用post操作

//newHandler().postDelayed(newRunnable(){

//

@Override

//

publicvoidrun(){

//

updatePopup();

//

}

//},500);

postDelayed(newRunnable(){

@Override

publicvoidrun(){

updatePopup();

//

}

},500);//如果不在post中,而是直接調(diào)用,那么彈出位置就會有問題

}

雖然上面沒有看到對布局的顯式調(diào)用進(jìn)行重新布局,照理控件的對象沒有被銷毀,但是控件在橫豎屏切換時(shí)應(yīng)該是需要進(jìn)行重新layout和measure,然后再進(jìn)行重繪的,否則不會引發(fā)彈出框位置的變化,至于如何調(diào)用重新layout、measure和Draw操作,在這里就不多展開了。自適應(yīng)橫豎屏如果想讓它啟動的時(shí)候是橫屏的話就橫屏表示,縱屏的話就縱屏表示,然后手機(jī)切換橫豎屏就不能用了該怎么解決呢?首先:在Mainfest.xml中追加android:screenOrientation="sensor"android:configChanges="orientation|keyboardHidden"這兩個(gè)屬性。第二步:取得屏幕的長和寬,進(jìn)行比較設(shè)置橫豎屏的變量。

Displaydisplay=getWindowManager().getDefaultDisplay();

intwidth=display.getWidth();

intheight=display.getHeight();

if(width>height){

orientation=ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;

}else{

orientation=ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;

}

第三步:在onCon

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論