Fragment(一)簡(jiǎn)介

Fragment

Fragment最初是為了適應(yīng)不同屏幕尺寸誕生的,它可以加載一個(gè)視圖,然后對(duì)視圖進(jìn)行管理操作,類似于Activity,而Fragment本身又可作為一個(gè)視圖模塊,托管給Activity來(lái)管理。 這樣就減輕了Activity的負(fù)擔(dān),大部分的功能可以在Fragment里實(shí)現(xiàn),Activity只負(fù)責(zé)加載管理就可以了。

Fragment生命周期

Fragment與Activity類似,生命周期也有相似之處,但是多了與View和托管對(duì)象Activity有關(guān)的方法:

  • 創(chuàng)建:
    1.onAttach() Fragment與Activity關(guān)聯(lián)時(shí)調(diào)用
    2.onCreate() Fragment初始化創(chuàng)建
    3.onCreateView() 建立并返回Fragment的View
    4.onViewCreated()該方法官方?jīng)]有介紹,實(shí)際上會(huì)調(diào)用,View創(chuàng)建完成時(shí)調(diào)用
    5.onActivityCreated() 當(dāng)托管該Fragment的Activity完成創(chuàng)建(onCreate)時(shí)調(diào)用

  • 創(chuàng)建完成開(kāi)始運(yùn)行
    1.onStart()
    2.onResume()

  • 轉(zhuǎn)入后臺(tái)
    1.onPause()
    2.onStop()

以上方法與Activity是一樣的,Activity調(diào)用時(shí),F(xiàn)ragment也會(huì)跟著調(diào)用。

  • 結(jié)束
    1.onDestroyView()與onActivityCreated()對(duì)應(yīng),F(xiàn)ragment視圖被移除時(shí)調(diào)用
    2.onDestroy()
    3.onDetach()與onAttach對(duì)應(yīng),與Activity解除關(guān)聯(lián)時(shí)調(diào)用。

  • 狀態(tài)保存與恢復(fù)
    與Activity一樣,非正常退出Fragment時(shí),也會(huì)觸發(fā) onSaveInstanceState(Bundle outState)方法,將數(shù)據(jù)保存在Bundle中,恢復(fù)的時(shí)候會(huì)調(diào)用onViewRestrored(Bundle savedInstanceState)方法。在Activity中調(diào)用的方法是onRestoreInstanceState()。

Fragment使用

Fragment是API 11 才引入的,使用的時(shí)候有android.app.fragment和v4支持包兩個(gè)選項(xiàng)。獲取FragmentManager的API也不同,v4包中使用getSupportedFragmentManager,直接繼承的使用getFragmentManager

靜態(tài)使用Fragment

靜態(tài)使用是指將Fragment當(dāng)做一個(gè)空間,定義在Layout文件中。
先定義一個(gè)Fragment引用的layout文件:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/item_content"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          android:gravity="center"
          android:text="Item Frament">
</TextView>

然后新建Fragment,加載視圖:

public class ItemFragment  extends Fragment {
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.item,container,false);
        return v;
    }
}

到這里Fragment的部分完成了,可以把這個(gè)Fragment當(dāng)做控件在XMl中直接引用,下面是Activity的layout文件

<?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">
    <fragment
        android:id="@+id/frag_item"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:name="com.cris.miniweather.model.fragment.ItemFragment"/>
</LinearLayout>

在Activity里setContentView設(shè)置這個(gè)layout就可以了。注意fragment控件必須指定id,否則會(huì)崩潰

動(dòng)態(tài)使用Fragment

和靜態(tài)使用步驟類似,都需要先建立好Fragment和它對(duì)應(yīng)的layout文件,不同的是在Activity中引用時(shí),使用FragmentManager來(lái)管理Fragment。

先完成Fragment使用的layout(frag_list),這里用了Recyclerview:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.RecyclerView 
        xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/list_title"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

</android.support.v7.widget.RecyclerView>

Recyclerview的對(duì)應(yīng)的layout文件(item.xml),一個(gè)TextView:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/item_content"
          android:layout_width="match_parent"
          android:layout_height="50dp"
          android:gravity="center"
          android:text="Item Frament">
</TextView>

然后建立Fragment(TitleListFragment.java),這里實(shí)現(xiàn)的是一個(gè)最簡(jiǎn)單的recyclerview

public class TitleListFragment extends android.support.v4.app.Fragment{
    private List<String> mItems;
     @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
         mItems = new ArrayList<>();
         for(int i = 0; i<50; i++ ){
             String item = "Title No." + i;
             mItems.add(item);
         }
    }
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.list_title,container,false);
        RecyclerView mRecyclerView = (RecyclerView) v.findViewById(R.id.frag_list);
        RecyclerView.LayoutManager manager=new LinearLayoutManager(getActivity());
        manager.setAutoMeasureEnabled(true);
        mRecyclerView.setLayoutManager(manager);
        mRecyclerView.setAdapter(new RecycleAdapter());
        return v;
    }
    private class RecycleHolder extends RecyclerView.ViewHolder{
        private TextView mTextView;
        public RecycleHolder(View itemView) {
            super(itemView);
            mTextView = (TextView) itemView;
        }
    }
    private class RecycleAdapter extends RecyclerView.Adapter<RecycleHolder>
    {
        @Override
        public RecycleHolder onCreateViewHolder(ViewGroup parent, int viewType) {
            View TitleItemView = LayoutInflater.from(getActivity()).inflate(R.layout.item,parent,false);
            return new RecycleHolder(TitleItemView);
        }
        @Override
        public void onBindViewHolder(RecycleHolder holder, int position) {
            holder.mTextView.setText(mItems.get(position));
        }
        @Override
        public int getItemCount() {
            return mItems.size();
        }
    }
}

到這里,F(xiàn)ragment的部分已經(jīng)完成,可以在Activity里加載它了,先設(shè)置Activity的layout文件,一個(gè)空的FrameLayout,作為Fragment的容器:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
             android:id="@+id/frag_container"
             android:layout_width="match_parent"
             android:layout_height="match_parent">
</FrameLayout>

在Activity里加載Fragment:

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_fragment_container);
        FragmentManager fm= getSupportFragmentManager();
        if(fm.findFragmentById(R.id.frag_container) ==null) {
            fm.beginTransaction()
                    .add(R.id.frag_container, new TitleListFragment())
                    .commit();
        }
    }

注意:
1.在Activity里是用FragmentManager來(lái)管理Fragment的,findFragmentById里的參數(shù)是Fragment容器的id,返回的是它所管理的Fragment。
2.在add方法之前,需要加一個(gè)判斷,如果為null才會(huì)去添加Fragment。因?yàn)锳ctivity非正常退出,并且被回收的時(shí)候,F(xiàn)ragmentManager 會(huì)將它所管理的Fragment隊(duì)列保存下次,Activity重新建立的時(shí)候,F(xiàn)ragmentManager 會(huì)先回復(fù)它所保存的隊(duì)列,并重建Fragment。

Fragment常用API

與Fragment相關(guān)的API主要有以下兩大類

  • FragmentManager
  1. beginTransaction() 獲取FragmentTransaction對(duì)象,用來(lái)操作Fragment
  1. findFragmentById(id) 獲取id對(duì)應(yīng)的父容器中的當(dāng)前Fragment
  2. findFragmentByTag(String tag) 獲取tag對(duì)應(yīng)的Fragment,tag在add時(shí)添加
  3. getFragment(Bundle bundle, String key) 與putFragment對(duì)應(yīng),將一個(gè)Fragment對(duì)象放在Bundle數(shù)據(jù)中
  4. isDestroyed() 托管該Fragment的Activity執(zhí)行onDestroy后,會(huì)返回true。
  5. void popBackStack() 將棧頂對(duì)象彈出。相當(dāng)于back鍵
  6. saveFragmentInstanceState(Fragment f) 存儲(chǔ)f的狀態(tài)。
  • FragmentTransaction
  1. add(Fragment fragment, String tag); 調(diào)用第三個(gè)方法,containerViewId為0
  1. add(int containerViewId, Fragment fragment) 調(diào)用第三個(gè)方法,tag為null
  2. add(int containerViewId, Fragment fragment, String tag);添加fragment到container中
  3. addToBackStack(String name)添加Fragment到name返回棧中,默認(rèn)為null
  4. attach(Fragment fragment) 在使用detach方法與UI解除關(guān)聯(lián)之后重新關(guān)聯(lián)
  5. commit() 提交事物
  6. detach(Fragment fragment) 從UI中解除Fragment的綁定。
  7. remove(Fragment fragment) 移除一個(gè)已經(jīng)存在了的Fragment。
  8. hide(Fragment fragment) 隱藏一個(gè)存在的Fragment
  9. show(Fragment fragment) 顯示一個(gè)之前隱藏的Fragment。
  10. replace(int containerViewId, Fragment fragment, String tag);替換一個(gè)已經(jīng)存在了的Fragment(先remove,在add)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容