《Android》『Fragment』- 如何在 MainActivity 中控管 Fragment 之間的切換
《Android Developers 參考文獻》
《簡單介紹》
在前面我們已經介紹過如何靜態以及動態的使用 Fragment,接著,當我們真正將此技術應用在實務時,往往會因為不同的需求而需要頻繁的切換 Fagment 頁面,這個時候,我們通常會將呼叫這些 Fragment 的 Activity 當作主體,透過這個 Activity 來控管不同 Fragment 之間的切換,這樣做的目的是,當 Fragment 變得越來越多時,整個專案才不會變得難以控管與維護。
《實作方法》
這邊直接透過程式碼片段,來說明如何實作,首先我們宣告兩個 Fragment,名稱分別自訂為 ViewFragment1 與 ViewFragment2,且為了方便講解,共用一個介面佈局檔,自訂名稱為 fragment_main。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package ... import ... public class ViewFragment1 extends Fragment { public static final String TAG = ViewFragment1.class.getSimpleName(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); return rootView; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Button btnChangeFragment = (Button) getView().findViewById(R.id.btnChangeFragment); btnChangeFragment.setText("Change to ViewFragment2"); btnChangeFragment.setOnClickListener(btnChangeFragment_Listener); } Button.OnClickListener btnChangeFragment_Listener = new View.OnClickListener() { @Override public void onClick(View v) { ((MainActivity)getActivity()).gotoScene(MainActivity.SCENE_NORMAL, MainActivity.FRAG_02); } }; } |
ViewFragment1.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
package ... import ... public class ViewFragment2 extends Fragment { public static final String TAG = ViewFragment2.class.getSimpleName(); @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_main, container, false); return rootView; } @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Button btnChangeFragment = (Button) getView().findViewById(R.id.btnChangeFragment); btnChangeFragment.setText("Change to ViewFragment1"); btnChangeFragment.setOnClickListener(btnChangeFragment_Listener); } Button.OnClickListener btnChangeFragment_Listener = new View.OnClickListener() { @Override public void onClick(View v) { ((MainActivity)getActivity()).gotoScene(MainActivity.SCENE_NORMAL, MainActivity.FRAG_01); } }; } |
ViewFragment2.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin"> <Button android:id="@+id/btnChangeFragment" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </RelativeLayout> |
fragment_main.xml
兩個 Fragment 中,我們分別宣告了一個按鈕,用來執行點擊跳轉到另一個 Fragment 的動作,這邊大家可以發現,兩個 Fragment 裡的按鈕點擊動作裡面,皆呼叫了同一個定義在 MainActivity 中的函式,這個函式即是此篇文章討論的重點,我們就是透過這個自訂的函式,於 MainActivity 中控管不同的 Fragment 切換。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
package ... import ... public class MainActivity extends AppCompatActivity { public static int SCENE_NORMAL = 001; public static int FRAG_01 = 101; public static int FRAG_02 = 102; int currentFragIndex = FRAG_01; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); gotoScene(SCENE_NORMAL, FRAG_01); } public void gotoScene(int targetScene, int fragIndex) { if(targetScene == SCENE_NORMAL) { //設定不同動畫 gotoFrag(fragIndex, false); } } public void gotoFrag(int fragIndex, boolean isAddToBackStack) { FragmentManager fragmentManager = getSupportFragmentManager(); Fragment frag = null; String tag = null; if(fragIndex == FRAG_01) //當 FRAG_01 時,傳入 ViewFragment1 { tag = ViewFragment1.TAG; frag = fragmentManager.findFragmentByTag(tag); if (frag == null) { frag = new ViewFragment1(); } } else if(fragIndex == FRAG_02) //當 FRAG_02 時,傳入 ViewFragment2 { tag = ViewFragment2.TAG; frag = fragmentManager.findFragmentByTag(tag); if (frag == null) { frag = new ViewFragment2(); } } currentFragIndex = fragIndex; transFragment(frag, tag, isAddToBackStack); } public void transFragment(Fragment frag, String tag, boolean isAddToBackStack) { if(frag == null) {return;} FragmentManager fragmentManager = getSupportFragmentManager(); FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction(); if(tag != null) { fragmentTransaction.replace(R.id.frameLayout, frag, tag); //指定 Fragment 要替代的介面 if (isAddToBackStack) { fragmentTransaction.addToBackStack(tag); } } try { fragmentTransaction.commit(); } catch (IllegalStateException e) { e.printStackTrace(); try { fragmentTransaction.commitAllowingStateLoss(); } catch (IllegalStateException ise) { e.printStackTrace(); } } } } |
MainActivity.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.example.xylon.fragmentexp.MainActivity"> <FrameLayout android:id="@+id/frameLayout" //Fragment 要切換的介面 android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout> |
activity_main.xml
我們在 MainActivity 中,自訂了三個函式,分別為 gotoScene()、gotoFrag() 以及 transFragment(),其中 gotoScene() 用來控管不同的動畫效果,gotoFrag()用來控管 Fragment 之間的切換,transFragment() 則用來執行 Fragment 切換的動作。
我們宣告了不同的參數來表示不同的轉場動畫以及 Fragment,如此一來,當我們要使用特定的動畫以及切換至不同的 Fragment 時,就可以透過代入這些參數來表示。
臉書留言
一般留言