Activity嵌套多個Fragment實現橫豎屏切換,activityfragment

來源:互聯網
上載者:User

Activity嵌套多個Fragment實現橫豎屏切換,activityfragment

一、

二、需求

       近期項目遇到個橫豎屏切換的問題,較為複雜,在此記之。

       1、Activity中豎屏嵌套3個Fragment,本文簡稱豎屏FP1,FP2,FP3。

       2、其中豎屏FP1與FP2可以切換為橫屏的FL1,FL2,即豎屏FP1切換到對應的橫屏FL1,豎屏FP2對應切換到橫屏FL2。

       3、FP3不允許橫豎屏切換。

       4、豎屏FP1,FP2,FP3用ViewPager實現左右滑動切換。

       5、橫屏的FL1,FL2用布局中的切換按扭實現左右切換,不允許滑動切換。


      看到這需求有點兒暈菜了吧!!!呵呵!!!

      (一)先說說我走過的彎路,將橫豎屏切換在一個Activity中實現。

      (1)、在一個Activity中實現橫豎屏切換難在什麼地方呢?主要是橫豎屏切換,Activity有它自己的生命週期、Fragment也有它的生命週期,而且Activity的生命週期左右著Fragment的生命週期。最複雜的地方是,首次橫豎屏切換時,Activity的onDestory()方法會執行,在執行此方法之前,Fragment的onDestoryView()首先會獲得執行,接著會執行onCreateView()方法。而首次切換到橫屏時,Activity的onCreate()方法會執行,接著橫屏FL1的onCreateView()方法又會執行,這樣的話,Fragment的布局就會發生覆蓋。(這是我在做的時候發現的問題,不知道其他人是否遇到)。

     (2)、在一個Activity中橫豎屏切換,豎屏布局與橫屏布局不一樣,本文樣本豎屏為Activity中嵌套3個Fragment,橫屏嵌套2個Fragment,首先會有很多頁面狀態需要記錄,其次就是Activity與Fragment的生命週期關係問題,確實挺複雜,控制這裡面的狀態,只有做過的人才知道有多苦。

      (二)可取的辦法,將橫豎屏切換在兩個Activity中實現


 三、解決問題思路

        1、首先當然是要讓兩個Activity能夠橫豎切,這裡首先需要在AndroidManifest.xml中配置兩個Activity能夠橫豎切換,配置如下:

       

<activity            android:name=".ActivityPort"            android:configChanges="orientation|keyboardHidden|screenSize"            android:label="@string/app_name"            android:windowSoftInputMode="stateAlwaysHidden|adjustPan" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>                 <activity            android:name=".ActivityLand"            android:configChanges="orientation|keyboardHidden|screenSize"            android:label="@string/app_name"            android:windowSoftInputMode="stateAlwaysHidden|adjustPan" />

       2、豎屏Activity的切換到橫屏Activity的時候,通過Intent跳轉到橫屏的Activity,然後將當前Activity給finish()掉。反之也是一樣的邏輯。那麼現在面臨的一個問題是什麼,這個跳轉寫在什麼地方,寫在onDestory()方法中顯然是不合適的,因為這個方法在橫豎切的時候會始終執行,當你在按回退鍵返回到上一個頁面時,同樣會執行這個方法,這樣跳轉的話,就會死迴圈,會總是開啟頁面。這時候就想到了Activity的onConfigurationChanged()方法。Google官網說橫豎屏切換不希望大家用這個方法實現橫豎屏切換,但是遇到了這樣怪異的需求,不得不使用。上代碼:

      

@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);ActivityLand.showActivityLand(this);finish();}

       3、在兩個Activity中實現橫豎切換之後,換來一個好處,Fragment的生命週期我們非常好控制,裡面的邏輯想怎麼寫就怎麼寫,而且切換過來之後,布局也會自動去載入橫屏的布局。(相信大家明白我的意思)。


      4、切換到對應的Fragment,主要是藉助於緩衝,記錄頁面狀態。詳見源碼。


       5、上主要代碼:

       (1)豎屏Activity的主要邏輯

package com.example.screenswitch;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.content.Intent;import android.content.pm.ActivityInfo;import android.content.res.Configuration;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.support.v4.view.ViewPager;import android.view.KeyEvent;import com.example.screenswitch.adapter.ChartFragmentPagerAdapter;import com.example.screenswitch.application.DataCache;import com.example.screenswitch.fragments.Fragment1;import com.example.screenswitch.fragments.Fragment2;import com.example.screenswitch.fragments.Fragment3;public class ActivityPort extends FragmentActivity {private static final String TAG = "ActivityPort";/**頁面類型-豎屏1**/public static final int PORT_PAGE_1 = 1;/**頁面類型-豎屏2**/public static final int PORT_PAGE_2 = 2;/**頁面類型-豎屏3**/public static final int PORT_PAGE_3 = 3;private ViewPager vpChartPage;private Fragment1 fragment1;private Fragment2 fragment2;private Fragment3 fragment3;/**豎屏FragmentManager**/private FragmentManager portfragmentManager;/**fragmentTransaction**/private FragmentTransaction mFragmentTransaction;/**Fragment集合**/private List<Fragment> mFragmentList;/**分時、K線、明細介面適配器**/private ChartFragmentPagerAdapter mPagerAdapter;/**螢幕方向 預設指定為豎屏**/private int mScreenOrientation = Configuration.ORIENTATION_PORTRAIT;/**當前Fragment**/private Fragment mCurentFragment;public static void showActivityPort(Activity activity){Intent intent = new Intent(activity,ActivityPort.class);activity.startActivity(intent);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.layout_main);mScreenOrientation = getResources().getConfiguration().orientation;portfragmentManager = getSupportFragmentManager();mFragmentTransaction = portfragmentManager.beginTransaction();switch (mScreenOrientation) {case Configuration.ORIENTATION_PORTRAIT:// 豎屏  分時 K線findPortViews();initPortCtrl();break;}}private void findPortViews(){vpChartPage = (ViewPager) findViewById(R.id.vp_chart_page);vpChartPage.setOnPageChangeListener(new ChartPageChangeListener());}private void initPortCtrl(){fragment1 = new Fragment1();fragment2 = new Fragment2();fragment3 = new Fragment3();mFragmentList = new ArrayList<Fragment>();mFragmentList.add(fragment1);mFragmentList.add(fragment2);mFragmentList.add(fragment3);mCurentFragment = fragment1;mPagerAdapter = new ChartFragmentPagerAdapter(portfragmentManager,mFragmentList);vpChartPage.setAdapter(mPagerAdapter);//橫1對豎1 橫2對豎2  完成對應頁的橫豎切換if(getPageType() == PORT_PAGE_1 || getPageType() == ActivityLand.LAND_PAGE_1){setPageType(PORT_PAGE_1);vpChartPage.setCurrentItem(0);}else if(getPageType() == PORT_PAGE_2 || getPageType() == ActivityLand.LAND_PAGE_2){setPageType(PORT_PAGE_2);vpChartPage.setCurrentItem(1);}}/**分時、K線、明細豎屏介面切換**/class ChartPageChangeListener implements ViewPager.OnPageChangeListener {@Overridepublic void onPageScrollStateChanged(int i) {}@Overridepublic void onPageScrolled(int i, float v, int i2) {}@Overridepublic void onPageSelected(int i) {//設定介面指標switch (i) {case 0:mCurentFragment = fragment1;setPageType(PORT_PAGE_1);break;case 1:setPageType(PORT_PAGE_2);mCurentFragment = fragment2;setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR);//設定可以橫豎切換break;case 2:setPageType(PORT_PAGE_3);mCurentFragment = fragment3;setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);//禁止旋轉螢幕break;}}}@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);ActivityLand.showActivityLand(this);finish();}@Overrideprotected void onDestroy() {super.onDestroy();}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if(keyCode == KeyEvent.KEYCODE_BACK){finish();}return true;}/**記錄當前頁面類型**/private void setPageType(int chartPageType) {DataCache.instance().setmChartPageType(chartPageType);}/**擷取當前頁面類型 **/private int getPageType() {return DataCache.instance().getmChartPageType();}}


    (2)、橫屏Activity的主要邏輯


package com.example.screenswitch;import android.app.Activity;import android.content.Intent;import android.content.res.Configuration;import android.os.Bundle;import android.support.v4.app.Fragment;import android.support.v4.app.FragmentActivity;import android.support.v4.app.FragmentManager;import android.support.v4.app.FragmentTransaction;import android.view.KeyEvent;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import com.example.screenswitch.application.DataCache;import com.example.screenswitch.fragments.Fragment1;import com.example.screenswitch.fragments.Fragment2;public class ActivityLand extends FragmentActivity {private static final String TAG = "ActivityLand";/**頁面類型-橫屏1**/public static final int LAND_PAGE_1 = 4;/**頁面類型-橫屏2**/public static final int LAND_PAGE_2 = 5;private Fragment1 fragment1;private Fragment2 fragment2;/**豎屏FragmentManager**/private FragmentManager mfragmentManager;/**fragmentTransaction**/private FragmentTransaction mFragmentTransaction;/**螢幕方向 預設指定為豎屏**/private int mScreenOrientation = Configuration.ORIENTATION_PORTRAIT;/**當前Fragment**/private Fragment mCurentFragment;/**切換按鈕**/private Button btSwitch;public static void showActivityLand(Activity activity) {Intent intent = new Intent(activity, ActivityLand.class);activity.startActivity(intent);}@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.layout_main);mScreenOrientation = getResources().getConfiguration().orientation;mfragmentManager = getSupportFragmentManager();mFragmentTransaction = mfragmentManager.beginTransaction();switch (mScreenOrientation) {case Configuration.ORIENTATION_LANDSCAPE:// 橫屏  分時 K線findLandViews();initLandCtrl();break;}}private void findLandViews() {btSwitch = (Button) findViewById(R.id.bt_switch);btSwitch.setOnClickListener(new TheOnSwitchBtnClickListener());}private void initLandCtrl() {fragment1 = new Fragment1();fragment2 = new Fragment2();//橫1對豎1 橫2對豎2  完成對應頁的橫豎切換if (getPageType() == ActivityPort.PORT_PAGE_1 || getPageType() == LAND_PAGE_1) {setPageType(ActivityPort.PORT_PAGE_1);mCurentFragment = fragment1;} else if (getPageType() == ActivityPort.PORT_PAGE_2 || getPageType() == LAND_PAGE_2) {setPageType(ActivityPort.PORT_PAGE_2);mCurentFragment = fragment2;}mFragmentTransaction = mfragmentManager.beginTransaction();mFragmentTransaction.add(R.id.ll_content, mCurentFragment);mFragmentTransaction.commit();}/** * 橫屏介面切換 * @author Wilson */class TheOnSwitchBtnClickListener implements OnClickListener {@Overridepublic void onClick(View v) {if (mCurentFragment instanceof Fragment1) {//橫1切到橫2mCurentFragment = fragment2;setPageType(LAND_PAGE_2);mFragmentTransaction = mfragmentManager.beginTransaction();mFragmentTransaction.replace(R.id.ll_content, fragment2);mFragmentTransaction.commit();} else if (mCurentFragment instanceof Fragment2) {//橫2切到橫1mCurentFragment = fragment1;setPageType(LAND_PAGE_1);mFragmentTransaction = mfragmentManager.beginTransaction();mFragmentTransaction.replace(R.id.ll_content, fragment1);mFragmentTransaction.commit();}}}@Overridepublic void onConfigurationChanged(Configuration newConfig) {super.onConfigurationChanged(newConfig);ActivityPort.showActivityPort(this);finish();}@Overrideprotected void onDestroy() {super.onDestroy();}@Overridepublic boolean onKeyDown(int keyCode, KeyEvent event) {if (keyCode == KeyEvent.KEYCODE_BACK) {finish();}return true;}/**記錄當前頁面類型**/private void setPageType(int chartPageType) {DataCache.instance().setmChartPageType(chartPageType);}/**擷取當前頁面類型 **/private int getPageType() {return DataCache.instance().getmChartPageType();}}


     6、範例程式碼下載連結地址

           http://download.csdn.net/detail/xiogjie_67/8839853















      
















聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.