Fragment、FragmentActivity、Fragment生命周期及Fragment组件穿透

-- 单Activity+多Fragment 或者 多模块Activity+多Fragment的架构, Fragment管理框架

单Activity+多Fragment 或者 多模块Activity+多Fragment的架构,重度使用Fragment或者想使用单Activity+多Fragment的组件架构- https://github.com/YoKeyword/Fragmentation

PagerBottomTabStrip完成底部的page滑动效果
An bottom navigation bar for Android- https://github.com/tyzlmjj/PagerBottomTabStrip

Android官方架构组件Navigation:大巧不工的Fragment管理框架-https://www.jianshu.com/p/ad040aab0e66
Fragment管理框架- https://github.com/googlecodelabs/android-navigation
A powerful library that manage Fragment for Android- https://github.com/YoKeyword/Fragmentation
Fragment切换方法的封装- https://github.com/Yumenokanata/FragmentManager

-- java.lang.IllegalStateException: Fragment already added异常的处理?
当快速双击调用FragmentTransaction.add()方法添加fragmentA,而fragmentA不是每次单独生成的,就会引起这个异常。
  DialogFragment.show()内部调用了FragmentTransaction.add()方法,所以调用DialogFragment.show()方法时候也可能会出现这个异常。
  在add()方法时候,先判断fragmentA.isAdded(),如下调用可以避免该异常:
if(!fragmentA.isAdded()){
                    FragmentManager manager = ((FragmentActivity)context).getSupportFragmentManager();
                    FragmentTransaction ft = manager.beginTransaction();
                    ft.add(fragmentA, "fragment_name");
                    ft.commit();
}

可以使用setter和getter Fragment的属性方法进行数据的存储和获取。

-- 在Fragment的生命周期中,有一下方法会被回调:
  · onAttach():当Fragment被添加到Activity时被回调,只回调一次。
  · onCreate(Bundle savedStatus):创建Fragment时被回调,一次。
  · onCreateView(): 每次创建、绘制该Fragment的View组件时回调,Fragment将会显示该方法返回的View组件。
  · onActivityCreated():Fragment所在的Activity启动完成后回调。
  · onStart():每次启动或恢复Fragment时被回调。
  · onResume():每次启动或恢复Fragment时被回调,onStart()回调后就会回调此方法。
  · onPause():暂停时回调。
  · onStop():停止Fragment时回调。
  · onDestroyView():销毁Fragment的View组件时回调。
  · onDestroy():销毁Fragment时调用,一次。
  · onDetach():将Fragment从Activity中删除、被替换完成时回到该方法,在onDestroy()之后回调。
  根据以上方法被回调的时机,我们可以根据需要选择性的覆盖指定方法。从而实现相关需求。

-- how to use Fragment

Fragment全解析系列(一):那些年踩过的坑- https://www.jianshu.com/p/d9143a92ad94
Fragment全解析系列(二):正确的使用姿势- https://www.jianshu.com/p/fd71d65f0ec6
 发生Fragment重叠的根本原因在于FragmentState没有保存Fragment的显示状态,即mHidden,导致页面重启后,该值为默认的false,即show状态,所以导致了Fragment的重叠。
public class BaseFragment extends Fragment {
    private static final String STATE_SAVE_IS_HIDDEN = "STATE_SAVE_IS_HIDDEN";

    @Override
    public void onCreate(@Nullable Bundle savedInstanceState) {
    ...
    if (savedInstanceState != null) {
        boolean isSupportHidden = savedInstanceState.getBoolean(STATE_SAVE_IS_HIDDEN);

        FragmentTransaction ft = getFragmentManager().beginTransaction();
        if (isSupportHidden) {
            ft.hide(this);
        } else {
            ft.show(this);
        }
        ft.commit();
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        ...
        outState.putBoolean(STATE_SAVE_IS_HIDDEN, isHidden());
    }
}

 由Activity/父Fragment来管理子Fragment的Hidden状态转变为 由Fragment自己来管理自己的Hidden状态!
 优点:不管多深的嵌套Fragment、同级Fragment等场景,全都可以正常工作,不会发生重叠!
 官方在Support 24.0.0及以上版本已经从底层使用该方式修复该BUG;如果你还在使用 < 24.0.0 的版本,还是需要这 ”9行代码“的~

  Fragment是可以让你的app纵享丝滑的设计,如果你的app想在现在基础上性能大幅度提高,并且占用内存降低,同样的界面Activity占用内存比Fragment要多,响应速度Fragment比Activty在中低端手机上快了很多,甚至能达到好几倍!如果你的app当前或以后有移植平板等平台时,可以让你节省大量时间和精力。

-- Fragment的坑:
1、getActivity()空指针
2、异常:Can not perform this action after onSaveInstanceState
3、Fragment重叠异常-----正确使用hide、show的姿势
4、Fragment嵌套的那些坑
5、未必靠谱的出栈方法remove()
6、多个Fragment同时出栈的深坑BUG
7、深坑 Fragment转场动画

-- FragmentPagerAdapter与FragmentStatePagerAdapter使用详解与区别
 1.FragmentPagerAdapter不会销毁Fragment, 适用于那些相对静态的页,数量也比较少的那种
 2.如果需要处理有很多页,并且数据动态性较大、占用内存较多的情况,应该使用FragmentStatePagerAdapter,会销毁不需要的Fragment,当拥有大量的页面时,不必在内存中占用大量的内存,更省内存。

-- 浅谈Android中的 Fragment、生命周期回调方法 以及使用- http://blog.csdn.net/gjy_it/article/details/52150773

* support v4 FragmentActivity 兼容2.x模式下使用Fragment;
* support v7 AppCompatActivity 兼容2.x模式下使用Fragment和ActionBar,ActionBarActivity是AppCompatActivity过时产品;

* 如果3.0以上直接继承Activity,便可使用Fragment和ActionBar.

FragmentActivity、AppCompatActivity与Activity中使用ViewPager?

V4包下,FragmentStatePagerAdapter 和FragmentPagerAdapter 一样,是继承子 PagerAdapter。

-- getActivity()与getContext()的区别:
getActivity() 相当于this 或者 Activity.this,是获取当前Activity的实例,生命周期随当前的Activity销毁而销毁;
getContext() 获取当前context的实例(如果使用场景是Activity则相当于 this, 如果使用场景是一个Server 那么获取的实例就是
一个ApplicationContext())
 1.MainActivity.this:表示MainActivity对象,一般用在内部类中指示外面的this,如果在内部类直接用this,指示的是内部类本
身。因为MainActivity继承Activity,而Activity继承Context,所以它也可以用来提供Activity Contex;
 2.this:表示当前对象;一般而言,在哪个类中调用,就是指向该对象。
 3.getContext():这个是View类中提供的方法,在继承了View的类中才可以调用,返回的是当前View运行在哪个Activity Context
中。
 4.getActivity():获得Fragment依附的Activity对象。Fragment里边的getActivity()不推荐使用原因如下:这个方法会返回当前
Fragment所附加的Activity,当Fragment生命周期结束并销毁时,getActivity()返回的是null,所以在使用时要注意判断null或者
捕获空指针异常。
-- Fragment中getActivity()和getContext()为空的问题
 你在调用了getActivity()时,当前的Fragment已经onDetach()了宿主Activity。比如:你在pop了Fragment之后,该Fragment的异
步任务仍然在执行,并且在执行完成后调用了getActivity()方法,这样就会空指针。

if (isTelephoneFragment(currFragment.getType())) {
                    FragmentTransaction ft.remove(currFragment);
                } else {
                    ft.hide(currFragment);
                }
                if (fragment.isAdded()) {
                    ft.show(fragment);
                } else if (fragment.isDetached()) {
                    ft.attach(fragment);
                }
ft.commitAllowingStateLoss();

-- Android Fragment- onDestroyView() onDestroy(), Fragment的生命周期
在Fragment里重写onDestroyView,保存这个页面View的,返回这页时;际使用时,先把view从fragment移除,这样做 ((ViewGroup) getView()).remove(v),这样v就不会被销毁了;移除要放在super.onDestroyView()前执行;

Fragment onDestroyView()与onCreateView()生命周期对应么? No.
onCreateView()对应 onDestroy().

完整的Fragment的生命周期是:
onAttach() --> onCreate() --> onCreateView() --> onActivityCreated() -->
onStart() --> onResume() --> onPause() --> onStop() -->
onDestroyView() --> onDestroy() --> onDetach()

 启动Fragment时,经过的生命周期函数:
onAttach() --> onCreate() --> onCreateView() --> onActivityCreated() --> onStart() --> onResume()
 当锁屏时,Fragment消失,经过的生命周期函数:
onPause() --> onStop()
 当屏幕解锁时,Fragment又出现,经过的生命周期函数是:
onStart() --> onResume()

当从一个Fragment上切换到另一个Fragment时的生命周期变化是:
 第一个Fragmrnt经历的生命周期是 :
onPause() --> onStop() --> onDestroyView() --> onDestroy() --> onDetach() 
 第二个Fragment经历的生命周期是:
onAttach() --> onCreate() --> onCreateView() --> onActivityCreated() --> onStart() --> onResume()

> Fragment,FragmentActivity与Activity:
  fragment是3.0以后的东西,为了在低版本中使用fragment就要用到android-support-v4.jar兼容包,而fragmentActivity就是这个兼容包里面的,它提供了操作fragment的一些方法,其功能跟3.0及以后的版本的Activity的功能一样。
  下面是API中的原话:FragmentActivity is a special activity provided in the Support Library to handle fragments on system versions older than API level 11. If the lowest system version you support is API level 11 or higher, then you can use a regular Activity.
  1.FragmentActivity 继承自activity,用来解决android3.0 之前没有fragment的api,所以在使用的时候需要导入support包,同时继承fragmentActivity,这样在activity中就能嵌入fragment来实现你想要的布局效果。 
  2.当然3.0之后你就可以直接继承自Activity,并且在其中嵌入使用fragment了。 
  3.获得Manager的方式也不同 ,3.0以下:getSupportFragmentManager() ;3.0以上:getFragmentManager()

-- android.support.v4.app.Fragment和android.app.Fragment区别
1. android.app.Fragment 兼容的最低版本是android:minSdkVersion="11" 即3.0版
android.support.v4.app.Fragment 兼容的最低版本是android:minSdkVersion="4" 即1.6版
 2.  android.support.v4.app.Fragment使用  fragmentManager=getSupportFragmentManager()获得 ,并且当前的类必须继
FragmentActivity

android.app.Fragment使用 fragmentManager=getFragmentManager() 获得  ,继承Activity即可。
 3. v4包中的Fragment在Activity的布局中是可以使用<fragment>标签的,有些博客中也叫静态地载入fragment。

android.app.Fragment在Activity布局中是不可以使用<fragment>标签的,需要在程序中通过add或者replace的方式添加。

总结起来
就是:当这个Activity的布局中有fragment标签的时候,这个Activity必须继承FragmentActivity,也就是使用V4包的fragment,否
则就会抛出android.view.InflateException: Binary XML file line #69: Error inflating class fragment异常。

>【Activity的生命周期】与Fragment的生命周期:

     Activity                  Fragment

1.【onCreate()】    onAttach(),onCreate(),onCreateView(),onActivityCreated()
2.【onStart()】       onStart()
3.【onResume()】 onResume()
4.【onPause()】    onPause()
5.【onStop()】       onStop()

6.【onDestroy()】   onDestroyView(),onDestroy(),onDetach()

-- Fragment与Activity的生命周期之间的联系
  http://www.cnblogs.com/mengdd/archive/2013/01/11/2856374.html
  http://blog.csdn.net/zjclugger/article/details/10442335
 当activity处于Resumed状态时,可以自由地添加和移除fragment,也即是说,只有activity在Resumed状态时,fragment的状态可以独立改变。但是,当activity离开Resumed状态,fragment的生命周期被activity控制。

>  Fragment Transactions & Activity State Loss,commit和commitAllowingStateLoss唯一的区别就是后者在状态丢失时候 不会抛出异常,通常不会使用这个方法,因为这将意味着状态的可能丢失。最好的方式就是写好你的应用,这样transaction确保在activity状态保存之后commit,这样用户体验会更好。除非状态丢失不可避免了,否则不要使用commitAllowingStateLoss()    关于getChildFragmentManager()、 getFragmentManager()、getSupportFragmentManager()的使用:
 android的v4扩展包中的FragmentActivity中获取FragmentManager使用的就是getSupportFragmentManager(),android.app中获取管理类的方法就是getFragmentManager()。

  需要管理相互独立的并且隶属于Activity的Fragment使用FragmentManager(),而在Fragment中动态的添加Fragment要使用getChildFragmetManager()来管理。

-- app包下FragmentManager用:Fragmentmanager fragmentManager=getFragmentManager();
v4包的FragmentManager用:FragmentManager fragmentManager=getSupportFragmentManager()获取;

  有时在使用getSupportFragmentManager()时,发现已经添加了v-4包支持,但是依旧找不到getSupportFragmentManager(),此时要注意是否是在Activity中使用,因为Activity中并没有此方法的定义,必须是继承FragmentActivity或者AppCompatActivity,然后使用。

> Fragment的类型有:DialogFragment;ListFragment;PreferenceFragment。

 不保存当前的Fragment时,使用Fragment.commitAllowingStateLoss()方法
      For example, if a news application has two fragments in an activity—one to show a list of articles (fragment A) and another to display an article (fragment B)—then fragment A must tell the activity when a list item is selected so that it can tell fragment B to display the article. In this case, the OnArticleSelectedListener interface is declared inside fragment A:
Fragment A通过Activity传输数据到Fragment B,实现机制:Fragment A定义一个interface,Activity去实现接口,并将返回通知给Fragment B。
将Activity的数据传给Fragment时,可以使用Bundle.
Also like an activity, you can retain the state of a fragment using a Bundle, in case the activity's process is killed and you need to restore the fragment state when the activity is recreated. You can save the state during the fragment'sonSaveInstanceState() callback and restore it during either onCreate(), onCreateView(), oronActivityCreated(). 
横竖屏切换时,Activity状态的保存。

-- Fragment碎片化
Fragment中XML Button设置Android:onClick="onClick"属性,不去手动设置id 和button.setOnClickListener(this),点击按钮,则会报错;需要手动找到Button的id及设置button.setOnClickListener(this)。
  Android 在 android 3.0 (API 级别 11)中引入了碎片,主要是为了给大屏幕(如平板电脑)上更加动态的和灵活的 UI 设计提供支持,由于平板电脑的屏幕比手机屏幕大太多,因此可用于组合和交换 UI 组件的空间更大,利用碎片实现此类设计时,你无需管理对视图层次结构的复杂更改,通过将 Activity 布局分成碎片,你可以在运行时修改 Activity 的外观,并在由 Activity 管理的返回栈中保留这些更改
  注意这里会有两个不同的包下的 Fragment 供我们选择,一个是系统内置的 andorid.app.Fragment,一个是 support - v4 库中的android.suppout.v4.app.Fragment,这里强烈建议大家使用 support - v4 库中的 Fragment ,因为它可以让 Fragment 在所有 Android系统版本中保持功能一致性
private void replaceFragment(Fragment fragment) {  
        //调用 getSupportFragmentManager() 方法获取 FragmentManager  
        FragmentManager fragmentManager = getSupportFragmentManager();  
        //通过 beginTransaction() 方法开启一个事务  
        FragmentTransaction fragmentTransaction = fragmentManager.beginTransaction();  
        //通过 replace() 方法向容器添加或替换 Fragment  
        fragmentTransaction.replace(R.id.frameLayout, fragment);  
        
         fragmentTransaction.addToBackStack(null); 
        //通过 commit() 方法来提交事务  
        fragmentTransaction.commit();  

    }  

> Fragment 比 Activity 多了几个生命周期回调方法
onAttach():当 Activity 与 Fragment 发生关联时调用
onCreateView():创建 Fragment 的视图
onActivityCreated():当 Activity 的 onCreate() 方法返回时调用,或者说当 Activity的onCreate() 方法执行完时调用
onDestroyView():与 onCreateView() 相对应,Fragment 中的布局被移除时调用
onDetach():与 onAttach() 相对应,当 Activity 与 Fragment 解除关联的时候调用

 Fragment 不和任何 Activity 耦合,任何Activity 都可以使用,并且我们声明了一个接口来回调其点击事件,想要管理其点击事件的 Activity 实现此接口就可以,我们在onClick() 方法中首先判断了当前绑定 Activity 是否实现了该接口
 1)在 Activity 中调用 Fragment 中的方法
  为了方便 Fragment 和 Activity 之间的通信,FragmentManager 提供了一个类似于 findViewById() 的方法,专门用于从布局文件中获取 Fragment 的实例,代码如下:
BottomFragment b = (BottomFragment) getSupportFragmentManager().findFragmentById(R.id.fragment_bottom);
 调用 getSupportFragmentManager() 的 findFragmentById() 方法,可以在活动中得到相应的 Fragment 实例,然后就可以调用 Fragment 中的 public 方法
 2)在 Fragment 中调用 Acitivity 中的方法
 掌握如何在 Activity 中调用 Fragment 中的方法,我们来学习如何在 Fragment 中调用 Activity 中的方法,其实在每个 Fragment中都可以调用 getActivity() 方法来得到和当前 Fragment 相关联的 Activity 的实例,代码如下:
MainActivity activity = (MainActivity) getActivity();  

 有了 Activity 实例以后,在 Fragment 中就可以调用 Activity 中的 public 方法,另外当 Fragment 中需要使用 Context 对象时,也可以使用 getActivity() 方法,因为获取到的 Activity 本身就是一个 Context 对象,如果该 Context 需要在 Activity 销毁后还存在,则可以使用 getActivity().getApplicationContext()。

-- fragment中的attach/detach方法Activity/Fragment onAttach() onDetach()
  使用add()加入fragment时将触发onAttach(),使用attach()不会触发onAttach();使用replace()替换后会将之前的fragment的view从viewtree中删除。
  触发顺序:
detach()->onPause()->onStop()->onDestroyView();
attach()->onCreateView()->onActivityCreated()->onStart()->onResume()

  使用hide()方法只是隐藏了fragment的view并没有将view从viewtree中删除,随后可用show()方法将view设置为显示
  而使用detach()会将view从viewtree中删除,和remove()不同,此时fragment的状态依然保持着,在使用attach()时会再次调用  onCreateView()来重绘视图,注意使用detach()后fragment.isAdded()方法将返回false,在使用attach()还原fragment后isAdded()会依然返回false(需要再次确认)
  执行detach()和replace()后要还原视图的话, 可以在相应的fragment中保持相应的view,并在onCreateView()方法中通过view的parent的removeView()方法将view和parent的关联删除后返回

>  Activity和Fragment的生命周期执行顺序- https://blog.csdn.net/eyishion/article/details/54318740
Activity和Fragment生命周期变化- https://www.cnblogs.com/gzdx-tjh/p/4923331.html
 - Activity和Fragment创建
Activity::onCreate;
Fragment::onAttach;Fragment::onCreate;Fragment::onCreateView;Fragment::onActivityCreate;
Activity::onStart;Fragment::onSatrt;
Activity::onResume;Fragment::onResume;
 - Activity和Fragment都会被销毁
Fragment::onPause;Activity::onPause;Fragment::onSaveInstanceState(保存销毁前的状态);
Fragment::onStop;Activity::onStop;
Fragment::onDestroyView;Fragment::onDestroy;Fragment::onDetach;Activity::onDestroy;

Fragment全解析系列(一):那些年踩过的坑- https://www.jianshu.com/p/d9143a92ad94
适合单Activity+多Fragment或者多模块Activity+多Fragment的架构- https://github.com/YoKeyword/Fragmentation
Square:从今天开始抛弃Fragment吧- http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0605/2996.html

> Fragmemt穿透

Fragmemt的生命周期,与Activity的生命周期的联系?
 ImageView点击事件穿透  ANdroid? Activity点击事件穿透  ANdroid?
fragment点击事件穿透解决方法:
 叠在一起的fragment上层会响应下层的按钮点击事件,而且还会响应activity中的点击事件。在每个fragment布局的根节点加一条android:clickable="true"可破。
 ImageView图片透明区域不响应点击事件,不规则图片透明区域响应点击事件- http://blog.csdn.net/aminfo/article/details/7872681

关于Fragment叠加点击穿透的解决方案- https://blog.csdn.net/xieluoxixi/article/details/53992251
Android通过hide&show管理多Fragment出现重叠以及点击穿透的解决之道- https://juejin.im/post/5cde90fc51882525a9439f05

-- Fragment中context,getActivity与getContext()
   在Activity中可以直接调用getApplicationContext(),Activity.this/context获取相应的context。
   在Fragment中的使用方式则为: 
1.getActivity();//获取包含该fragment的活动(activity)上下文 
2.getContext();//获取该fragment上下文 
3.getActivity().getApplicationContext();//通过包含该fragment的活动(activity)获取整个应用的上下文 
4.getContext().getApplicationContext();//通过该fragment获取整个应用的上下文
(在非特殊情况下(如:内存泄漏),这四种方式都可以正常使用,并且效果相同。)

-- 关于getContext()、getApplication()、getApplicationContext()、getActivity()的区别:
(1).getContext():获取到当前对象的上下文。
(2).getApplication():获得Application的对象
(3).getApplicationContext():获得应用程序的上下文。有且仅有一个相同的对象。生命周期随着应用程序的摧毁而销毁。就像是社会,所有的都发生在这个社会上,仅且只有一个社会。每个Activity都有自己的上下文,而整个应用只有一个上下文
(4)getActivity():获得Fragment依附的Activity对象。Fragment里边的getActivity()不推荐使用原因如下:这个方法会返回当前Fragment所附加的Activity,当Fragment生命周期结束并销毁时,getActivity()返回的是null,所以在使用时要注意判断null或者捕获空指针异常。所以只要判断getActivity()为空,就可以不再执行下面的代码,这完全不影响业务的使用。
> Fragment的理解与使用

【Android】Fragment之间数据传递的三种方式- https://www.jianshu.com/p/f87baad32662
Tab主界面Fragment+TabPageIndicator+ViewPager- http://blog.csdn.net/lmj623565791/article/details/24740977

Android Fragment 真正的完全解析(上)- http://blog.csdn.net/lmj623565791/article/details/37970961/
Android Fragment 你应该知道的一切- http://blog.csdn.net/lmj623565791/article/details/42628537/
Android开发技术点2——Fragment叠加点击穿透解决方案- http://blog.csdn.net/dong19870625/article/details/50550147
Activity和Fragment传递数据的两种方式- http://blog.csdn.net/b10060224/article/details/51325775

Fragment 事务 回退栈- https://www.cnblogs.com/baiqiantao/p/5414708.html
Android Fragment管理 解析- https://www.jianshu.com/p/1d0bec0800d2
fragment之添加回退栈- http://blog.csdn.net/lamp_zy/article/details/50266461
Fragment栈结构压栈弹栈以及Demo- http://blog.csdn.net/dorsey_c/article/details/50167713

这样引用android:name="com.example.wildcard.autovideoplayer.MainActivityFragment",可以执行Fragment(MainActivityFragment)类中的方法
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment"
    android:name="com.example.MainActivityFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:layout_behavior="@string/appbar_scrolling_view_behavior"
    tools:layout="@layout/fragment_main" />

> Fragment压栈和弹栈
void addFragmentToStack() {  
        Fragment newFragment = CountingFragment.newInstance(mStackLevel);  
        FragmentTransaction ft = getFragmentManager().beginTransaction(); 
//ft.hide(this); 
        ft.replace(R.id.simple_fragment, newFragment);  
        ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);  
        ft.addToBackStack(null);  
        ft.commit(); //压栈
    } 
getFragmentManager().popBackStack(); //弹栈

> Fragment的API
1.add(int containerViewId, Fragment fragment, String tag)把一个fragment添加到一个容器 container 里。
2.remove(Fragment fragment) remove是先remove掉相同id的所有fragment,然后在add当前的这个fragment。
3.replace(int containerViewId, Fragment fragment, String tag)替换一个已经存在堆栈中的fragment,类似于先执行remove(),再add的过程。也就是说会销毁视图,所以不推荐这么做,会增大内存消耗,Fragment使用了replace方法,replace是remove和add的合体
4.hide(Fragment fragment)隐藏一个存在的fragment 即Visibliity变为visible
5.show(Fragment fragment)显示之前隐藏的fragmentVisibliity变为GONE

6.commit()事务的提交。

> Fragment的生命周期与Activity不同。在Fragment中,如果你在onCreateView中使用绑定,那么你需要在onDestroyView中设置所有view为null。为此,ButterKnife返回一个Unbinder实例以便于你进行这项处理。在合适的生命周期回调中调用unbind函数就可完成重置。
    public class FancyFragment extends Fragment {
        @BindView(R.id.button1)
        Button button1;
        @BindView(R.id.button2)
        Button button2;
        private Unbinder unbinder;

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fancy_fragment, container, false);
            unbinder = ButterKnife.bind(this, view); // TODO Use fields... 
            return view;
        }

        @Override
        public void onDestroyView() {
            super.onDestroyView();
            unbinder.unbind();
        }
    }

> Fragment及懒加载
1.Android Fragment 真正的完全解析(上)-http://blog.csdn.net/lmj623565791/article/details/37970961
2.Android FragmentManage FragmentTransaction介绍- http://blog.csdn.net/xyz_lmn/article/details/6927763
3.ViewPager中fragment是否可见---android实用技巧- http://blog.csdn.net/mmjiajia132/article/details/44201809

> Android Fragment使用(二) 嵌套Fragments- http://www.cnblogs.com/mengdd/p/5552721.html
  在宿主fragment里调用getChildFragmentManager(),即可用它来向这个fragment内部添加fragments.
  Fragment videoFragment = new VideoPlayerFragment();
FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
transaction.add(R.id.video_fragment, videoFragment).commit();
同样, 对于内部的fragment来说, getParentFragment() 方法可以获取到fragment的宿主fragment.

> fragment重复加载和fragment在viewpage中预加载的问题- http://blog.csdn.net/u011807932/article/details/51330833
 ViewPager会预加载2个Fragment,来回滑动时,超过2个的会重新执行onCreate() onCreateView()的生命周期。当不需要重新加载Fragment的场景,判断view及data数据是否为空;需要加载时,加起始变量重新初始化,可能是Page=1.
  viewpage中嵌套fragment来回切换时,fragment每次都会执行oncreate()方法重新加载;
-重复加载问题: 
 - 在fragment的onCreateView()方法中判断是否已经创建:
if (fragmentView == null) {
        fragmentView = inflater.inflate(R.layout.fragment_layout, container, false);
        initData();
    }
ViewGroup parent = (ViewGroup) fragmentView.getParent();
    if (parent != null) {
        parent.removeView(fragmentView);
    }
    return fragmentView;
-预加载问题: 

   - 根据当前fragment的UI是否显示来判断是否加载数据,使用setUserVisibleHint()方法,fragment可 见时才进行数据加载操作,即Fragment的懒加载。但是此方法会先与onCreateView()方法执行,因此在视图未初始化的时候做处理,会有空指针的异常。结合上面避免重复加载的方法,当已经有初始化的数据时data != null,说明已经初始化视图,可以加载数据。

@Override
public void setUserVisibleHint(boolean isVisibleToUser) {
    super.setUserVisibleHint(isVisibleToUser);
    if (getUserVisibleHint() && data != null) {
    } else {
    }

> Android Fragment 使用解析- https://juejin.im/post/5cadbe046fb9a068ad1b0578
- Fragment的优势:
  模块化(Modularity):我们不必把所有代码全部写在Activity中,而是把代码写在各自的Fragment中。
  可重用(Reusability):多个Activity可以重用一个Fragment。
  可适配(Adaptability):根据硬件的屏幕尺寸、屏幕方向,能够方便地实现不同的布局,这样用户体验更好。

- Fragment核心类:
  Fragment:Fragment的基类,任何创建的Fragment都需要继承该类。
  FragmentManager:管理和维护Fragment。他是抽象类,具体的实现类是FragmentManagerImpl。
  FragmentTransaction:对Fragment的添加、删除等操作都需要通过事务方式进行。他是抽象类,具体的实现类是BackStackRecord。
  Nested Fragment(Fragment内部嵌套Fragment的能力)是Android 4.2提出的,support-fragment库可以兼容到1.6。通过getChildFragmentManager()能够获得子Fragment的FragmentManager,在子Fragment中可以通过getParentFragment()获得父Fragment。

-- FragmentTransaction有一些基本方法,下面给出调用这些方法时,Fragment生命周期的变化:
 add(): onAttach()->onCreate()->onCreateView()->onActivityCreated()->onStart()->onResume(),在执行add()时,同一个Fragment不允许被add()两次
 remove(): onPause()->onStop()->onDestroyView()->onDestroy()->onDetach()。
 replace(): 相当于旧Fragment调用remove(),新Fragment调用add()。
 show(): 不调用任何生命周期方法,调用该方法的前提是要显示的Fragment已经被添加到容器,只是纯粹把Fragment UI的setVisibility为true。
 hide(): 不调用任何生命周期方法,调用该方法的前提是要显示的Fragment已经被添加到容器,只是纯粹把Fragment UI的setVisibility为false。
 detach(): onPause()->onStop()->onDestroyView()。UI从布局中移除,但是仍然被FragmentManager管理。
 attach(): onCreateView()->onStart()->onResume()。
 commit():提交事务·每次提交之前,必须通过mFragmentManager.beginTransaction()重新开始一个事务。

-- support v13和support v4中都提供了FragmentPagerAdapter
  在support v13和support v4中都提供了FragmentPagerAdapter和FragmentStatePagerAdapter,区别在于:support v13中使用android.app.Fragment,而support v4使用android.support.v4.app.Fragment。一般都使用support v4中的FragmentPagerAdapter和FragmentStatePagerAdapter。

-- FragmentPagerAdapter和FragmentStatePagerAdapter需要重写的方法都一样,常见的重写方法如下:
  public FragmentPagerAdapter(FragmentManager fm): 构造函数,参数为FragmentManager。如果是嵌套Fragment场景,子PagerAdapter的参数传入getChildFragmentManager()。
  Fragment getItem(int position): 返回第position位置的Fragment,必须重写。
  int getCount(): 返回ViewPager的页数,必须重写。
  Object instantiateItem(ViewGroup container, int position): container是ViewPager对象,返回第position位置的Fragment。
  void destroyItem(ViewGroup container, int position, Object object): container是ViewPager对象,object是Fragment对象。
  getItemPosition(Object object): object是Fragment对象,如果返回POSITION_UNCHANGED,则表示当前Fragment不刷新,如果返回POSITION_NONE,则表示当前Fragment需要调用destroyItem()和instantiateItem()进行销毁和重建。默认情况下返回POSITION_UNCHANGED。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值