天天看點

【Android Training - 03】使用Fragments建立動态的UI [ Lesson 3 - 建立靈活可變的UI ] Building a Flexible UI

Building a Flexible UI

當把你的程式設計成可以适配一系列大小各異的螢幕時,你可以基于可使用的螢幕空間來為你的fragments設定不同的參數,進而達到重用的目的。

例如:在手持裝置上,一次顯示一個fragment會比較合适。對應的,在平闆這樣螢幕比較大的裝置上,你可以用多個fragment的方式來呈現出side-by-side的效果。這樣能夠一次顯示更多的資訊給使用者。如下圖所示:

【Android Training - 03】使用Fragments建立動态的UI [ Lesson 3 - 建立靈活可變的UI ] Building a Flexible UI

FragmentManager

 類提供了運作時進行添加,移除,替換fragment的方法,這樣就建立了一個動态的體驗。

Add a Fragment to an Activity at Runtime [添加fragment]

與在XML檔案中定義個fragment不同,你可以在運作時添加fragment到activity中。如果你打算在activity的某個生命周期中改變fragment,這個方法則是很有必要的。

為了執行添加或者移除fragment的切換,你必須使用 

FragmentManager

 來建立一個

FragmentTransaction

, 它會提供添加,移除,置換與其他的一些動作的APIs。

如果你的activity允許fragment被移除與置換,你必須在activity的onCreate()方法裡面添加初始化的fragmentt(s)。

當處理那些fragment的時候,特别是運作時做添加動作時,有一個重要的規定:fragment必須有一個容器

View

 來裝它。(例如使用LinearLayout等container來包裝那個fragment)

下面的layout示例是上一節課的内容。示例使用了一個空的FrameLayout來扮演那個fragment的container。(友善後面添加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()

 來獲得一個 

FragmentManager

。然後執行 

beginTransaction()

 來建立 

FragmentTransaction

 ,最後執行 

add()

 來添加一個fragment。

你可以使用同一個 

FragmentTransaction

.來預設多個fragment的切換。當你準備想要執行那些設定時,你必須執行 

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);

        // Check that the activity is using the layout version with
        // the fragment_container FrameLayout
        if (findViewById(R.id.fragment_container) != null) {

            // However, if we're being restored from a previous state,
            // then we don't need to do anything and should return or else
            // we could end up with overlapping fragments.
            if (savedInstanceState != null) {
                return;
            }

            // Create an instance of ExampleFragment
            HeadlinesFragment firstFragment = new HeadlinesFragment();
            
            // In case this activity was started with special instructions from an Intent,
            // pass the Intent's extras to the fragment as arguments
            firstFragment.setArguments(getIntent().getExtras());
            
            // Add the fragment to the 'fragment_container' FrameLayout
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.fragment_container, firstFragment).commit();
        }
    }
}      

因為這個fragment是在運作時被添加到 

FrameLayout

 container ,而不是上一節課的定義XML的方式。是以activity可以做移除與置換fragment的動作。 

Replace One Fragment with Another [置換fragment]

置換fragment的流程與添加fragment是類似的,僅僅需要使用

replace()

 來替代 

add()

當你執行fragment的置換或者移除等切換動作時請注意:因為使用者很可能想做後退與撤銷的動作,為了讓使用者能夠回退到之前的狀态,你必須在你commit FragmentTransaction 之前執行 

addToBackStack()。

Note: 當你執行移除或者置換操作并且把這個動作添加到back stack的時候,被移除的fragment并沒有被銷毀而是stopped狀态。如果使用者執行回退的操作來恢複那個fragment,它會被restart。如果你沒有把那個動作添加到back stack,那麼fragment會被銷毀。

下面是fragment的置換示例:

// Create fragment and give it an argument specifying the article it should show
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();      

這個

addToBackStack()

 的方法會需要一個可選的string參數來指定這個特定的動作。除非你需要使用FragmentManager.BackStackEntry 的API來做一些更加進階複雜的操作,一般是不需要傳遞的。

學習自:https://developer.android.com/training/basics/fragments/fragment-ui.html,謝謝!

轉載請注明出自:http://blog.csdn.net/kesenhoo,謝謝!