FragmentManager类允许你的在运行期间向你的Activity中增加,移除和替换Fragment来提供一种动态体验

在运行期间向你的Activity添加Fragment

  • 相比于在布局文件中用 fragment标签来为你的Activity定义fragment。你可以在运行期间向Activity添加fragment
  • 为了能执行像添加或者移除一个fragment的操作。你必须使用FragmentManger来创建一个FragmentTransaction,它提供相应的API来来添加,移除,替换,并且执行其他fragment的任务。
  • 如果你的activity允许fragments能够被移除和替换,你应该在activity的oncrease()方法中向activity中添加初始的fragment
  • 对于fragments一个重要的规则-特别是在运行期间添加fragments-你的布局里必须包含一个可以插入fragment的容器view
  • 接下来的布局是对上面课程中布局的一个替代(上节课程每次只能展示一个fragment)。为了能够用一个fragment替换另外一个fragment,这次Activity布局中包含一个空的FrameLayout来扮演fragment的容器
<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中,调用getSupportFragmentManger()来获得FragmentManger,然后调用beginTransaction()函数来创建FragmentTransaction并且调用add()函数来添加一个fragment。用同一个FragmentTransaction你可以对activity中的fragment进行多种操作。当你准备让某些改变生效时,你必须调用commit()函数。
比如:

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 a new Fragment to be placed in the activity layout 
            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在运行期间被添加到frame layout容器中,而不是在activity的布局中用fragment标签定义的,所以activity能够将fragment移除并且用另一个fragment替换

用一个fragment替换另一个

  • 替换fragment的过程跟添加一个fragment的过程很相似,但是需要用replace()函数而不是add()函数。
  • 记住,当你执行fragment的事务时,比如替换或者移除一个fragment,最好能允许用户能够导航回去或者撤销操作。为了达到这个目的,你必须在提交FragmentTransaction之前调用addToBackStack()函数。
    注意:当你移除或者替换一个fragment并且将这个事务添加到back stack中,这个被移除的fragment是不停止了stopped(而不是destroyed)。如果用户返回来恢复这个fragment,它会重新启动。如果不这样(添加transaction到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类型的参数用来给transaction确定个名称。这个参数不是必须的除非你打算用FragmentManger.BackStackEntry API来进行更高级的操作。