文章出處

這一節的主要內容

1、在運行時添加一個fragment到Activity

2、替換fragment

 

為了適應不同大小的屏幕,我們可以根據屏幕的大小動態地在不同的布局文件中重用fragment。比如,對于在手機上,我們可能就只能顯示一個fragment,而在平板電腦上我們就可以并列地在界面上顯示兩個fragment,以便顯示更多的信息。

圖1.同一個Activity中的兩個fragment在大小不同的屏幕上的顯示效果。在大屏幕上,兩個fragment并列顯示。而在小屏幕上,同一時間只顯示一個fragment,另一個fragment當用戶需要的時候才顯示。

在Activity運行時添加fragment

除了在XML配置文件中定義一個fragment--像上一節我們講到的使用<fragment> 元素--你也可以在activity運行時向他添加一個fragment。如果你打算在activity存活的時候,改變fragment,這就很有必要。

為了實現事務性操作如添加或刪除一個fragment,我們必須使用FragmentManager來創建一個FragmentTransaction。我們可以通過FragmentTransaction 提供的API實現添加、刪除、替換和其他的fragment事務性操作。

如果你要允許activity中的fragment可以被刪除或者替換,那你就應該在activity的onCreate() 方法中初始化fragment。

使用Fragment很重要的一點是--特別是當你想要在運行時添加fragment--就是fragment必須裝在布局中的一個容器View里面.

下面的布局方式相對于上一節所講的不能在運行時被修改的fragment布局方式是另一種選擇。為了可以將布局中的fragment替換成另一個,在Activity中必須有一個空的FrameLayout,以便作為fragment的容器。

注意下面的文件名跟上一節的布局文件的名字一樣,但是布局文件的路徑中沒有large限定詞,所以這個布局使用在比large尺寸更小的屏幕上的,因為屏幕的大小不足以同時將所有的fragment放進去。

res/layout/news_articles.xml:

<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里面,調用getSupportFragmentManager()來獲取兼容庫(the Support Library)中的FragmentManager。然后調用beginTransaction() 來創建一個FragmentTransaction ,最后調用 add() 增加一個fragment.

你可以在一個Activity里面同時進行多個fragment事務性操作,使用同一個FragmentTransaction。當你已經沒有更多要修改的東西時,你可以調用commit()讓操作生效。

下面的例子展示的是怎么向前面的布局文件添加一個fragment:

package com.bang.testfragment;

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);
        // 檢查看Activity是不是使用fragment_container的FrameLayout的布局文件
        if (findViewById(R.id.fragment_container) != null) {
            // 如果我們是從之前的狀態恢復的,那么我們什么都不需要做
            // 否則,我們可能會將之前的fragment覆蓋掉
            if (savedInstanceState != null) {
                return;
            }
            // 在Activity的布局中創建一個可以被替換的新fragment
            HeadlinesFragment firstFragment = new HeadlinesFragment();

            // 為了防止Activity使用Intent的方式啟動的一些特殊參數信息被遺漏,
            // 我們將Intent中的額外信息作為參數傳遞給fragment
            firstFragment.setArguments(getIntent().getExtras());

            // 將fragment添加到'fragment_container'的FrameLayout中
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container, firstFragment).commit();
        }

    }
}

因為上面的fragment是在運行時被添加到FrameLayout中的--而不是在activity中的布局文件中用<fragment>元素定義的--所以activity可以將原有的fragment替換或者移除。

替換Fragment

替換fragment的過程跟添加fragment的過程差不多,只不過需要用replace()方法而不是add().

要記住當我們做一些跟fragment有關的事務性操作時,比如替換或刪除某個fragment,通常用戶可能會想回退或者撤銷原來的操作。為了允許用戶撤銷操作,你必須在準備提交FragmentTransaction前調用addToBackStack()

注意:當你刪除或替換一個fragment并將添加fragment事務到back stack,被刪除的其實是停止了(而不是銷毀)。如果用戶為了恢復fragment而回退,它就會重新啟動。如果你沒有將fragment事務添加到back stack中,那么當fragment被刪除或替換的時候,它就是真的被銷毀了。

下面代碼展示如何用替換fragment

// 創建一個fragment并將特定的文章信息作為參數傳遞給它
            ArticleFragment newFragment = new ArticleFragment();
            Bundle args = new Bundle();
            args.putInt(ArticleFragment.ARG_POSITION, position);
            newFragment.setArguments(args);
            FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();

            // 用這個新的fragment替換在fragment_container中的任何東西
            // 并將事務添加到back stack 中,以便用戶可以回退,恢復之前的操作
            transaction.replace(R.id.fragment_container, newFragment);
            transaction.addToBackStack(null);

            // 提交事務
            transaction.commit();

addToBackStack() 方法接受一個用來做事務名稱的string類型的參數。這個參數不是必須的,除非你打算使用用到FragmentManager.BackStackEntry APIs去做一些高級的fragment操作。

 

參考鏈接


文章列表


不含病毒。www.avast.com
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 大師兄 的頭像
    大師兄

    IT工程師數位筆記本

    大師兄 發表在 痞客邦 留言(0) 人氣()