AndroidTraining學(xué)習(xí)------Building a Dynamic UI with Fragments

Create a Fragment Class

  • 如何創(chuàng)建一個(gè)Fragment
  • 繼承Fragment類并覆蓋關(guān)鍵的生命周期方法柳弄,和操作activity差不多吮铭。
  • 唯一的不同就是你需要在Fragment中使用onCreateView()方法去加載布局。
import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.ViewGroup;
public class ArticleFragment extends Fragment {    
   @Override    
   public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {        
        // Inflate the layout for this fragment        
       return inflater.inflate(R.layout.article_view, container, false);    
   }
}

Add a Fragment to an Activity using XML

  • 這里是一個(gè)將兩個(gè)fragment添加到一個(gè)activity的例子
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <fragment android:name="com.example.android.fragments.HeadlinesFragment"
              android:id="@+id/headlines_fragment"
              android:layout_weight="1"
              android:layout_width="0dp"
              android:layout_height="match_parent" />

    <fragment android:name="com.example.android.fragments.ArticleFragment"
              android:id="@+id/article_fragment"
              android:layout_weight="2"
              android:layout_width="0dp"
              android:layout_height="match_parent" />

</LinearLayout>
  • 將布局添加到你的activity中
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;

public class MainActivity extends FragmentActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.news_articles);
    }
}

Note:

  • 如果你使用的是v7 appcompat library屁商,你的activity需要繼承APPCompatActivity,它是FragmentActivity的一個(gè)子類。
  • 當(dāng)你的使用在layout XML File中定義Fragment這一方式添加fragment時(shí)营勤,你不能在運(yùn)行時(shí)移除fragment。如何你想在用戶交互的時(shí)候替換fragment壹罚,你必須在activity第一次啟動(dòng)時(shí)添加fragment葛作。

Buildinga Flexible UI

我們需要在的布局中使用重復(fù)的fragment,可根據(jù)屏幕尺寸的不同進(jìn)行適配猖凛。比如在手機(jī)上可能只能顯示一個(gè)fragment赂蠢,而在平板電腦上需要并排顯示兩個(gè)fragment。
利用FragmentManager類提供的方法辨泳,你就可以在運(yùn)行時(shí)添加虱岂、刪除和替換Activity中的Fragment,為用戶提供一種動(dòng)態(tài)的體驗(yàn)菠红。

Fragment added at runtime to Activity

  • 如果你想添加或移除Fragment和其他事物第岖,你必須使用FragmentManager創(chuàng)建一個(gè)FragmentTransaction筹陵,這是一個(gè)可以添加吃靠、刪除和替換Fragment和其他事物的Fragemnt API。
  • 在處理Fragment(特別是在運(yùn)行時(shí)添加Fragment)時(shí)碰声,請謹(jǐn)記以下重要規(guī)則:必須在布局中為 Fragment 提供 View 容器,以便保存 Fragment 的布局烫饼。
  • 要用一個(gè)Fragment替換另一個(gè)Fragment猎塞,Activity的布局中需要包含一個(gè)作為Fragment容器的空FrameLayout。
    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/fragment_container"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
  • 在Activity內(nèi)部杠纵,使用Support Library API調(diào)用getSupportFragmentManager()以獲取FragmentManager荠耽,然后調(diào)用beginTransaction()創(chuàng)建FragmentTransaction,同時(shí)調(diào)用add()添加Fragment比藻。
    import android.os.Bundle;
    import android.support.v4.app.FragmentActivity;

    public class MainActivity extends FragmentActivity {
        &Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.news_articles);

            // 確認(rèn) Activity 使用的布局版本包含
            // fragment_container FrameLayout
            if (findViewById(R.id.fragment_container) != null) {

                // 不過铝量,如果我們要從先前的狀態(tài)還原,
                // 則無需執(zhí)行任何操作而應(yīng)返回
                // 否則就會(huì)得到重疊的 Fragment 银亲。
                if (savedInstanceState != null) {
                    return;
                }

                // 創(chuàng)建一個(gè)要放入 Activity 布局中的新 Fragment
                HeadlinesFragment firstFragment = new HeadlinesFragment();

                // 如果此 Activity 是通過 Intent 發(fā)出的特殊指令來啟動(dòng)的慢叨,
                // 請將該 Intent 的 extras 以參數(shù)形式傳遞給該 Fragment
                firstFragment.setArguments(getIntent().getExtras());

                // 將該 Fragment 添加到“fragment_container”FrameLayout 中
                getSupportFragmentManager().beginTransaction()
                        .add(R.id.fragment_container, firstFragment).commit();
            }
        }
    }

用一個(gè) Fragment 替換另一個(gè) Fragment

  • 替換Fragment的步驟和添加Fragment的步驟差不多,只不過add()換成replace()
  • 當(dāng)你執(zhí)行替換或移除 Fragment 等 Fragment 事務(wù)時(shí)务蝠,最好能讓用戶向后導(dǎo)航和“撤消”所做更改拍谐。要通過 Fragment 事務(wù)允許用戶向后導(dǎo)航,你必須調(diào)用 addToBackStack()馏段,然后再執(zhí)行 FragmentTransaction轩拨。
  • 當(dāng)你移除或替換 Fragment 并向返回堆棧添加事務(wù)時(shí),已移除的 Fragment 會(huì)停止(而不是銷毀)院喜。如果用戶向后導(dǎo)航亡蓉,還原該 Fragment,它會(huì)重新啟動(dòng)喷舀。如果你沒有向返回堆棧添加事務(wù)砍濒,那么該 Fragment 在移除或替換時(shí)就會(huì)被銷毀。
    // 創(chuàng)建 Fragment 并為其添加一個(gè)參數(shù)硫麻,用來指定應(yīng)顯示的文章
    ArticleFragment newFragment = new ArticleFragment();
    Bundle args = new Bundle();
    args.putInt(ArticleFragment.ARG_POSITION, position);
    newFragment.setArguments(args);

    FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

    // 將 fragment_container View 中的內(nèi)容替換為此 Fragment 爸邢,
    // 然后將該事務(wù)添加到返回堆棧,以便用戶可以向后導(dǎo)航
    transaction.replace(R.id.fragment_container, newFragment);
    transaction.addToBackStack(null);

    // 執(zhí)行事務(wù)
    transaction.commit();

Communication with Other Fragment

  • Fragment無法直接與Fragment通信庶香,但是可以通過Activity進(jìn)行通信甲棍。

Define an Interface

為了讓Fragment和Activity通信需要一下幾步:

  • 在Fragment中定義一個(gè)接口,并且在Activity中實(shí)現(xiàn)這個(gè)接口
  • Fragment在onAttach()方法中捕獲接口的實(shí)現(xiàn)
  • 調(diào)用接口方法與activity進(jìn)行通信
    這里是一個(gè)Fragment和Activity通信的例子
public class HeadlinesFragment extends ListFragment {
    OnHeadlineSelectedListener mCallback;

    // Container Activity must implement this interface
    public interface OnHeadlineSelectedListener {
        public void onArticleSelected(int position);
    }

    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);

        // This makes sure that the container activity has implemented
        // the callback interface. If not, it throws an exception
        try {
            mCallback = (OnHeadlineSelectedListener) activity;
        } catch (ClassCastException e) {
            throw new ClassCastException(activity.toString()
                    + " must implement OnHeadlineSelectedListener");
        }
    }

    ...
}

現(xiàn)在Fragment通過調(diào)用onArticleSelected()方法(或者interface中其他的方法)就可以傳遞messages給activity了赶掖。
例如,以下Fragment中的方法當(dāng)用戶點(diǎn)擊一個(gè)菜單項(xiàng)時(shí)被調(diào)用七扰。fragment通過回調(diào)接口傳遞事件給父級activity奢赂。

    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        // Send the event to the host activity
        mCallback.onArticleSelected(position);
    }

Implement the Interface

為了接收到來自fragment的事件,activity必須實(shí)現(xiàn)定義在Fragment的接口颈走。

public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...

    public void onArticleSelected(int position) {
        // The user selected the headline of an article from the HeadlinesFragment
        // Do something here to display that article
    }
}

Deliver a Message to a Fragment

activity可以通過findFragmentById獲取Fragment實(shí)例膳灶,然后直接調(diào)用fragment的public方法。
舉個(gè)例子,假如上述的例子中的activity包含另一個(gè)fragment用于顯示item指定的回調(diào)方法中返回的數(shù)據(jù)轧钓。這樣序厉,activity可以將回調(diào)方法中收到的數(shù)據(jù)傳遞到其他的fragment中,并顯示出來毕箍。

public static class MainActivity extends Activity
        implements HeadlinesFragment.OnHeadlineSelectedListener{
    ...

    public void onArticleSelected(int position) {
        // The user selected the headline of an article from the HeadlinesFragment
        // Do something here to display that article

        ArticleFragment articleFrag = (ArticleFragment)
                getSupportFragmentManager().findFragmentById(R.id.article_fragment);

        if (articleFrag != null) {
            // If article frag is available, we're in two-pane layout...

            // Call a method in the ArticleFragment to update its content
            articleFrag.updateArticleView(position);
        } else {
            // Otherwise, we're in the one-pane layout and must swap frags...

            // Create fragment and give it an argument for the selected article
            ArticleFragment newFragment = new ArticleFragment();
            Bundle args = new Bundle();
            args.putInt(ArticleFragment.ARG_POSITION, position);
            newFragment.setArguments(args);

            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

            // Replace whatever is in the fragment_container view with this fragment,
            // and add the transaction to the back stack so the user can navigate back
            transaction.replace(R.id.fragment_container, newFragment);
            transaction.addToBackStack(null);

            // Commit the transaction
            transaction.commit();
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弛房,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子而柑,更是在濱河造成了極大的恐慌文捶,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件媒咳,死亡現(xiàn)場離奇詭異粹排,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)涩澡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門顽耳,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人妙同,你說我怎么就攤上這事射富。” “怎么了渐溶?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵辉浦,是天一觀的道長。 經(jīng)常有香客問我茎辐,道長宪郊,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任拖陆,我火速辦了婚禮弛槐,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘依啰。我一直安慰自己乎串,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布速警。 她就那樣靜靜地躺著叹誉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪闷旧。 梳的紋絲不亂的頭發(fā)上长豁,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天,我揣著相機(jī)與錄音忙灼,去河邊找鬼匠襟。 笑死钝侠,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的酸舍。 我是一名探鬼主播帅韧,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼啃勉!你這毒婦竟也來了忽舟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤璧亮,失蹤者是張志新(化名)和其女友劉穎萧诫,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體枝嘶,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡帘饶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了群扶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片及刻。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖竞阐,靈堂內(nèi)的尸體忽然破棺而出缴饭,到底是詐尸還是另有隱情,我是刑警寧澤骆莹,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布颗搂,位于F島的核電站,受9級特大地震影響幕垦,放射性物質(zhì)發(fā)生泄漏丢氢。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一先改、第九天 我趴在偏房一處隱蔽的房頂上張望疚察。 院中可真熱鬧,春花似錦仇奶、人聲如沸貌嫡。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽岛抄。三九已至,卻和暖如春狈茉,著一層夾襖步出監(jiān)牢的瞬間弦撩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工论皆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓点晴,卻偏偏與公主長得像感凤,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子粒督,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355

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

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,133評論 25 707
  • Fragment概述 Fragment是Activity中用戶界面的一個(gè)行為或者說是一部分陪竿。主要是支持大屏幕上動(dòng)態(tài)...
    wangling90閱讀 11,541評論 5 75
  • Fragment用于創(chuàng)建動(dòng)態(tài)的、多窗口的交互體驗(yàn) 創(chuàng)建一個(gè)Fragment 必須重寫onCreateView()回...
    Dear宅學(xué)長閱讀 686評論 0 4
  • 這周末孩子回家屠橄,出了去上了一次英語一對一之外族跛,幾乎什么也沒做,英語锐墙、語文礁哄、數(shù)學(xué)都未完成作業(yè),回家什么樣溪北,返...
    記得祝福閱讀 124評論 0 2
  • 小白入職場之拨,像窗明幾凈上的筆酣墨飽恭候下的一張白紙茉继,請務(wù)必三思而行謹(jǐn)慎落筆。 兩種人要警惕蚀乔。 一烁竭、老金: 金萬全,...
    愛碼愛自由閱讀 662評論 12 19