Android建立靈活動態(tài)的 UI

2018-08-02 18:34 更新

編寫:fastcome1985 - 原文:https://developer.android.com/training/basics/fragments/fragment-ui.html

在設(shè)計支持各種屏幕尺寸的應(yīng)用時,你可以在不同的布局配置中重復(fù)使用 Fragment,以便根據(jù)相應(yīng)的屏幕空間提供更出色的用戶體驗。

例如,一次只顯示一個 Fragment 可能就很適合手機這種單窗格界面,但在平板電腦上,你可能需要設(shè)置并列的 Fragment,因為平板電腦的屏幕尺寸較寬闊,可向用戶顯示更多信息。

圖1: 兩個 Fragment,顯示在不同尺寸屏幕上同一 Activity 的不同配置中。在較寬闊的屏幕上,兩個 Fragment 可并列顯示;在手機上,一次只能顯示一個 Fragment,因此必須在用戶導(dǎo)航時更換 Fragment。

利用 FragmentManager 類提供的方法,你可以在運行時添加、移除和替換 Activity 中的 Fragment,以便為用戶提供一種動態(tài)體驗。

在運行時向 Activity 添加 Fragment

你可以在 Activity 運行時向其添加 Fragment,而不用像 上一課 中介紹的那樣,使用 <fragment> 元素在布局文件中為 Activity 定義 Fragment。如果你打算在 Activity 運行周期內(nèi)更改 Fragment,就必須這樣做。

要執(zhí)行添加或移除 Fragment 等事務(wù),你必須使用 FragmentManager 創(chuàng)建一個 FragmentTransaction,后者可提供用于執(zhí)行添加、移除、替換以及其他 Fragment 事務(wù)的 API。

如果 Activity 中的 Fragment 可以移除和替換,你應(yīng)在調(diào)用 Activity 的 onCreate() 方法期間為 Activity 添加初始 Fragment(s)。

在處理 Fragment(特別是在運行時添加的 Fragment)時,請謹(jǐn)記以下重要規(guī)則:必須在布局中為 Fragment 提供 View 容器,以便保存 Fragment 的布局。

下面是 上一課 所示布局的替代布局,這種布局一次只會顯示一個 Fragment。要用一個 Fragment 替換另一個 Fragment,Activity 的布局中需要包含一個作為 Fragment 容器的空 FrameLayout

請注意,該文件名與上一課中布局文件的名稱相同,但布局目錄沒有 large 這一限定符。因此,此布局會在設(shè)備屏幕小于“l(fā)arge”的情況下使用,原因是尺寸較小的屏幕不適合同時顯示兩個 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 中,用 Support Library API 調(diào)用 getSupportFragmentManager() 以獲取 FragmentManager,然后調(diào)用 beginTransaction() 創(chuàng)建 FragmentTransaction,然后調(diào)用 add() 添加 Fragment。

你可以使用同一個 FragmentTransaction 對 Activity 執(zhí)行多 Fragment 事務(wù)。當(dāng)你準(zhǔn)備好進(jìn)行更改時,必須調(diào)用 commit()。

例如,下面介紹了如何為上述布局添加 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)返回,否則
            // 就會得到重疊的 Fragment。
            if (savedInstanceState != null) {
                return;
            }

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

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

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

由于該 Fragment 已在運行時添加到 FrameLayout 容器中,而不是在 Activity 布局中通過 <fragment> 元素進(jìn)行定義,因此該 Activity 可以移除和替換這個 Fragment。

用一個 Fragment 替換另一個 Fragment

替換 Fragment 的步驟與添加 Fragment 的步驟相似,但需要調(diào)用 replace() 方法,而非 add()。

請注意,當(dāng)你執(zhí)行替換或移除 Fragment 等 Fragment 事務(wù)時,最好能讓用戶向后導(dǎo)航和“撤消”所做更改。要通過 Fragment 事務(wù)允許用戶向后導(dǎo)航,你必須調(diào)用 addToBackStack(),然后再執(zhí)行 FragmentTransaction。

注: 當(dāng)你移除或替換 Fragment 并向返回堆棧添加事務(wù)時,已移除的 Fragment 會停止(而不是銷毀)。如果用戶向后導(dǎo)航,還原該 Fragment,它會重新啟動。如果你沒有向返回堆棧添加事務(wù),那么該 Fragment 在移除或替換時就會被銷毀。

替換 Fragment 的示例:

// 創(chuàng)建 Fragment 并為其添加一個參數(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();

addToBackStack() 方法可接受可選的字符串參數(shù),來為事務(wù)指定獨一無二的名稱。除非你打算使用 FragmentManager.BackStackEntry API 執(zhí)行高級 Fragment 操作,否則無需使用此名稱。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號