Fragment篇——快速上手Fragment

Fragment的使用

因?yàn)锳ndroid-support-v4包里面的fragment比系統(tǒng)的功能更加的強(qiáng)大荒叼,所以我們所有的討論都圍繞android.support.v4.app.Fragment進(jìn)行荤崇。首先來學(xué)習(xí)一下Fragment的使用,Fragment必須依附于Activity,不能夠單獨(dú)存在罚攀。

1党觅、靜態(tài)添加Fragment

靜態(tài)添加Fragment,在布局文件中可以像添加普通控件一樣添加fragment斋泄,然后通過android:name設(shè)置fragment的實(shí)現(xiàn)類杯瞻,在實(shí)現(xiàn)類中通過onCreateView方法中設(shè)置fragment的布局。

注意:必須要設(shè)置android:id屬性是己,否則程序會出錯又兵。

StudyFragment,SecondFragment的布局如下

<?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="match_parent"
        android:layout_height="wrap_content"
        android:text="Fragment Second"
        android:gravity="center"
        android:textSize="20sp"
        android:background="#000000"
        android:textColor="#ffffff"/>
</LinearLayout>

StudyFragment和SecondFragment加載布局的代碼

@Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        return inflater.inflate(R.layout.fragment_second,container,false);
    }

MainActivity的布局如下

<?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/fragment_study1"
        android:name="com.example.study.StudyFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <fragment
        android:id="@+id/fragment_study2"
        android:name="com.example.study.StudyFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    <fragment
        android:id="@+id/fragment_second"
        android:name="com.example.study.SecondFragment"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
</LinearLayout>

需要注意的是卒废,使用v4包下的fragmet沛厨,Activity需要繼承v4包下的FragmentActivity,通常我們在AndroidStudio創(chuàng)建一個新的項(xiàng)目摔认,Activity都會默認(rèn)繼承v7包的AppCompatActivity逆皮,而AppCompatActivity繼承自FragmentActivity。如下

public class AppCompatActivity extends FragmentActivity implements AppCompatCallback,
        TaskStackBuilder.SupportParentable, ActionBarDrawerToggle.DelegateProvider {
        ...
}

所以直接在我們的Activity中的onCreate調(diào)用setContentView参袱,就可以靜態(tài)加載Fragment

效果如 圖1

關(guān)于靜態(tài)加載Fragment還有一點(diǎn)需要補(bǔ)充的就是电谣,通常我們加載完之后,還是要獲得Fragment對象進(jìn)行操作的抹蚀,這個時候可通過FragmentManager下的findFragmentById()方法或者findFragmentByTag()方法獲取Fragment對象剿牺。

2、動態(tài)加載Fragment

就像我們可以動態(tài)地添加View到視圖中环壤,我們也可以動態(tài)地添加fragment到Activity晒来。下面就來學(xué)習(xí)一下動態(tài)添加Fragment。

雖然不想誤導(dǎo)大家郑现,但還是要給大家強(qiáng)調(diào)一下湃崩,當(dāng)我們動態(tài)添加Fragment到Activity的時候,就要使用到FragmentManager接箫,我們可以通過getFragmentManager()方法獲取的Fragment用于管理android.app.Fragment的實(shí)例攒读,對于android.support.v4.app.Fragment,我們使用getSupportFragmentManager()方法。

動態(tài)加載Fragment大致有四個步驟:
1辛友、使用getSupportFragmentManager()或者getFragmentManager()獲取一個FragmentManager對象薄扁,大多數(shù)情況下我們調(diào)用的是getSupportFragmentManager()
2、開啟一個事務(wù)废累,通過調(diào)用FragmentManager的beginTransaction()方法邓梅,返回一個FragmentTransaction對象
3、往事務(wù)中添加一系列的Fragment操作九默,一般使用add或者replace方法震放,添加Fragment到當(dāng)前Activity
4、提交事務(wù)驼修,調(diào)用FragmentTransaction的commit方法

下面的例子殿遂,我們通過代碼來動態(tài)添加Fragment到Activity中。我先直接上MainActivity的布局和代碼
layout_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:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context="com.example.study.MainActivity">

    <TextView
        android:id="@+id/btn_addStudyFragment"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:background="#000000"
        android:gravity="center"
        android:textColor="#ffffff"

        android:text="addStudyFragment" />
    <TextView
        android:id="@+id/btn_addSecondFragment"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:background="#000000"
        android:textColor="#ffffff"
        android:text="addStudyFragment" />
    <TextView
        android:id="@+id/btn_check"
        android:layout_width="match_parent"
        android:layout_height="50dp"
        android:gravity="center"
        android:background="#000000"
        android:textColor="#ffffff"
        android:text="check" />
    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">
        <LinearLayout
            android:id="@+id/fragment_container"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical"/>
    </ScrollView>

</LinearLayout>

MainActivity

public class MainActivity extends AppCompatActivity {

    FragmentManager fragmentManager;
    StudyFragment studyFragment;
    SecondFragment secondFragment;

    private TextView btn_addStudy;
    private TextView btn_addSecond;
    TextView btn_check;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        fragmentManager = getSupportFragmentManager();
        btn_addSecond = (TextView) findViewById(R.id.btn_addSecondFragment);
        btn_addStudy = (TextView) findViewById(R.id.btn_addStudyFragment);
        btn_check = (TextView)findViewById(R.id.btn_check);
        btn_check.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //獲取添加到FragmentManager中的Fragment列表里面的Fragment
                Fragment fragment1 = fragmentManager.getFragments().get(0);
                Fragment fragment2 = fragmentManager.getFragments().get(2);
                Log.e("true or false",(fragment1 instanceof  StudyFragment) +"");
                Log.e("true or false",(fragment2 instanceof  StudyFragment) +"");
                Log.e("true or false",(fragment1 == fragment2) +"");
            }
        });
        btn_addStudy.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addStudyFragment();
            }
        });
        btn_addSecond.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                addSecondFragment();
            }
        });
    }

    //添加StudyFragment
    private void addStudyFragment(){
        studyFragment = new StudyFragment();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.fragment_container,studyFragment);
        transaction.commit();
    }

    //添加SecondFragment
    private void addSecondFragment(){
        secondFragment = new SecondFragment();
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.add(R.id.fragment_container,secondFragment);
        transaction.commit();
    }
}

運(yùn)行程序乙各,直接來一波操作墨礁。

當(dāng)我們反復(fù)添加Fragment進(jìn)FragmentManager的時候,那么我們要怎么對它進(jìn)行管理呢耳峦?同一個Fragment只能添加一次恩静,要是我們想要把一個Fragment添加多次,那么就要實(shí)例化多個Fragment對象才行。


反復(fù)添加Fragment的時候
注意:如果我們要對Fragment進(jìn)行操作的話驶乾,最好通過FragmentManager對Fragment進(jìn)行統(tǒng)一管理邑飒。

Fragment怎么與Activity交互

把Fragment加載到Activity后,我們知道Fragment必須依附于Activity级乐,那么Activity和Fragment交互有多少種方式呢疙咸?先從最簡單的說
1、如果Activity持有Fragment的實(shí)例风科,那么我們可以通過該Fragment直接調(diào)用Fragment里面的public方法撒轮,但是也是有坑的,就像我在上面說的贼穆,當(dāng)我們反復(fù)添加一個Fragment實(shí)例的話题山,最好還是通過FragmentManager來獲取對應(yīng)的實(shí)例,這樣減少出錯的幾率故痊。
2顶瞳、在Fragment中我們也可以通過getActivity()方法來得到當(dāng)前綁定的Activity實(shí)例,把該實(shí)例強(qiáng)轉(zhuǎn)成對應(yīng)的實(shí)例即可調(diào)用指定Activity的public方法崖蜜。

我們在開發(fā)中都會遇到的一個問題是浊仆,使用Fragment的一個好處就是我們可以重復(fù)使用,但是如果我們在ActivityA中使用了Fragment豫领,在ActivityB中也使用了Fragment抡柿,那我們調(diào)用getActivity()的時候就需要使用instanceof來判斷是哪一個類,這樣的話代碼的耦合度就很高了等恐。所以我們也可以斟酌著使用類似于回調(diào)洲劣,handler,廣播這樣的方式來進(jìn)行通信课蔬。

if(getActivity() instanceof xxxAactivity){
       //do something
}

其實(shí)說到FragmentActivity囱稽,FragmentFragment之間的通信,其實(shí)也無外乎是對象之間的訪問而已二跋,畢竟java是面向?qū)ο蟮恼骄m然activity和fragment有各自的生命周期,但是歸根到底也是對象而已扎即。只是當(dāng)我們熟悉Fragment和Activity的生命周期以后吞获,不至于寫出太生硬的代碼。

下面介紹一下接口回調(diào)方式具體怎么使用
(1)谚鄙、在Fragment中定義接口

    private OnGetListener onGetListener;
    public interface OnGetListener{
        void onGet();
    }

(2)各拷、在Fragment中對接口進(jìn)行設(shè)置

    @Override
    public void onAttach(Context context) {
        super.onAttach(context);
        if (context instanceof OnGetListener){
            onGetListener = (OnGetListener) context;
        }
    }

(3)、在MainAactivity中實(shí)現(xiàn)對回調(diào)接口的實(shí)現(xiàn)

public class MainActivity extends AppCompatActivity implements SecondFragment.OnGetListener{
    
    ...   

    @Override
    public void onGet() {

    }
}

(4)闷营、在fragment中調(diào)用回調(diào)函數(shù)

    private void doSomething(){
        if (onGetListener != null){
            onGetListener.onGet();
        }
    }

下一篇具體研究一下Fragment和Activity各自的生命周期

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末烤黍,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌速蕊,老刑警劉巖嫂丙,帶你破解...
    沈念sama閱讀 222,590評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異互例,居然都是意外死亡奢入,警方通過查閱死者的電腦和手機(jī)筝闹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,157評論 3 399
  • 文/潘曉璐 我一進(jìn)店門媳叨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人关顷,你說我怎么就攤上這事糊秆。” “怎么了议双?”我有些...
    開封第一講書人閱讀 169,301評論 0 362
  • 文/不壞的土叔 我叫張陵痘番,是天一觀的道長。 經(jīng)常有香客問我平痰,道長汞舱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,078評論 1 300
  • 正文 為了忘掉前任宗雇,我火速辦了婚禮昂芜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘赔蒲。我一直安慰自己泌神,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,082評論 6 398
  • 文/花漫 我一把揭開白布舞虱。 她就那樣靜靜地躺著欢际,像睡著了一般。 火紅的嫁衣襯著肌膚如雪矾兜。 梳的紋絲不亂的頭發(fā)上损趋,一...
    開封第一講書人閱讀 52,682評論 1 312
  • 那天,我揣著相機(jī)與錄音椅寺,去河邊找鬼浑槽。 笑死,一個胖子當(dāng)著我的面吹牛配并,可吹牛的內(nèi)容都是我干的括荡。 我是一名探鬼主播,決...
    沈念sama閱讀 41,155評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼溉旋,長吁一口氣:“原來是場噩夢啊……” “哼畸冲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,098評論 0 277
  • 序言:老撾萬榮一對情侶失蹤邑闲,失蹤者是張志新(化名)和其女友劉穎算行,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體苫耸,經(jīng)...
    沈念sama閱讀 46,638評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡州邢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,701評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了褪子。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片量淌。...
    茶點(diǎn)故事閱讀 40,852評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖嫌褪,靈堂內(nèi)的尸體忽然破棺而出呀枢,到底是詐尸還是另有隱情,我是刑警寧澤笼痛,帶...
    沈念sama閱讀 36,520評論 5 351
  • 正文 年R本政府宣布裙秋,位于F島的核電站,受9級特大地震影響缨伊,放射性物質(zhì)發(fā)生泄漏摘刑。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,181評論 3 335
  • 文/蒙蒙 一刻坊、第九天 我趴在偏房一處隱蔽的房頂上張望枷恕。 院中可真熱鬧,春花似錦紧唱、人聲如沸活尊。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,674評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蛹锰。三九已至,卻和暖如春绰疤,著一層夾襖步出監(jiān)牢的瞬間铜犬,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,788評論 1 274
  • 我被黑心中介騙來泰國打工轻庆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留癣猾,地道東北人。 一個月前我還...
    沈念sama閱讀 49,279評論 3 379
  • 正文 我出身青樓余爆,卻偏偏與公主長得像纷宇,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子蛾方,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,851評論 2 361

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