Fragment 横竖屏切换问题
生活随笔
收集整理的這篇文章主要介紹了
Fragment 横竖屏切换问题
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在默認(rèn)情況下當(dāng)發(fā)生橫豎屏切換時(shí),當(dāng)前Activity中的fragment都會(huì)通過(guò)Fragment.instantiate重新生成,該方法將使用默認(rèn)的構(gòu)造函數(shù)來(lái)生成相應(yīng)的Fragment,所以如果沒(méi)有默認(rèn)構(gòu)造函數(shù)的話(huà)將會(huì)報(bào)錯(cuò),例如:
?? ?
class MyFragment { public MyFragment(int title, String message){} public static final MyFragment newInstance(int title, String message) {MyFragment f = new MyFragment (int title, String message);return f; } } 這時(shí)候當(dāng)橫豎屏切換時(shí)由于MyFragment沒(méi)有默認(rèn)構(gòu)造函數(shù),將拋出java.lang.InstantiationException異常,正確的方式為使用Bundle來(lái)進(jìn)行參數(shù)傳遞修改如下:
?? ?
class MyFragment { private static final String TITLE="title",MESSAGE="message"; private String title,message; public void onCreate(Bundle saveInstanceState){title = getArguments().getString(TITLE);message = getArguments().getString(MESSAGE); } public static final MyFragment newInstance(int title, String message) {MyFragment f = new MyFragment (int title, String message);Bundle bdl = new Bundle(2);bdl.setString(TITLE,title);bdl.setString(MESSAGE,message);f.setArguments(bdl);return f; } }
?通過(guò)這種方式創(chuàng)建的Fragment在橫豎屏切換時(shí)通過(guò)getArguments依然能夠獲得之前設(shè)置的數(shù)據(jù),其原理是在FragmentActivity切換時(shí)會(huì)調(diào)用onRetainNonConfigurationInstance方法將FragmentManager中管理的所有Fragment及其狀態(tài)數(shù)據(jù)(其中就包括了這個(gè)設(shè)置的Bundle)保存在一個(gè)FragmentActivity.NonConfigurationInstances對(duì)象實(shí)例中,這樣在新的FragmentActivity啟動(dòng)時(shí)在onCreate方法中可以使用Activity.getLastNonConfigurationInstance()方法來(lái)獲取這個(gè)對(duì)象,然后通過(guò)FragmentManager.restoreAllState方法還原所有Fragment及其狀態(tài),需要注意的是在這種情況下可能會(huì)出現(xiàn)之前的Fragment沒(méi)有detach而處于活動(dòng)狀態(tài)導(dǎo)致該Fragment的視圖生成,可能會(huì)造成兩個(gè)Fragment視圖重疊的情況,在官方的Support.v4的例子中FragmentTabs.TabManager.addTab里有一段檢查Fragment是否detach的代碼正是用于解決這個(gè)問(wèn)題。
通過(guò)上面的處理基本是沒(méi)問(wèn)題了,但因?yàn)槟J(rèn)情況下橫豎屏切換后整個(gè)FragmentActivity會(huì)被銷(xiāo)毀并重建,所有Fragment中的成員變量也會(huì)丟失,但所有的Fragment狀態(tài)數(shù)據(jù)如上所述會(huì)被保留并還原,這個(gè)時(shí)候所有的視圖都會(huì)重新創(chuàng)建。
解決方法一:在相應(yīng)的Activity配置中加上android:configChanges="orientation|keyboardHidden"設(shè)置,這樣切換時(shí)就不會(huì)銷(xiāo)毀FragmentActivity,所有的Fragment的狀態(tài)及視圖也就會(huì)保持。
解決方法二:在使用FragmentTransaction.add()方法添加fragment時(shí)設(shè)置第三個(gè)tag參數(shù),隨后在還原時(shí)可通過(guò)FragmentManager.findFragmentByTag()方法找回還原的fragment.
?? ?
class MyFragment { public MyFragment(int title, String message){} public static final MyFragment newInstance(int title, String message) {MyFragment f = new MyFragment (int title, String message);return f; } } 這時(shí)候當(dāng)橫豎屏切換時(shí)由于MyFragment沒(méi)有默認(rèn)構(gòu)造函數(shù),將拋出java.lang.InstantiationException異常,正確的方式為使用Bundle來(lái)進(jìn)行參數(shù)傳遞修改如下:
?? ?
class MyFragment { private static final String TITLE="title",MESSAGE="message"; private String title,message; public void onCreate(Bundle saveInstanceState){title = getArguments().getString(TITLE);message = getArguments().getString(MESSAGE); } public static final MyFragment newInstance(int title, String message) {MyFragment f = new MyFragment (int title, String message);Bundle bdl = new Bundle(2);bdl.setString(TITLE,title);bdl.setString(MESSAGE,message);f.setArguments(bdl);return f; } }
?通過(guò)這種方式創(chuàng)建的Fragment在橫豎屏切換時(shí)通過(guò)getArguments依然能夠獲得之前設(shè)置的數(shù)據(jù),其原理是在FragmentActivity切換時(shí)會(huì)調(diào)用onRetainNonConfigurationInstance方法將FragmentManager中管理的所有Fragment及其狀態(tài)數(shù)據(jù)(其中就包括了這個(gè)設(shè)置的Bundle)保存在一個(gè)FragmentActivity.NonConfigurationInstances對(duì)象實(shí)例中,這樣在新的FragmentActivity啟動(dòng)時(shí)在onCreate方法中可以使用Activity.getLastNonConfigurationInstance()方法來(lái)獲取這個(gè)對(duì)象,然后通過(guò)FragmentManager.restoreAllState方法還原所有Fragment及其狀態(tài),需要注意的是在這種情況下可能會(huì)出現(xiàn)之前的Fragment沒(méi)有detach而處于活動(dòng)狀態(tài)導(dǎo)致該Fragment的視圖生成,可能會(huì)造成兩個(gè)Fragment視圖重疊的情況,在官方的Support.v4的例子中FragmentTabs.TabManager.addTab里有一段檢查Fragment是否detach的代碼正是用于解決這個(gè)問(wèn)題。
通過(guò)上面的處理基本是沒(méi)問(wèn)題了,但因?yàn)槟J(rèn)情況下橫豎屏切換后整個(gè)FragmentActivity會(huì)被銷(xiāo)毀并重建,所有Fragment中的成員變量也會(huì)丟失,但所有的Fragment狀態(tài)數(shù)據(jù)如上所述會(huì)被保留并還原,這個(gè)時(shí)候所有的視圖都會(huì)重新創(chuàng)建。
解決方法一:在相應(yīng)的Activity配置中加上android:configChanges="orientation|keyboardHidden"設(shè)置,這樣切換時(shí)就不會(huì)銷(xiāo)毀FragmentActivity,所有的Fragment的狀態(tài)及視圖也就會(huì)保持。
解決方法二:在使用FragmentTransaction.add()方法添加fragment時(shí)設(shè)置第三個(gè)tag參數(shù),隨后在還原時(shí)可通過(guò)FragmentManager.findFragmentByTag()方法找回還原的fragment.
轉(zhuǎn)載于:https://www.cnblogs.com/wjhblogs/p/4688921.html
總結(jié)
以上是生活随笔為你收集整理的Fragment 横竖屏切换问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: java的数据结构
- 下一篇: enmo_day_06