Building a Flexible UI
當把你的程式設計成可以适配一系列大小各異的螢幕時,你可以基于可使用的螢幕空間來為你的fragments設定不同的參數,進而達到重用的目的。
例如:在手持裝置上,一次顯示一個fragment會比較合适。對應的,在平闆這樣螢幕比較大的裝置上,你可以用多個fragment的方式來呈現出side-by-side的效果。這樣能夠一次顯示更多的資訊給使用者。如下圖所示:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL4IDO48FN4IDN5ADN1MTMvwFOy8CXxEjMxAjMvw1ckF2bsBXdvwFdl5mLuR2cj5Set1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
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,謝謝!