声明
该文章只作为一个笔记,排版杂乱,看文前慎重!
Fragment的用法及其生命周期
相关链接:
Fragment 的静态生命周期
Fragment 动态添加
注意:
- 第一次的动态添加使用add,接下来的使用replace.
- 除了onCreateView,其他的所有生命周期方法如果你重写了,必须调用父类对于该方法的实现。
我的总结
生命周期测试
Fragment动态显示主要有两种方式
- 通过 replace、add方法动态添加
//替代Fragment
void replaceFragment1(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.three_activity_fragment_layout, fragment);
transaction.commit();
}
//此时按返回键会将Fragment最上层的出栈,而不是退出活动
// 此种方法下Fragment如果
void replaceFragment2(Fragment fragment) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.three_activity_fragment_layout, fragment);
transaction. addToBackStack(null);//添加到栈中
transaction.commit();
}
/**
假设有FragmentA和FragmentB
在此种方法下
如果 当前显示是FragmentA ,此时调用replaceFragment2替换 Fragment A,此时FragmentA的生命周期不会有任何变化,但是如果此时按返回键返回的仍然是FragmentA。
如果当前显示是FragmentA,此时调用replaceFragment2替换FragmentB,此时FragmentA的生命周期走到onDetech,FragmentB从onAttach走到onResume,之后如果按下返回键,此时FragmentB生命周期走到onDetech,FragmentA生命周期从onAttchch走到onResume,由此可以看出,在此种方法下,Fragment每次入栈出栈,都是判断当端下一个位于栈顶的Fragment是否与当前Fragment相同,如果不同,则销毁当前栈顶Fragment,并且创建新的Fragment,如果相同,则Fragment生命周期无变化
**/
//添加Fragment
//注意,如果Fragment已经添加了,再次添加会报错
//如果添加了多个就会产生重叠,因为Fragment的特性就是每次添加的布局都在页面左上角
//
// Fragment already added: Test1Fragment
void addFragment(Fragment fragment){
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.add(R.id.three_activity_fragment_layout,fragment);
transaction.commit();
}
2.
# 活动ThreeActivity创建,且在ThreeActivity中动态添加了Test1Fragment
com.example.applicationtest I/ThreeActivity: onCreate: test3
com.example.applicationtest I/Test1Fragment: onAttach: test3
com.example.applicationtest I/ThreeActivity: onAttachFragment: test3
com.example.applicationtest I/Test1Fragment: onCreate: test3
com.example.applicationtest I/Test1Fragment: onCreateView: test3
com.example.applicationtest I/Test1Fragment: onActivityCreated: test3
com.example.applicationtest I/Test1Fragment: onStart: test3
com.example.applicationtest I/ThreeActivity: onStart: test3
com.example.applicationtest I/ThreeActivity: onResume: test3
com.example.applicationtest I/Test1Fragment: onResume: test3
# 从上可以看出Fragment生命周期是受到Activity影响的,
#Activity的onAttchFragment是在Fragment的onAttch之后调用的
# 点击按钮切换成Test2Fragment
# 可以 看到Test1在被替换后,其生命周期走向了onDestroy,但是还没有走到oDetech
com.example.applicationtest I/Test2Fragment: onAttach: test3
com.example.applicationtest I/ThreeActivity: onAttachFragment: test3
com.example.applicationtest I/Test2Fragment: onCreate: test3
com.example.applicationtest I/Test1Fragment: onPause: test3
com.example.applicationtest I/Test1Fragment: onStop: test3
com.example.applicationtest I/Test1Fragment: onDestroyView: test3
com.example.applicationtest I/Test1Fragment: onDestroy: test3
com.example.applicationtest I/Test2Fragment: onCreateView: test3
com.example.applicationtest I/Test2Fragment: onActivityCreated: test3
com.example.applicationtest I/Test2Fragment: onStart: test3
com.example.applicationtest I/Test2Fragment: onResume: test3
Fragment布局应用及其要点
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
Log.i(TAG, "onCreateView: test3");
View view=inflater.inflate(R.layout.fragment_test1,container,false);
//此处attachToRoot,不能为true,否则会报错
return view;
}
如上代码所示,在onCreateView中引入布局,但是要注意attachToRoot参数必须是为false,否则会报错,在调用onStart提示 child已经有了parent.
The specified child already has a parent. You must call removeView() on the child's parent first.
Fragment 更好的切换方法
Fragment 使用hide和show,使用onHiddenChanged代替执行生命周期_移动开发_Losileeya-CSDN博客
show,hide方法
为了避免布局的重复创建和加载,采用如下方式,能够更好更快的切换布局,此种方法不会走Fragment的生命周期
/**
* 修改显示的内容 不会重新加载
* to 下一个fragment
* mContent 当前的fragment
*/
private void switchContent(Fragment to) {
if (mContent != to) {
FragmentTransaction transaction = fragmentManager.beginTransaction();
if (!to.isAdded()) { // 判断是否被add过
// 隐藏当前的fragment,将 下一个fragment 添加进去
transaction.hide(mContent).add(R.id.layout_content, to).commit();
} else {
// 隐藏当前的fragment,显示下一个fragment
transaction.hide(mContent).show(to).commit();
}
mContent = to;
}
}
为了监听Fragment的状态转换,可以重写Fragment的onHinddenChanged方法,通过判断Fragment是否隐藏,手动模式生命周期的onPause,onResume。 onHiddenChanged方法
@Override
public void onHiddenChanged(boolean hidden) {
super.onHiddenChanged(hidden);
if (hidden) { // 不在最前端显示 相当于调用了onPause();
return;
}else{ // 在最前端显示 相当于调用了onResume();
//网络数据刷新
}
}