手把手,嘴对嘴,Fragment使用

来源:互联网 发布:原生js返回顶部火箭 编辑:程序博客网 时间:2024/04/27 14:37

这里使用v4.app.Fragment ,因为他兼容更低版本 ,他需要你的Activity继承FragmentActivity而不是Activity ,除非你使用的是app.Fragmetn,app.Fragment兼容的最低版本为3.0。

Fragmetn生命周期

先看下Fragment的生命周期:

这是我盗的图

下面用代码说话:

public class FragmentA extends android.support.v4.app.Fragment{    /**     * 当Fragment与Activity发生关联时调用。     *     * @param context 当前Activity的Context     */    @Override    public void onAttach(Context context) {        super.onAttach(context);        L("onAttach");    }    /**     * 在创建fragment时系统会调用此方法。     * 在实现代码中,你可以初始化想要在fragment中保持的那些必要组件(这里的组件是指除了view之外的东西,比如需要进行界面展示的关键数据)     * 当fragment处于暂停或者停止状态之后可重新启用它们。     *     * @param savedInstanceState 如果你在onSaveInstanceState()将一些值保存到了Bundle中,在这里你可以拿到他     */    @Override    public void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        String aaa = "";        if (savedInstanceState != null)            aaa = savedInstanceState.getString("aaa");        L("onCreate _ " + aaa);    }    /**     * 在第一次为fragment绘制用户界面时系统会调用此方法     * 为fragment绘制用户界面,这个函数必须要返回所绘出的fragment的根View     * 如果fragment没有用户界面可以返回空。     *     * @param inflater 用来填充的Layout     * @param container 父容器     * @param savedInstanceState 如果你在onSaveInstanceState()将一些值保存到了Bundle中,在这里你可以拿到他     * @return     */    @Nullable    @Override    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {        String aaa = "";        if (savedInstanceState != null)            aaa = savedInstanceState.getString("aaa");        L("onCreateView _ " + aaa);        return inflater.inflate(R.layout.fragment_a , container , false);    }    /**     * 当Activity的onCreate方法返回时调用     *     * @param savedInstanceState 如果你在onSaveInstanceState()将一些值保存到了Bundle中,在这里你可以拿到他     */    @Override    public void onActivityCreated(Bundle savedInstanceState) {        super.onActivityCreated(savedInstanceState);        String aaa = "";        if (savedInstanceState != null)            aaa = savedInstanceState.getString("aaa");        L("onActivityCreated _ " + aaa);    }    /**     *  将当前Fragment切到后台再切回来的时候,如果这期间时间不长,他将会被第一个调用     */    @Override    public void onStart() {        super.onStart();        L("onStart");    }    /**     * 将当前Fragment切到后台再切回来的时候,如果这期间时间不长,他将会被第二个调用     */    @Override    public void onResume() {        super.onResume();        L("onResume");    }    /**     * 系统回调用该函数作为用户离开fragment的第一个预兆(尽管这并不总意味着fragment被销毁)     * 在当前用户会话结束之前,通常要在这里提交任何应该持久化的变化(因为用户可能不再返回)。     */    @Override    public void onPause() {        super.onPause();        L("onPause");    }    /**     * 在onPause之后调用,在这里你可以将当前Fragment的状态保存下来,     * 因为用户可能会在这个Fragment被回收之后才回来,为了确保他们回来后看到的界面依然是离开前的样子     * 你需要保存一些数据信息到Bundle,并在onCreateView()中重新设置到界面上     * @param outState     */    @Override    public void onSaveInstanceState(Bundle outState) {        super.onSaveInstanceState(outState);        outState.putString("aaa", "FragmentA_Bundle");        L("onSaveInstanceState");    }    /**     * 半死不活     */    @Override    public void onStop() {        super.onStop();        L("onStop");    }    /**     * 这个还不太明白什么意思……     */    @Override    public void onDestroyView() {        super.onDestroyView();        L("onDestroyView");    }    /**     * 这个Fragment已经死透了     */    @Override    public void onDestroy() {        super.onDestroy();        L("onDestroy");    }    /**     * 这个Fragment已经跟Activity断绝关系了     */    @Override    public void onDetach() {        super.onDetach();        L("onDetach");    }    /**     * 这是个LOG……     * @param msg 你想说的话……     */    private void L(String msg){        Log.i("FragmentTag" , "FragmentA : "  + msg);    }}

我将每一个生命周期的回调都打上了LOG。然后我是这么操作的:打开App,Fragment一张傻脸呈现在我面前,然后我赶紧按返回键退出App。LOG信息就是下面这样了。
onAttach
onCreate
onCreateView
onActivityCreated
onStart
onResume
onPause
onSaveInstanceState
onStop
onDestroyView
onDestroy
onDetach

具体每个回调的调用时机,都在注释中。这里要说的是, 如果你看到Fragment的傻脸时候按Home键,他会调用onPause ,onSaveInstanceState , onStop , 然后再回到他那张傻脸的时候会调用onStart , onResume。如果在这期间作了别的操作,比如说浏览了一些黄图,摇了几个妹子,然后再回来他大概已经被回收了,这时他会调用onCreate,onCreateView,onActivityCreated,onStart,onResume,我理解的是你可以在onCreateView()中通过Bundle将界面恢复到用户离开之前的样子。


Fragment切换

对Fragment的管理,中国人儿歪果仁儿都使用FragmentManager,通过他可以得到一个FragmentTransaction,字面意思就是事务,在对Fragment做了一系列操作后,提交事务你的操作就会或报错或改变或没反应的在屏幕上应验。

首先要了解一下FragmentTransaction的这4个方法:

add() 添加

replace() 替换

hide() 隐藏

show() 显示

英语6级不黑不吹~这里先这样,后面会告诉你他们怎么用。

这里主要说Fragment之间的切换,两种方式:
1 . 替换 replace()
2 . 切换 hide() add() show()
看需求而定,如果Fragment之间的切换并不是特别频繁,那么使用1.替换会更好一点。如果你是频繁切换,2.切换会性能更优。

这个MainActivity中,使用了“1.替换”的方式切换Fragment:

/** * 界面上有两个Button * 点击A切换到FragmentA * 点击B切换到FragmentB */public class MainActivity extends FragmentActivity {    Fragment fragmentA;    Fragment fragmentB;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        fragmentA = new FragmentA();        fragmentB = new FragmentB();    }    /**     * ButtonA的点击事件     * @param view     */    public void A(View view){        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();        ft.replace(R.id.f , fragmentA).commit();    }    /**     * ButtonB的点击事件     * @param view     */    public void B(View view){        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();        ft.replace(R.id.f , fragmentB).commit();    }}

打印Log,会发现切换期间两个Fragment是在不停初始化的,也就是说,我干死你我再站这,你再干死我你再站这,有你没我有我没你。


在这个MainActivity中,使用了“2.切换”的方式在两个Fragment之间跳转,缠绵,周旋,游走,并且
个人认为这样才是Fragment之间切换的正确姿势 ,当然,不同的体位是要根据不同喜好的人改变的,这里同理,根据需求而定:

/** * 界面上有两个Button * 点击A切换到FragmentA * 点击B切换到FragmentB */public class MainActivity extends FragmentActivity {    Fragment fragmentA;    Fragment fragmentB;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        fragmentA = new FragmentA();        fragmentB = new FragmentB();    }    /**     * ButtonA的点击事件     * @param view     */    public void A(View view){        hideFragment();        showWhat(fragmentA);    }    /**     * ButtonB的点击事件     * @param view     */    public void B(View view){        hideFragment();        showWhat(fragmentB);    }    private void hideFragment(){        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();        List<Fragment> fragmentList = getSupportFragmentManager().getFragments();        if (fragmentList != null){            for (int i = 0; i < fragmentList.size(); i++) {                ft.hide(fragmentList.get(i));            }            ft.commit();        }    }    private void showWhat(Fragment fragment){        FragmentTransaction ft = getSupportFragmentManager().beginTransaction();        if (!fragment.isAdded()){            ft.add(R.id.f, fragment);        }else{            ft.show(fragment);        }        ft.commit();    }}

打印Log,会发现切换期间完全没有走任何一个生命周期,除了第一次add()的时候。这就相当于你去前台表演的时候我就去幕后了,我们轮流上台。说到轮流,我想起了一首诗。“南村群童欺我老无力,轮流与我发生性关系”,哈哈哈哈哈。算福利了,送给大家。


好了 基本使用就这些了,下面还会有一些别的花样儿等着你。

0 0
原创粉丝点击