动态添加Fragment到页面上需要使用到FragmentManager. 顾名思义,就是一个管理器,用来管理Fragment. FragmentManager常用的方法有:
(1) findViewById()或findViewByTag(): 获得已经在Activity中存在的Fragment.
(2) beginTransaction(): 获得一个Fragment的事务对象,这个事务对象可以向窗口中添加,替换,移除Fragment.
(3) popBackStack(): 将回退栈中栈顶的操作弹出, 如果没有的话,返回false.
(4) addOnBackStackChangedListener(): 为Back Stack添加监听器.
一.开始动态添加Fragment
首先,需要准备一个Fragment,暂且命名为FragmentOne.简单的修改背景颜色和添加一个按钮:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ff0000">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click"
android:id="@+id/btn_frag_one_click"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
接着,新建一个类继承自Fragment,复写onCreateView()方法:
public class FragmentOne extends Fragment{
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_one, null);
return view;
}
在Activity的布局中,为布局添加一个id就可以了:
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/lay"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
随后,将FragmentOne添加进Activity中,这一步可以分为五个小步:
(1) 创建一个Fragment的对象.(这里是得到一个FragmentOne的对象)
(2) 获得一个FragmentManager对象,在活动中可以直接通过getFragmentManager()方法获得.
(3) 通过FragmentManager对象的beginTransaction()方法开启一个事务.
(4) 使用replace()或者add()方法将Fragment加入事务中.
(5) 提交事务.
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
FragmentOne one = new FragmentOne();
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.add(R.id.layout, one);
transaction.addToBackStack(null);//将事务加入到返回栈中
transaction.commit();
}
}
这样就完成了动态添加Fragment的目标.
二.replace()与add()方法区别
replace()与add()方法在显示上是没有区别的,主要的区别是: replace()是move掉容器中的其它Fragment,然后将自己add进去.add()没有move的步骤,只是单纯的add.所以,尽管它们显示是一样的(因为显示的都是最上层的Fragment).但是,使用add()方法实际上它是有很多层叠加在一起的.而replace()方法添加的Fragment只有一层.
因此,通常情况下推荐使用replace(),有利于节约资源.
三. 模拟返回栈
在Fragment中也可以模拟Activity中返回栈的效果,只需要使用transaction.addToBackStack(null)方法就可以.为此,我们再新建一个FragmentTwo(与FragmentOne相同,只要改个名字就可以了).接着,在Fragment中获取布局文件中的按钮,并为按钮添加单击事件,在单击事件中将FragmentTwo添加进容器中.记住要为FragmentOne和FragmentTwo添加transaction.addToBackStack(null)方法.
public class FragmentOne extends Fragment{
private Button mFOneClick;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.frag_one, null);
mFOneClick = (Button) view.findViewById(R.id.btn_frag_one_click);
mFOneClick.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
FragmentTwo fragment = new FragmentTwo();
FragmentManager manager = getFragmentManager();
FragmentTransaction transaction = manager.beginTransaction();
transaction.replace(R.id.lay, fragment);
<span style="color:#FF0000;">transaction.addToBackStack(null);</span>
transaction.commit();
}
});
return view;
}
随后,在Activity中复写onKeyDown方法.
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
FragmentManager manager = getFragmentManager();
// 条件1:判断点击的是返回键.条件2:判断返回栈是否为空
if(keyCode == KeyEvent.KEYCODE_BACK && manager.getBackStackEntryCount() > 0) {
manager.popBackStack();
return true;
}else {
return super.onKeyDown(keyCode, event);
}
}
这样,就完成了通过点击按钮从FragmentOne切换到FragmentTwo,随后通过Back键从FragmentTwo返回到FragmentOne