
public interface BackHandleInterface {
void onSelectedFragment(BackHandleFragment backHandleFragment)
}
2、创建一个自定义Fragment类
public abstract class BackHandleFragmentextends BaseFragment{
private BackHandleInterfacebackHandleInterface
/**
* 所有继承BackHandledFragment的子类都将在这个方法中实现物理Back键按下后的逻辑
* FragmentActivity捕捉到物理返回键点击事件后会首先询问Fragment是否消费该事件
* 如果没有Fragment消息时FragmentActivity自己才会消费该事件
*/
public abstract boolean onBackPressed()
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState)
if(getActivity()instanceof BackHandleInterface){
this.backHandleInterface = (BackHandleInterface)getActivity()
}else{
throw new ClassCastException("Hosting Activity must implement BackHandledInterface")
}
}
@Override
public void onStart() {
super.onStart()
backHandleInterface.onSelectedFragment(this)
}
}
3、在fragment的容器Activity中
1)声明变量属性
private BackHandleFragmentbackHandleFragment
2)activity实现接口(implements BackHandleInterface),重写回调方法
@Override
public void onSelectedFragment(BackHandleFragment backHandleFragment) {
this.backHandleFragment = backHandleFragment
}
3)重写onKeyDown()方法
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
//if判断里面就调用了来自Fragment的onBackPressed()
//一样!!,如果onBackPressed是返回false,就会进入条件内进行默认的 *** 作
if(backHandleFragment ==null || !backHandleFragment.onBackPressed()){
if(getSupportFragmentManager().getBackStackEntryCount() ==0){
/**
* 按返回键直接返回桌面,监听返回键,防止按了音量键也返回桌面
*/
if (keyCode == KeyEvent.KEYCODE_BACK){
Intent intent =new Intent(Intent.ACTION_MAIN)
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP)
intent.addCategory(Intent.CATEGORY_HOME)
startActivity(intent)
return true
}
}
}
return super.onKeyDown(keyCode, event)
}
4、fragment继承自定义fragemnt,重写回调方法onBackPressed()
tip:因为我的项目中fragment是包含整个webview,需求是点击返回后,webview如果可以返回上一个页面就返回上一个页面
@Override
public boolean onBackPressed() {
if (webView.canGoBack()){
webView.goBack()
return true
}else {
return false
}
}
Fragment必须总是被嵌入到一个activity之中,并且fragment的生命周期直接接受其宿主activity的生命周期的影响。你可以认为fragment是activity的一个模块零件,它有自己的生命周期,接收它自己的输入的事件,并且可以在activity运行时添加或者删除。
应该将每一个fragment设计为模块化和可复用化的activity组件。也就是说,你可以在多个activity中引用同一个fragment,因为fragment定义了它自己的布局,并且使用它本身生命周期回调的行为。
Fragment比Activity多了几个额外的生命周期回调方法:
管理fragment生命周期与管理activity生命周期很相像,像activity一样,fragment也有三种状态:
1、Resumed:
fragment在运行中的activity中可见。
2、Paused:
另一个activity处于前台且得到焦点,但是这个fragment所在的activtiy仍然可见(前台activity部分透明,或者没有覆盖全屏)。
3、Stopped:
fragment不可见。要么宿主activity已经停止,要么fragment已经从activity上移除,但已被添加到后台栈中。一个停止的fragment仍然活着(所有的状态和成员信息仍然由系统保留着)。但是,它对于用户来讲已经不再可见,并且如果activity被杀掉,它也将被杀掉。
如果activity的进程被杀掉了,在activity被重新创建时,你恢复fragment状态。可以执行fragment的onSaveIntanceState()来保存状态(注意:fragment是在onCreate(),onCreateView()或者onActivityCreate()中进行恢复)。
在生命周期方面,activity和fragment之间一个很重要的不同就是在各自的后台栈中是如何存储的。当activity停止时,默认情况下activity被安置在由系统管理的activity后台栈中;fragment仅当在一个事务被移除时,通过显式调用addToBackStack()请求保存的实例,该fragment才被置于由宿主activity管理的后台栈。
类似与Android系统为Activity维护一个任务栈,我们也可以通过Activity维护一个回退栈来保存每次Fragment事务发生的变化。
如果你将Fragment任务添加到回退栈,当用户点击后退按钮时,将看到上一次的保存的Fragment。一旦Fragment完全从后退栈中d出,用户再次点击后退键,则退出当前Activity。
通过Arguments创建Fragment,不建议通过为Fragment添加带参数的构造函数
1、FragmentPagerAdapter:对于不再需要的fragment,选择调用detach方法,仅销毁视图,并不会销毁fragment实例。
2、FragmentStatePagerAdapter:会销毁不再需要的fragment,当当前事务提交以后,会彻底的将fragment从当前Activity的FragmentManager中移除。
3、懒加载,核心方法是 setUserVisibleHint()
原因1:横竖屏切换,造成Fragment重新实例化。
原因2:按下Home键,Activity处于后台,由于内存不足被销毁,重新唤醒时Fragment重新实例化。
注:出现的原因是在 API24 之前的 v4包 的源码问题,
解决方案:通过检查onCreate的参数Bundle savedInstanceState就可以判断,当前是否发生Activity的重新创建:
默认的savedInstanceState会存储一些数据,只有在savedInstanceState==null时,才进行创建Fragment实例:
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)