Fragment生命週期和使用小結

Fragment:
碎片,是一種可以嵌在活動中的UI片段.
1.靜態:在佈局文件定義一個

    <fragment
        android:id="@+id/fragment1"
  android:name="com.example.gp08_day23_fragment2.fragment.TestFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
//獲取碎片管理器----可以直接在 activity獲取到
        manager = getFragmentManager();     
        //使用碎片管理器得到需要的碎片對象
        Fragment fragment = manager.findFragmentById(R.id.fragment1);
        //得到碎片對象中的佈局對象
        View view = fragment.getView();

2.動態:
—-FragmentManager
—-事務的使用
—-activity給fragment傳值(Bundle對象)

2.1動態添加fragment步驟:
1)在佈局文件中給fragment佔個位,一般用FrameLayout
2)創建fragment實例
3)獲取到FragmentManager,在活動中可以直接調用getFragmentManager()
4)開啓一個事務,通過調用beginTransaction方法開啓
5)向容器內加入fragment,一般使用replace()方法實現,需要傳入容器的id(就是在佈局文件中佔的位置)和fragment實例
6)提交事務,調用commit()方法完成。

2.2先介紹一下傳值

傳值:
//使用碎片管理器對象得到事務對象
        FragmentTransaction transaction = manager.beginTransaction();//開啓事務
//      Fragment f =  manager.findFragmentByTag("flag");
//      if(f==null)
//      {
//          TestFragment fragment = new TestFragment();
//          transaction.add(R.id.container, fragment, "flag");
//      }
        TestFragment fragment = new TestFragment();
        //activity給fragment傳參數
        Bundle bundle = new Bundle();
        bundle.putString("msg", "hehe"+new Date());
        fragment.setArguments(bundle);
        //replace是替換掉之前的fragment對象(remove--->add)
        transaction.replace(R.id.container, fragment);      
        //提交事務
        transaction.commit();//事務只能提交一次

接收:
public class TestFragment extends Fragment {
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState) {        
        TextView textView = new TextView(getActivity());
        textView.setTextSize(20);
        //獲取傳遞過來的參數
        Bundle bundle = getArguments();
        String value = bundle.getString("msg");
        textView.setText(value);    
        return  textView;
    }
}

關鍵是這個:
//activity給fragment傳參數
Bundle bundle = new Bundle();
bundle.putString(“msg”, “hehe”+new Date());
fragment.setArguments(bundle);

3.生命週期

Fragment的生命週期:11個方法
* 1):初始化:對應於 activity的onCreate()
* onAttach(Activity) 和所屬的activity關聯
* onCreate(Bundle )fragment的初始化
* onCreateView()初始化fragment顯示的UI視圖
* onActivityCreated()當activity的 onCreate()方法執行完(說明 activity的初始化已經完成)
* 2):顯示,隱藏
* onStart(),onResume(),onPause(),onStop()
* 3):銷燬
* onDestroyView() 銷燬fragment顯示的UI視圖(View 對象)
* onDestroy() 銷燬的是fragment
* onDettach() 和所屬的activity斷開

這裏寫圖片描述

實例:源碼地址見後面
和Activity聯動:
創建時:從外到內創建
這裏寫圖片描述

關閉時:從內到外銷燬
這裏寫圖片描述

4.自定義模擬回退棧

// 作爲回退棧
    private LinkedList<Fragment> stack = new LinkedList<Fragment>();
public void addFragment(View v) {
        TestFragment fragment = new TestFragment();
        Bundle bundle = new Bundle();
        bundle.putString("msg", "hahahaha" + new Date());
        fragment.setArguments(bundle);
        // 如果棧爲空直接入棧,不爲空則把當前的activity隱藏,然後加入新的fragment
        if (stack.size() == 0)
            getFragmentManager().beginTransaction()
                    .add(R.id.container, fragment).commit();
        else            getFragmentManager().beginTransaction().hide(stack.peek())// 隱藏棧頂的
                    .add(R.id.container, fragment).commit();
        // 入棧
        stack.push(fragment);
    }
    // 點擊回退按鈕顯示上一個fragment
    public void backFragment(View v) {
        if (!stack.isEmpty()) {
            getFragmentManager().beginTransaction().remove(stack.poll())
                    .commit();
}
        if (!stack.isEmpty())           getFragmentManager().beginTransaction().show(stack.peek()).commit();
    }

效果圖:
這裏寫圖片描述

5.使用baskToStack(null);方法

public void addFragment(View v) {
        TestFragment fragment = new TestFragment();
        Bundle bundle = new Bundle();
        bundle.putString("msg", "xixi" + new Date());
        fragment.setArguments(bundle);      
        FragmentTransaction tran = getFragmentManager().beginTransaction();     
        tran.add(R.id.container, fragment);//remove1 add 2      
        tran.addToBackStack(null);//把事務加入當前的回退棧  回滾
        tran.commit();
    }
    // 點擊回退按鈕顯示上一個fragment
    public void backFragment(View v) {      
        onBackPressed();
    }

效果和自定義回退棧相同。
–>使用回退棧的作用主要是返回時返回到上一個fragment

6.橫屏豎屏動態變化佈局
1)創建一個在橫屏時加載的佈局文件夾
這裏寫圖片描述

豎屏佈局:只有一個fragment

<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=".MainActivity" >
    <fragment
        android:id="@+id/fragment"
        android:layout_width="200dp"
        android:layout_height="match_parent"        android:name="com.beiing.fragmentlandscapefragment.FilesFragment"
         />   
</RelativeLayout>

橫屏佈局:

<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=".MainActivity" >
    <fragment
        android:id="@+id/fragment"
        android:layout_width="200dp"
        android:layout_height="match_parent"        android:name="com.beiing.fragmentlandscapefragment.FilesFragment"
         />
    <FrameLayout 
        android:id="@+id/container"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_toRightOf="@id/fragment"
        />

</RelativeLayout>

2)判斷橫屏豎屏:根據橫屏豎屏得到不同的操作

// 判斷屏幕方向
                if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                    ContentFragment fragment = new ContentFragment();
                    fragment.setArguments(bundle);

                    getFragmentManager().beginTransaction()
                                        .replace(R.id.container, fragment)
                                        .addToBackStack(null)
                                        .commit();
                }
                else
                {
                    Intent intent = new Intent(getActivity(),ContentActivity.class);
                    intent.putExtras(bundle);
                    startActivity(intent);
                }

效果圖:
這裏寫圖片描述

我的總結:
1)實際開發中,fragment使用非常多,用法大都是在一個顯示界面中底部放上一些按鈕,中間一個fragment,這樣就不用一個activity一個activity的跳了
2)引包的時候注意,一個是android.app.Fragment,還有一個向下兼容的
android.support.v4.app.Fragment;用後一個包的fragment時activity也要用這個包的FragmentActivity
3)在實現1)說的那種類似標籤頁時,需要注意不要每次都通過事務FragmentTransaction的replace()方法去變換界面,這樣會導致該fragment重新創建,如果這個fragment裏面有從網絡獲取數據的操作,這樣,變換一次加載一次,誰受得了,解決方法是,在MainActivity中定義相應fragment的成員,然後一次加入FragmentManager中,然後想要顯示哪個fragment只用調用FragmentTransaction 的show方法和hide方法。後面具體項目會遇到。

源碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章