本帖最後由 tonyh 於 2018-1-13 14:58 編輯
什麼是Fragment
Fragment (中譯:片段、區塊) 是Android提供的一個畫面區塊,可將Fragment放在一個Activity中,可使用多個Fragment構成一個手機畫面。因此,Fragment是Activity的子畫面,如下圖:
在Activity中的每個Fragment擁有自己的生命週期,當Activity進入暫停時,Activity內的Fragment也會自動執行相對的生命週期方法,在Fragment中覆寫這些方法,可自訂區塊的功能設計。例如,何時要重新讀取資料、何時暫停處理資料等。
在2009年Android剛嶄露頭角時,手機的畫面不大,解析度也不高,一個畫面放不了太多資訊,因此使用Activity轉換到另一個Activity的方式來設計功能,如下圖:
像是在Activity1中顯示消費清單,當按下清單中的其中一個項目時,在Activity2顯示該筆消費的詳細資訊。
但從2010年時平板開始流行後,畫面變大、解析度變高,一個畫面可容納更多的元件了,2011年初Android 3.0推出時,即加入了Fragment元件,可在Activity中加入Fragment區塊,使其可在一個畫面下容納多個區塊的顯示,並自訂每個區塊的內容,或者更換其中一個區塊功能。
Fragment的生命週期
每個Fragment擁有自己的生命週期,也就是說,在特定的狀況會自動呼叫特定的方法,供使用者依功能需求覆寫這些方法,加入必要的程式碼。依照Fragment產生與出現的順序會執行的方法描述如下:
產生階段(未出現在畫面上)
onAttach()
當Fragment被加到某個Activity畫面中時,會自動呼叫此方法。
onCreate()
Fragment被建立時會自動呼叫此方法,可加入初始化元件或資料的程式碼。
onCreateView()
將在畫面中第一次顯示Fragment時會自動呼叫此方法,必須回傳Fragment畫面的View元件,設計時,請使用方法中的LayoutInflater物件,在此方法中產生畫面元件並回傳。
onActivityCreated()
當加入本Fragment的Activity被建立時,該Activity的onCreate方法執行完成後,會自動執行此方法。執行完此方法後,Fragment才出現在畫面上。
準備階段(出現在畫面上)
onStart()
當Fragment出現在畫面中時先執行此方法。
onResume()
執行完onStart方法後,再自動執行本方法。完成後即在畫面中與使用者互動。
暫停階段
當使用者按下返回鍵,或是程式中將Fragment自某個Activity中移除時,會自動執行以下方法:
onPause()
進入暫停前第一個執行的方法。
onStop()
執行完onPause方法後,自動執行本方法。
onDestroyView()
此時Fragment已不在畫面中,呼叫此方法。
onDestroy()
當Fragment要被清除之前,會執行此方法。
onDetach()
與當初被加入的Activity卸載時,會自動執行此方法。
實作Fragment
完成如下圖所示之練習,頁面上方為兩個按鈕,下方為一個 FrameLayout,點擊按鈕後將 FrameLayout 中的內容置換為目標子頁面。
layout\activity_main.xml- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout 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"
- tools:context=".MainActivity"
- android:orientation="vertical">
- <LinearLayout
- android:orientation="horizontal"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal">
- <Button
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Fragment1"
- android:id="@+id/button1"
- android:textAllCaps="false"
- android:textSize="20sp"
- android:layout_weight="1" />
- <Button
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="Fragment2"
- android:id="@+id/button2"
- android:layout_gravity="center_horizontal"
- android:textAllCaps="false"
- android:textSize="20sp"
- android:layout_weight="1" />
- </LinearLayout>
- <FrameLayout
- android:layout_width="fill_parent"
- android:layout_height="0dp"
- android:layout_weight="1"
- android:id="@+id/frame"
- android:visibility="visible"></FrameLayout>
- </LinearLayout>
複製代碼 layout\fragment1.xml- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#c0e6ff">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="This is Fragment1"
- android:id="@+id/textView"
- android:layout_gravity="center_horizontal"
- android:gravity="center"
- android:textSize="28sp"
- android:textColor="@android:color/black"
- android:background="#c8e9ff"
- android:visibility="visible" />
- </LinearLayout>
複製代碼 layout\fragment2.xml- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="#ffc7c7">
- <TextView
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:text="This is Fragment2"
- android:id="@+id/textView"
- android:layout_gravity="center_horizontal"
- android:gravity="center"
- android:textSize="28sp"
- android:textColor="@android:color/black"
- android:background="#f7d1ff"
- android:visibility="visible" />
- </LinearLayout>
複製代碼 MainActivity.java- package org.istak.ch38_fragment;
- import android.app.FragmentTransaction;
- import android.support.v7.app.AppCompatActivity;
- import android.os.Bundle;
- import android.view.View;
- import android.widget.Button;
- public class MainActivity extends AppCompatActivity {
- Button btn1, btn2;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
- btn1 = (Button) findViewById(R.id.button1);
- btn2 = (Button) findViewById(R.id.button2);
- btn1.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- //FragmentManager fm = getFragmentManager();
- Fragment1 f1 = new Fragment1();
- FragmentTransaction ft = getFragmentManager().beginTransaction();
- ft.add(R.id.frame, f1); //replace() 具同樣效果
- //ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE); //設轉場動畫 (無意義)
- ft.commit();
- }
- });
- btn2.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- //Fragment2 f2 = new Fragment2();
- //FragmentTransaction ft = getFragmentManager().beginTransaction();
- //ft.add(R.id.frame_layout, f2);
- //ft.commit();
- getFragmentManager().beginTransaction().add(R.id.frame, new Fragment2()).commit();
- }
- });
- }
- }
複製代碼 Fragment1.java- package org.istak.ch38_fragment;
- import android.app.Fragment;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- /**
- * Created by Tony on 2017/11/14.
- */
- public class Fragment1 extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View v=inflater.inflate(R.layout.fragment1,container,false);
- return v;
- }
- }
複製代碼 Fragment2.java- package org.istak.ch38_fragment;
- import android.app.Fragment;
- import android.os.Bundle;
- import android.view.LayoutInflater;
- import android.view.View;
- import android.view.ViewGroup;
- /**
- * Created by Tony on 2017/11/14.
- */
- public class Fragment2 extends Fragment {
- @Override
- public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
- View v=inflater.inflate(R.layout.fragment2,container,false);
- return v;
- }
- }
複製代碼 |