Building a Flexible UI
當把你的程序設計成可以適配一系列大小各異的屏幕時,你可以基於可使用的屏幕空間來爲你的fragments設置不同的參數,從而達到重用的目的。
例如:在手持設備上,一次顯示一個fragment會比較合適。對應的,在平板這樣屏幕比較大的設備上,你可以用多個fragment的方式來呈現出side-by-side的效果。這樣能夠一次顯示更多的信息給用戶。如下圖所示:
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,謝謝!