Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android Fragment

Android Fragment

編輯:關於Android編程

Fragment介紹

Android在3.0中引入了Fragments的概念,主要目的是用在大屏幕設備上(如平板電腦上)支持更加動態和靈活的UI設計。平板電腦的屏幕要比手機大,有更多的空間來放更多的UI組件,並且這些組件之間會產生更多的交互,Fragment在應用中應該是一個模塊化和可重用的組件,因為Fragment定義了它自己的布局,已經通過使用它自己的生命周期回調方法定義了他自己的行為,也可以將Fragment包含到多個Activity中。更多詳細介紹可查看官方文檔

Fragment知識概要

1、Fragment可以作為Activity界面的一部分組成出現。
2、可以在一個Activity中同時出現多個Fragment,並且一個Fragment也可以在多個Activity 中使用。
3、在Activity運行過程中,可以添加,移除和替換Fragment。
4、Fragment可以響應自己的輸入事件,並且有自己的生命周期,他們的生命周期受宿主Activity生命周期的影響和限制。

創建一個Fragment

創建一個Fragment,必須創建一個Fragment子類或繼承已存在的子類,創建好子類後可在onCreateView()方法中加載Fragment中的布局文件,Fragment第一次繪制它的用戶界面的時候,系統會調用此方法,為了繪制Fragment的UI,此方法必須返回一個View,如果不顯示UI,返回null即可。

public class MyFragment extends Fragment{
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        //在這裡加載Fragment的布局文件,將其轉換成View對象最後返回,(下面有詳細的案例)...

        return super.onCreateView(inflater, container, savedInstanceState);
    }
}


 

Activity加載Fragment兩種的方式(靜態加載、動態加載)

靜態加載:

 

在Activity的layout文件中聲明Fragment,需要特別注意的是在標簽中的需要包含一個android:name屬性來指定這個layout中實例化的Fragment類(把Fragment的全類名寫在這個屬性裡面),同時也要給這個Fragment一個唯一的標識。

標識一個Fragment的方法(兩種):

  • android:id屬性提供一個唯一ID
  • android:tag屬性提供一個唯一字符串

1、在Activity的layout文件中聲明Fragment




    


2、創建Fragment標簽中name屬性指定的Fragment類

 

 

public class MyFragment extends Fragment{

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        //加載Fragment自己的布局文件並轉換成View對象
        View view = inflater.inflate(R.layout.myfragment, container, false);

        //注意findViewById前的view
        TextView text=(TextView) view.findViewById(R.id.text);
        Button button=(Button) view.findViewById(R.id.button);

        //.........

        return view;
    }
}
Fragment的布局文件

 

 




    

    

 

以上就是在Activity中加載布局文件是會靜態加載Fragment,注:在Activity中也可以通過findViewById查找Fragment中的布局控件。

動態加載

動態加載需要撰寫代碼將Fragment添加到一個Activity layout中,add()添加一個Fragment(指定要添加的fargment和插入的View),與此類似的還有remove(),replace()。

要完成動態Fragment加載還需要處理Fragment事務,根據用戶的交互情況,對Fragmeeng進行添加,移除,替換以及執行其他動作,提交給Activity的每一套變化被稱作一個事務。獲取Fragment事務代碼如下:

FragmentManager  fragmentManager = getFragmentManager();
FragmentTransaction  beginTransaction = fragmentManager.beginTransaction();

每一個事物都是同時執一套變化,可以在一個事物中設置你所有想執行的變化,包括add(),remove(),replace(),然後提交給Activity,必須調用commit()方法(和mysql" target="_blank" title="MySQL知識庫">數據庫事務提交類似)

如果允許用戶通過按下BACK按鍵返回到前一個Fragment狀態,調用commit()之前可以加入addToBackStack()方法。

1、創建一個Fragment

 

public class MyFragment2 extends Fragment{

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        //加載Fragment自己的布局文件並轉換成View對象
        View view = inflater.inflate(R.layout.myfragment, container, false);
        TextView text=(TextView) view.findViewById(R.id.text);
        text.setText("動態加載Fragment");
        //................
        return view;
    }
}
這時就不需要在Activity的布局文件中聲明Fragment標簽,而是Activity中使用代碼將他添加到布局文件中來

 

 

MyFragment2 fragment2=new MyFragment2();
FragmentManager fragmentManager = getFragmentManager();//獲得fragment管理者
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();//開啟事務
beginTransaction.add(R.id.frame, fragment2);//第一個參數為要把fragment加載到那個布局中
beginTransaction.addToBackStack(null);//按back鍵可回退上一個fragment狀態
beginTransaction.commit();//提交事務    

 

Fragment生命周期

 

在學習Fragment聲明周期前我們應該要了解Activity的生命周期,Fragment作為Activity的一部分所以他的生命周期一定會受到宿主Activity生命周期的影響。

Fragment聲明周期圖
這裡寫圖片描述

Fragment與Activity生命周期對比圖
這裡寫圖片描述

通過上面的Fragment與Activity生命周期對比圖可以看出每個Activity生命周期所對應的狀態下都會至少對應一個Fragment生命周期的回調方法。接下來就對Fragment的所有生命周期方法進行了解。(直接在代碼中解釋)<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> public class MyFragment3 extends Fragment { private TextView tv; // 啟動Fragment——>屏幕鎖屏——>屏幕解鎖——> // 切換到其他的Fragment——>回到桌面——>回到應用——>退出Fragment /** * 每次創建都會繪制Fragment的View組件時回調該方法(在onCreate和onActivityCreated之間調用) */ @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // TODO Auto-generated method stub View view = inflater.inflate(R.layout.fragment2, container, false); TextView tv = (TextView) view.findViewById(R.id.text); tv.setText("第一個Fragment"); Log.i("Main", "Fragment1---onCreateView()"); return view; } /** * 當Fragment被添加到Activity時候會回調這個方法,並且只調用一次 */ @Override public void onAttach(Activity activity) { // TODO Auto-generated method stub super.onAttach(activity); Log.i("Main", "Fragment1---onAttach()"); } /** * 創建Fragment時會回調,只會調用一次 */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i("Main", "Fragment1---onCreate()"); } /** * 當Fragment所在的Activty啟動完成後調用 */ @Override public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); Log.i("Main", "Fragment1---onActivityCreated()"); } /** * 啟動Fragment * */ @Override public void onStart() { super.onStart(); Log.i("Main", "Fragment1---onStart()"); } /** * 恢復Fragment時會被回調,調用onStart()方法後面一定會調用onResume()方法 */ @Override public void onResume() { super.onResume(); Log.i("Main", "Fragment1---onResume()"); } /** * 暫停Fragment */ @Override public void onPause() { super.onPause(); Log.i("Main", "Fragment1---onPause()"); } /** * 停止Fragment */ @Override public void onStop() { super.onStop(); Log.i("Main", "Fragment1---onStop()"); } /** * 銷毀Fragment所包含的View組件時,和onCreateView所創建的View組件對應 */ @Override public void onDestroyView() { super.onDestroyView(); Log.i("Main", "Fragment1---onDestroyView()"); } /** * 銷毀Fragment時會被回調 */ @Override public void onDestroy() { super.onDestroy(); Log.i("Main", "Fragment1---onDestroy()"); } /** * Fragment從Activity中刪除時會回調該方法,並且這個方法只會調用一次 */ @Override public void onDetach() { super.onDetach(); Log.i("Main", "Fragment1---onDetach()"); } }

上面對Fragment的生命周期已經做了詳細的介紹,下面可以通過一個案例來演示來詳細了解以下操作對Fragment的生命周期的影響。(直接貼測試結果)

啟動fragment

onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()
屏幕鎖屏或按HOME鍵回到手機主界面

 

onPause()->onStop()
屏幕解鎖或長按HOME重新回到應用(Fragment)

 

 

onStart()->onResume()
退出Fragment

 

 

onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()

 

第一個Fragment切換到第二個Fragment(相對於第一個Fragment替換第二個Fragment)

第一個fragment調用的方法:

 

onPause()->onStop()->onDestoryView()->onDestory()->onDetach();
第二個fragment調用的方法:

 

 

onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume()

 

Fragment的生命周期方法

1、onAttach(); // 當fragment被添加到activity中時會回調這個方法;只會調用一次
2、onCreate(); // 在fragment創建的時候回調這個方法;只會調用一次;
3、onCreateView(): // 每次創建都會繪制Fragment的View組件時調用該方法,相當於fragment綁定一個布局,布局文件轉換成view返回回來;
4、onActivityCreated(); // fragment所在的activity啟動完成後調用;
5、onStart(): // 啟動Fragment時會被回調,
6、onResume(); // 調用onStart()方法後面一定會調用這個方法,恢復fragment時回調
7、onPause(): // 暫停Fragment
8、onStop(); // 停止Fragment
9、onDestroyView(): // 銷毀Fragment所包含的View組件,與onCreateView相對應
11、onDetach(): // Fragment從Activity中刪除時回調這個方法,並且只調用一次
10、onDestroy(): // 銷毀Fragment時會被回調

Fragment與Activity通信

知識點:

如果想在彼此之間建立通信,首先就要咋彼此的地盤中找到對方

1、在fragment可調用getActivity()方法獲取他所在的宿主Activity
2、Acitvity可調用FragmentManager的findFragmentById()或findFragmentByTag()方法獲取Fragment

在Fragment與Activity通信都會傳遞一些數據

1、Activity傳遞數據到Fragment:在Activity中創建Bundle數據包,並調用Fragment的setArguments(Bundle bundle)方法,然後在Fragment類裡面通過getArguments方法獲取Bundle數據包。

2、Fragment傳遞數據到Activity:需要在Fragment中定義一個內部回調接口,再讓包含該Fragment的Activity實現該回調接口。這樣Fragment可調用該回調方法將數據傳遞給Activity。

示例代碼:

Activity向動態加載的Fragment傳值(而且是在Fragment添加到Layout布局之前發送數據):

MyFragment5 fragment5 = new MyFragment5();
Bundle bundle = new Bundle();
bundle.putString("name", text);
fragment5.setArguments(bundle);

FragmentManager fragmentManager = getFragmentManager();
FragmentTransaction beginTransaction = fragmentManager.beginTransaction();
beginTransaction.add(R.id.layout, fragment5, "fragment5");//在動態加載時設置FragmentTag(fragment5)
beginTransaction.commit();
動態加載的Fragment取值:

 

String text=getArguments().get("name")+""   ;
//向靜態加載fragment傳值
FragmentManager fragmentManager = getFragmentManager();
Fragment findFragmentById = fragmentManager.findFragmentById(R.id.frag);//查找已加載進來的fragment
MyFragment frag=(MyFragment) findFragmentById;//類型轉換     
frag.setAaa("fragment靜態傳值");//調用MyFragment中接收數據變量的set方法將數據進去,在Fragment中直接調用get方法獲取數據
靜態加載的Fragment取值:

 

 

public class MyFragment extends Fragment{

    private String aaa;

    public String getAaa() {
        return aaa;
    }

    public void setAaa(String aaa) {
        this.aaa = aaa;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {

        View view = inflater.inflate(R.layout.myfragment, container, false);

        String value = getAaa();//獲取傳遞過來的值

        return view;
    }
}
Fragment向Activity傳遞數據

 

 

public class MyFragment5 extends Fragment{

    private String code="Thank you,Activity!";

    public MyListener listener;//3.為接口聲明一個對象

    //1.內部回調接口(為了向Activity傳遞數據),讓Activity實現該接口極其方法
    public interface MyListener
    {
        public void thank(String code);
    }

    /**
     * 2.實現Fragment生命周期的onAttach方法
     * 當Fragment被添加到Activity時候會回調這個方法,並且只調用一次
     */
    @Override
    public void onAttach(Activity activity) {
        listener=(MyListener) activity;//引用宿主Activity對象
        super.onAttach(activity);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment2, container, false);

       //直接通過listener(Activity)對象的的thank方法向Activity傳值
        listener.thank(code);

        return view;
    }
}
Activity接收數據

 

 

public class MainActivity extends Activity implements MyListener {

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

    }

    @Override
    public void thank(String code) {
        // 在接口實現的方法中得到Fragment中傳過來的數據
        Toast.makeText(MainActivity.this,  code,Toast.LENGTH_SHORT).show();
    }
}
上述已經介紹完成了Fragment常用的一些方法,相信看完,大家一定清楚了Fragment的產生理由,以及如何使用Fragment,最後需要說一下Fragment的例子,Android官方已經提供了Fragment的各種使用的Demo例子,在我們SDK下面的API Demo裡面就包含了Fragment的各種使用例子,需要看Demo的朋友,直接看API Demo那個程序就可以了,不用到處去找。裡面分開不同功能,實現了不同的類。可以根據需要查看具體代碼。
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved