有关回滚——FragmentTransaction
回滚指的是返回上一次commit的状态,注意是commit,你的一次commit被记录为一次操作状态,即便你再这次commit里add、remove、replace、attach、detach了很多次,但是这一连串的操作只有一个commit的话,他们都作为一个状态被保存在栈中
这里我们着重讲一下,回退是以commit()提交的一次事务为单位的,而不是以其中的add,replace等等操作为单位回退的,即,如果我们在一次提交是添加了fragment2,fragment3,fragment4,那么回退时,会依据添加时的顺序,将它们一个个删除,返回到没有添加fragment4,fragment3,fragment2的状态。
在transaction.commit()之前,使用addToBackStack()将其添加到回退栈中。
transaction.addToBackStack(String tag);
在需要回退时,使用popBackStack()将最上层的操作弹出回退栈。
manager.popBackStack();
当栈中有多层时,我们可以根据id或TAG标识来指定弹出到的操作所在层。函数如下:
void popBackStack(int id, int flags);
void popBackStack(String name, int flags);
其中
- 参数int id是当提交变更时transaction.commit()的返回值。
- 参数string name是transaction.addToBackStack(String tag)中的tag值;
- 至于int flags有两个取值:0或- FragmentManager.POP_BACK_STACK_INCLUSIVE;
- 当取值0时,表示除了参数一指定这一层之上的所有层都退出栈,指定的这一层为栈顶层;
- 当取值POP_BACK_STACK_INCLUSIVE时,表示连着参数一指定的这一层一起退出栈;
detach():会将view与fragment分离,将此将view从viewtree中删除!而且将fragment从Activity的ADD队列中移除!所以在使用detach()后,使用fragment::isAdded()返回的值是false;但此fragment实例并不会删除,此fragment的状态依然保持着使用,所以在fragmentManager中仍然可以找到,即通过FragmentManager::findViewByTag()仍然是会有值的。
attach():显然这个方法与detach()所做的工作相反,它一方面利用fragment的onCreateView()来重建视图,一方面将此fragment添加到ADD队列中;这里最值得注意的地方在这里:由于是将fragment添加到ADD队列,所以只能添加到列队头部,所以attach()操作的结果是,最新操作的页面始终显示在最前面!这也就解释了下面的例子中,为了fragment2 detach()后,当再次attach()后,却跑到了fragment3的前面的原因。还有,由于这里会将fragment添加到Activity的ADD队列中,所以在这里调用fragment::isAdded()将返回True;
调用attach方法后,会把重建这个fragment的实例,并将其放到栈顶,这点与show()方法不一样
获取回退栈里的Fragment的方法,记住每commit一次,就会加入一个回退栈(你调用了addtostack方法),所以说一直回退,一直都有
TextView tv = (TextView) findViewById(R.id.tv_stack_val);
FragmentManager manager = getSupportFragmentManager();
int count = manager.getBackStackEntryCount();
StringBuilder builder = new StringBuilder("回退栈内容为:\n");
for (int i = --count;i>=0;i--){
FragmentManager.BackStackEntry entry= manager.getBackStackEntryAt(i);
builder.append(entry.getName()+"\n");
}
tv.setText(builder.toString());
系统BUG——add()和replace()千万不要共用!!!
主要在replace的时候,并没有清掉所有的回退栈,出现了bug
Fragment参数传递
把参数传递进Fragment
为何不使用构造方法传递参数,而是使用Fragment.setArguments(Bundle bundle)
详见Android解惑 - 为什么要用Fragment.setArguments(Bundle bundle)来传递参数
摘要:通过上面的分析,我们可以知道Activity重新创建时,会重新构建它所管理的Fragment,原先的Fragment的字段值将会全部丢失,但是通过Fragment.setArguments(Bundle bundle)方法设置的bundle会保留下来。所以尽量使用Fragment.setArguments(Bundle bundle)方式来传递参数
传递进去 setArguments
public static Fragment2 newInstance(String arg) {
Bundle args = new Bundle();
args.putString(DATA1, arg);
Fragment2 fragment = new Fragment2();
fragment.setArguments(args);
return fragment;
}
得到 getArguments
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
View view = inflater.inflate(getLayout(), container, false);
Bundle arguments = getArguments();
if (arguments != null) {
mS = arguments.getString(DATA1);
mTv.setText(mS);
}
return view;
}
最后
今天关于面试的分享就到这里,还是那句话,有些东西你不仅要懂,而且要能够很好地表达出来,能够让面试官认可你的理解,例如Handler机制,这个是面试必问之题。有些晦涩的点,或许它只活在面试当中,实际工作当中你压根不会用到它,但是你要知道它是什么东西。
最后在这里小编分享一份自己收录整理上述技术体系图相关的几十套腾讯、头条、阿里、美团等公司20年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。
还有 高级架构技术进阶脑图、Android开发面试专题资料,高级进阶架构资料 帮助大家学习提升进阶,也节省大家在网上搜索资料的时间来学习,也可以分享给身边好友一起学习。
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
【算法合集】
【延伸Android必备知识点】
【Android核心高级技术PDF文档,BAT大厂面试真题解析】
[外链图片转存中…(img-IDhZUWE9-1718875089552)]
【算法合集】
[外链图片转存中…(img-WKAOGnFB-1718875089553)]
【延伸Android必备知识点】
[外链图片转存中…(img-sFtSwfLR-1718875089553)]