Fragment基礎(chǔ)

概念

Fragment英文原意是碎片暇韧,片段的意思,為了應(yīng)對(duì)android的碎片化含衔,F(xiàn)ragmnet的概念在Android3.0中被引入進(jìn)來煎娇,主要目的是用在大屏幕設(shè)備上--例如平板電腦上二庵,支持更加動(dòng)態(tài)和靈活的UI設(shè)計(jì)贪染。平板電腦的屏幕比手機(jī)大得多,有更多的空間來放更多的UI組件催享,并且這些組件之間會(huì)產(chǎn)生更多的交互杭隙。
Fragment在應(yīng)用中應(yīng)當(dāng)是一個(gè)模塊化和可重用的組件,因?yàn)镕ragment定義了自己的布局因妙,以及通過使用它自己的生命周期回調(diào)方法定義了它自己的行為痰憎,你可以將Fragment包含到多個(gè)Activity中,一個(gè)Activiy也可以包含多個(gè)Fragment攀涵。

下面這張圖可以幫助理解Fragment的概念:

知識(shí)概要

  1. Fragment可以作為Activity界面的一部分組成出現(xiàn)
  2. 可以在一個(gè)Activity中同時(shí)出現(xiàn)多個(gè)Fragment铣耘,并且一個(gè)Fragment也可以在多個(gè)Activity中使用
  3. 在Activity運(yùn)行過程中,可以添加以故,移除或替換Fragment
  4. Fragment可以響應(yīng)自己的輸入時(shí)間蜗细,并且有自己的生命周期,其生命周期受宿主Activity的生命周期影響

Fragment的使用

創(chuàng)建Fragment

靜態(tài)創(chuàng)建

靜態(tài)創(chuàng)建需要在在布局文件中聲明Fragment怒详,需要特別注意的是Fragment中的android:name屬性指定了在layout中實(shí)例化的Fragment類 ,同時(shí)必須要標(biāo)識(shí)Fragment炉媒。

標(biāo)識(shí)Fragment的方法:

android:id 屬性提供一個(gè)唯一的ID
android:tag 屬性提供一個(gè)唯一的字符串

** 創(chuàng)建方法:**

  1. 在布局文件中聲明一個(gè)fragment組件,name指向3中創(chuàng)建的類對(duì)象
<?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"
    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.w2.test.MainActivity"
    android:orientation="vertical">

    <Button
        android:id="@+id/button1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="button1"
        android:text="Button1"
        android:textSize="18sp"

        />
    <!--聲明一個(gè)fragment-->
    <fragment
        android:id="@+id/fragment"
        android:name="com.w2.test.MyFragment"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
</LinearLayout>

2.創(chuàng)建fragment布局文件

<?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">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="這是一個(gè)靜態(tài)加載的Fragment"
        android:id="@+id/textView"
        android:layout_gravity="center_horizontal"
        android:textSize="20sp"/>

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Change"
        android:id="@+id/button"
        android:layout_gravity="center_horizontal" />
</LinearLayout>

3.創(chuàng)建MyFragment類繼承Fragment對(duì)象昆烁,重寫onCreateView方法返回布局文件的View

public class MyFragment extends Fragment{
    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        /**
         * resource:Fragment需要加載的布局文件
         * root:加載layout的父ViewGroup
         * attactToRoot:false吊骤,不返回父ViewGroup
         */
        View v = inflater.inflate(R.layout.fragment,container,false);
        View view = inflater.inflate(R.layout.fragment, container, false);
        final TextView text=(TextView) v.findViewById(R.id.textView);
        Button button=(Button) v.findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                text.setText("測(cè)試成功");
            }
        });
        return v;
    }
}

動(dòng)態(tài)創(chuàng)建

在Java代碼中撰寫代碼將Fragment添加到Activity layout中。

add():添加一個(gè)Fragment静尼,指定要添加的Fragment和插入的View

與此類似的還有remove(),repalce()等

諸如上述對(duì)Fragment進(jìn)行添加白粉,移除,替換以及執(zhí)行其他動(dòng)作鼠渺,提交給Activity的每一套變化被稱為一個(gè)事物蜗元,處理這類事物需要Fragment Manager,通過FragmentManager開啟事務(wù)系冗。

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

每一個(gè)事務(wù)都是同時(shí)執(zhí)行一套變化奕扣,可以在一個(gè)事務(wù)中設(shè)置所要執(zhí)行的操作,然后提交給Activity掌敬,之后必須要調(diào)用commit方法惯豆。

如果允許用戶通過按下BACK按鍵返回到前一個(gè)Fragment狀態(tài),調(diào)用commit之前可以加入addToBackStack()方法奔害。

FragmentManager fragmentManager = getFragmentManager(); //獲取FragmentManager
FragmentTransaction beginTransaction = fragmentManager.beginTransaction(); //開啟事務(wù)
beginTransaction.add(R.id.frame, fragment2); //添加Fragment楷兽,參數(shù)1containerViewId傳入Fragment的父布局,參數(shù)2fragment穿入Fragment的實(shí)例化對(duì)象
beginTransaction.addToBackStack(null); //增加回退功能华临,回到上一個(gè)事務(wù)狀態(tài)
beginTransaction.commit(); //提交事務(wù)

Fragment的生命周期

  • Fragment生命周期圖


  • 與Activity生命周期對(duì)比


每個(gè)方法的回調(diào)條件:

  • onCreateView()
    每次創(chuàng)建都會(huì)繪制Fragment的View組件時(shí)回調(diào)該方法
    Fragment第一次繪制它的用戶界面的時(shí)候芯杀,系統(tǒng)會(huì)調(diào)用此方法,為了繪制Fragment的UI,此方法必須返回一個(gè)View揭厚,如果不顯示UI却特,返回null即可。

  • onAttach
    當(dāng)Fragment被添加到Activity時(shí)候會(huì)回調(diào)這個(gè)方法筛圆,并且只調(diào)用一次

  • onCreate
    創(chuàng)建Fragment時(shí)會(huì)回調(diào)裂明,只會(huì)調(diào)用一次

  • onActivityCreated
    當(dāng)Fragment所在的Activty啟動(dòng)完成后調(diào)用

  • onStart
    啟動(dòng)Fragment

  • onResume
    恢復(fù)Fragment時(shí)會(huì)被回調(diào),調(diào)用onStart()方法后面一定會(huì)調(diào)用onResume()方法

  • onPause
    暫停Fragment

  • onStop
    停止Fragment

  • onDestroyView
    銷毀Fragment所包含的View組件時(shí)

  • onDestroy
    銷毀Fragment時(shí)會(huì)被回調(diào)

  • onDetach
    Fragment從Activity中刪除時(shí)會(huì)回調(diào)該方法太援,并且這個(gè)方法只會(huì)調(diào)用一次

Fragment與Activity互相通信

Activity向Fragment傳遞數(shù)據(jù)

在Activity中創(chuàng)建Bundle數(shù)據(jù)包闽晦,并調(diào)用Fragment的setArgument(Bundle bundle)方法。這種方式是在加載Fragment之前傳遞數(shù)據(jù)的提岔。

Activity:

//動(dòng)態(tài)加載Fragment的同時(shí)傳遞數(shù)據(jù)
String text = editText.getText().toString(); //獲取要傳遞的數(shù)據(jù)
Bundle bundle = new Bundle();
if (text!=null){
    bundle.putString("msg",text);
}
MyFragment fragment = new MyFragment();
fragment.setArguments(bundle);
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.frame,fragment,"MyFragment");
transaction.addToBackStack(null);
transaction.commit();

Fragment:

//獲取數(shù)據(jù)并令TextView顯示
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View v = inflater.inflate(R.layout.fragment,container,false);
        TextView text=(TextView) v.findViewById(R.id.textView);
        text.setText(getArguments().get("msg").toString());
        return v;
    }

** 注意仙蛉,這里取得傳遞過來的數(shù)據(jù)用的是@getArgument方法,@setArgument中傳入的bundle只是一個(gè)數(shù)據(jù)類型碱蒙,與savedInstanceState這個(gè)參數(shù)沒有關(guān)系捅儒。我之前用savedInstanceState.getString()獲取數(shù)據(jù)一直錯(cuò)誤,很久都找不到錯(cuò)誤振亮。**

Fragment向Activity傳遞數(shù)據(jù)

需要在Fragment中定義回調(diào)接口巧还,再讓包含該Fragment的Activity實(shí)現(xiàn)該回調(diào)接口。這樣Fragment可以調(diào)用該回調(diào)方法傳數(shù)據(jù)給Activity坊秸。

  • 在Fragment中定義接口麸祷,并在接口中定義傳遞數(shù)據(jù)的抽象方法
    public interface MyListener{
        public void send(String code);
    }
  • 令A(yù)ctivity實(shí)現(xiàn)定義的接口,并重寫定義的方法
public class MainActivity extends AppCompatActivity implements MyFragment.MyListener
...
@Override
public void send(String code) {

}
  • 在Fragment中將創(chuàng)建接口對(duì)象并指向Activity褒搔,最后傳入String
MyListener listener;
@Override
public void onAttach(Activity activity) { //不一定非要在onAttach中
    listener = (MyListener) activity;
    super.onAttach(activity);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment,container,false);
    TextView text=(TextView) v.findViewById(R.id.textView);
    text.setText(getArguments().get("msg").toString());
    listener.send("這是發(fā)送給Activity的數(shù)據(jù)");//也不一定非在onCreateView中
    return v;
}
  • 在Activity中接收數(shù)據(jù)
@Override
public void send(String code) {
    editText.setText(code);
}

Activity向靜態(tài)加載Fragment傳遞數(shù)據(jù)

  • 首先按靜態(tài)加載方式創(chuàng)建Fragment

  • 在Fragment的創(chuàng)建數(shù)據(jù)用來接收傳來的數(shù)據(jù)阶牍,設(shè)置get和set方法

    public String a;

    public String getA() {
        return a;
    }

    public void setA(String a) {
        this.a = a;
    }
  • 在Activity通過Fragment.findFragmentById找到Fragment,通過set方法傳遞數(shù)據(jù)
FragmentManager fragmentManager = getFragmentManager();
MyFragment fragment = (MyFragment) fragmentManager.findFragmentById(R.id.fragment);
fragment.setA(text);
  • 最后在Fragment中通過get方法接收數(shù)據(jù)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末星瘾,一起剝皮案震驚了整個(gè)濱河市走孽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌琳状,老刑警劉巖磕瓷,帶你破解...
    沈念sama閱讀 212,542評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異念逞,居然都是意外死亡困食,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門翎承,熙熙樓的掌柜王于貴愁眉苦臉地迎上來硕盹,“玉大人,你說我怎么就攤上這事叨咖〈窭” “怎么了啊胶?”我有些...
    開封第一講書人閱讀 158,021評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)垛贤。 經(jīng)常有香客問我焰坪,道長(zhǎng),這世上最難降的妖魔是什么南吮? 我笑而不...
    開封第一講書人閱讀 56,682評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮誊酌,結(jié)果婚禮上部凑,老公的妹妹穿的比我還像新娘。我一直安慰自己碧浊,他們只是感情好涂邀,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,792評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著箱锐,像睡著了一般比勉。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上驹止,一...
    開封第一講書人閱讀 49,985評(píng)論 1 291
  • 那天浩聋,我揣著相機(jī)與錄音,去河邊找鬼臊恋。 笑死衣洁,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抖仅。 我是一名探鬼主播坊夫,決...
    沈念sama閱讀 39,107評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼撤卢!你這毒婦竟也來了环凿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,845評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤放吩,失蹤者是張志新(化名)和其女友劉穎智听,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體渡紫,經(jīng)...
    沈念sama閱讀 44,299評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞭稼,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,612評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了腻惠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片环肘。...
    茶點(diǎn)故事閱讀 38,747評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖集灌,靈堂內(nèi)的尸體忽然破棺而出悔雹,到底是詐尸還是另有隱情复哆,我是刑警寧澤,帶...
    沈念sama閱讀 34,441評(píng)論 4 333
  • 正文 年R本政府宣布腌零,位于F島的核電站梯找,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏益涧。R本人自食惡果不足惜锈锤,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,072評(píng)論 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望闲询。 院中可真熱鬧久免,春花似錦、人聲如沸扭弧。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鸽捻。三九已至呼巴,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間御蒲,已是汗流浹背衣赶。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評(píng)論 1 267
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留厚满,地道東北人屑埋。 一個(gè)月前我還...
    沈念sama閱讀 46,545評(píng)論 2 362
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像痰滋,于是被迫代替她去往敵國(guó)和親摘能。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,658評(píng)論 2 350

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

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 171,848評(píng)論 25 707
  • Fragment要點(diǎn) 1敲街、Fragment作為Activity界面的一部分組成出現(xiàn) 2团搞、可以在一個(gè)Activity...
    玉圣閱讀 1,224評(píng)論 0 16
  • 引言 A Fragment represents a behavior or a portion of user ...
    伍零一閱讀 827評(píng)論 4 16
  • 一個(gè)輪回的對(duì)視:一個(gè)是羨慕,一個(gè)是好奇多艇,我曾是你逻恐,你終會(huì)是我。人生峻黍,如此而已...... 孩子怎樣成長(zhǎng)复隆,老人就怎樣...
    田田126閱讀 287評(píng)論 1 1
  • 在百花睡眼迷蒙時(shí), 你花枝花枝招展的最燦爛姆涩, 那時(shí)的你是何等的紅光滿面挽拂, 那時(shí)的你如一個(gè)熱戀中的小女孩,...
    嘻嘻向陽(yáng)露閱讀 132評(píng)論 0 0