Fragment知识点详解

作者: PeOS | 来源:发表于2017-03-14 11:47 被阅读364次

    Fragment生命周期

    1.png

    onAttach(Context context)

    onAttach方法会在Fragment于窗口(Activity)关联后立刻调用。从该方法开始,就可以通过Fragment.getActivity方法获取与Fragment关联的窗口对象,但因为Fragment的控件未初始化,所以不能够操作控件。

    onCreate(Bundle savedInstanceState)

    在调用完onAttach执行完之后立刻调用onCreate方法,可以在Bundle对象中获取一些在Activity中传过来的数据。通常会在该方法中读取保存的状态,获取或初始化一些数据。在该方法中不要进行耗时操作,不然窗口不会显示。

    onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState)

    该方法是Fragment很重要的一个生命周期方法,因为会在该方法中创建在Fragment显示的View,其中inflater是用来装载布局文件的,container是<fragment>标签的父标签对应对象,savedInstanceState参数可以获取Fragment保存的状态,如果未保存那么就为null。

    onViewCreated(View view,Bundle savedInstanceState)

    Android在创建完Fragment中的View对象之后,会立刻回调该方法。其种view参数就是onCreateView中返回的view,而bundle对象用于一般用途。

    onActivityCreated(Bundle savedInstanceState)

    在Activity的onCreate方法执行完之后,Android系统会立刻调用该方法,表示窗口已经初始化完成,从这一个时候开始,就可以在Fragment中使用getActivity().findViewById(Id);来操控Activity中的view了。

    onStart()

    当系统调用该方法的时候,fragment已经显示在ui上,但还不能进行互动,因为onResume方法还没执行完。

    onResume()

    该方法为fragment从创建到显示Android系统调用的最后一个生命周期方法,调用完该方法时候,fragment就可以与用户互动了。

    onPause()

    fragment由活跃状态变成非活跃状态执行的第一个回调方法,通常可以在这个方法中保存一些需要临时暂停的工作。如保存音乐播放进度,然后在onResume中恢复音乐播放进度。

    onStop()

    当onStop返回的时候,fragment将从屏幕上消失。

    onDestoryView()

    该方法的调用意味着在 onCreateView 中创建的视图都将被移除。

    onDestroy()

    Android在Fragment不再使用时会调用该方法,要注意的是这时Fragment还和Activity相关联的!并且可以获得Fragment对象,但无法对获得的Fragment进行任何操作。

    onDetach()

    为Fragment生命周期中的最后一个方法,当该方法执行完后,Fragment与Activity不再有关联。

    Fragment比Activity多了几个额外的生命周期回调方法

    • onAttach(Activity):当Fragment和Activity发生关联时使用
    • onCreateView(LayoutInflater, ViewGroup, Bundle):创建该Fragment的视图
    • onActivityCreate(Bundle):当Activity的onCreate方法返回时调用
    • onDestoryView():与onCreateView相对应,当该Fragment的视图被移除时调用
    • onDetach():与onAttach相对应,当Fragment与Activity关联被取消时调用

    注意:除了onCreateView,其他的所有方法如果你重写了,必须调用父类对于该方法的实现。

    Fragment的生命周期和activity的关系

    11.jpg

    Fragment与Activity之间的交互

    Fragment与Activity之间的交互,一般指的是Activity如何向Fragment传递数据。
    虽然我们可以自定义一个带参数的Fragment构造方法,但并不能用它来传递数据。因为当一个fragment重新创建的时候,系统会再次调用 Fragment中的默认构造函数。 注意这里是默认构造函数,也就是自定义带参数的构造函数是不会被调用的(fragment重新创建,比如横竖屏切换等等)
    官方提供的方案:Fragment与Activity之间的交互可以通过Fragment.setArguments(Bundle args)以及Fragment.getArguments()来实现。
    如下程序:

    public class MainActivity extends FragmentActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            if (savedInstanceState == null) {
                getSupportFragmentManager().beginTransaction()
                        .replace(R.id.fl_main, FragmentOne.newInstance("params"))
                        .commit();
            }
        }
    }
    
    public class FragmentOne extends Fragment{
        private TextView textView;
        public View onCreateView(LayoutInflater inflater,
                @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.fragment_one, null);
            textView = (TextView) view.findViewById(R.id.textview);
            if(getArguments()!=null){
                //取出保存的值
                textView.setText(getArguments().getString("name"));
            }
            return view;
        }
        public static  FragmentOne newInstance(String text){
            FragmentOne fragmentOne = new FragmentOne();
            Bundle bundle = new Bundle();
            bundle.putString("name", text);
            //fragment保存参数,传入一个Bundle对象
            fragmentOne.setArguments(bundle);
            return fragmentOne;
        }
    }
    

    Fragment状态的持久化

    方法一:onSaveInstanceState、onRestoreInstanceState

    可以通过protected void onSaveInstanceState(Bundle outState),protected void onRestoreInstanceState(Bundle savedInstanceState) 状态保存和恢复的方法将状态持久化

    方法二:将Fragment在Activity中作为一个变量整个保存

    FragmentManager.putFragment(Bundle bundle, String key, Fragment fragment) 是在Activity中保存Fragment的方法。
    FragmentManager.getFragment(Bundle bundle, String key) 是在Activity中获取所保存的Frament的方法。
    注意:FragmentManager是通过Bundle去保存Fragment的。这个方法仅仅能够保存Fragment中的控件状态,比如说EditText中用户已经输入的文字(注意!在这里,控件需要设置一个id,否则Android将不会为我们保存控件的状态),而Fragment中需要持久化的变量依然会丢失,但依然有解决办法,就是利用方法一。

    状态持久化的事例代码

    Activity中的代码

        @Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.fragment_activity);
    
            if( savedInstanceState != null ){
                fragmentB = (FragmentB) getSupportFragmentManager().getFragment(savedInstanceState,"fragmentB");
            }
    
            init();
        }
        @Override
        protected void onSaveInstanceState(Bundle outState) {
            if( fragmentB != null ){
                getSupportFragmentManager().putFragment(outState,"fragmentB",fragmentB);
            }
            super.onSaveInstanceState(outState);
        }
    

    Fragment中保存变量的代码

        @Nullable
        @Override
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
            AppLog.e("onCreateView");
            if ( null != savedInstanceState ){
                String savedString = savedInstanceState.getString("string");
                //得到保存下来的string
            }
            View root = inflater.inflate(R.layout.fragment_a,null);
            return root;
        }
        @Override
        public void onSaveInstanceState(Bundle outState) {
            outState.putString("string","anAngryAnt");
            super.onSaveInstanceState(outState);
        }
    

    Fragment常用的API

    • android.support.v4.app.Fragment 主要用于定义Fragment(向下兼容至SDK11,即Android3.0)
    • android.support.v4.app.FragmentManager 主要用于在Activity中操作Fragment,可以使用FragmentManager.findFragmenById,FragmentManager.findFragmentByTag等方法去找到一个Fragment
    • android.support.v4.app.FragmentTransaction,对fragment进行添加,移除,替换,以及执行其他动作,必须调用commit才能生效
    • getFragmentManager(),主要的操作都是FragmentTransaction的方法,Fragment若使用的是support.v4包中的,那就使用getSupportFragmentManager代替

    管理Fragment回退栈

    跟踪回退栈状态

    通过实现 OnBackStackChangedListener 接口来实现回退栈状态跟踪

    public class XXX implements FragmentManager.OnBackStackChangedListener 
    /** 实现接口所要实现的方法 **/
    @Override
    public void onBackStackChanged() {
        //do whatevery you want
    }
    /** 设置回退栈监听接口 **/
    getSupportFragmentManager().addOnBackStackChangedListener(this);
    

    管理回退栈的相关方法

    • FragmentTransaction.addToBackStack(String) --将一个刚刚添加的Fragment加入到回退栈中
    • getSupportFragmentManager().getBackStackEntryCount() -获取回退栈中实体数量
    • getSupportFragmentManager().popBackStack(String name, int flags) -根据name立刻弹出栈顶的fragment
    • getSupportFragmentManager().popBackStack(int id, int flags) -根据id立刻弹出栈顶的fragment

    用Fragment同时适配手机和平板两种屏幕

    http://blog.csdn.net/guolin_blog/article/details/8744943

    参考

    https://github.com/GeniusVJR/LearningNotes/blob/master/Part1/Android/Fragment.md

    相关文章

      网友评论

        本文标题:Fragment知识点详解

        本文链接:https://www.haomeiwen.com/subject/jowcnttx.html