Fragment深入解析和学习

版权声明:随意了,开心就好。反正是给大家分享的笔记 https://blog.csdn.net/u011486491/article/details/84560760

Fragment深入解析和学习

Fragment的产生

在多屏展示的时候,为了维护各个展示界面独立的生命周期和数据加载效果。

概述

对于Fragment的使用,一方面Activity需要在布局中为Fragment安排位置,另一方面需要管理好Fragment的生命周期。

Fragment中涉及的对象和方法:

FragmentManager:

Activity中的FragmentManager,其内部维护着fragment队列,以及fragment事务的回退栈。

  • getFragments()

    获取加入到fragment中的fragment的list列表

  • findFragmentById(int id)

    通过id找到加入的fragment

  • findFragmentByTag(String tag)

    通过tag找到对应的fragment

  • popBackStack()

    顶层fragment出栈

    扫描二维码关注公众号,回复: 4734192 查看本文章

FragmentTransaction

保证一些列Fragment操作的原子性。主要用来操作fragment的展示和隐藏等相关操作。

  • transaction.add() 往Activity中添加一个Fragment

  • transaction.remove() 从Activity中移除一个Fragment,如果被移除的Fragment没有添加到回退栈,这个Fragment实例将会被销毁。

  • transaction.replace() 使用另一个Fragment替换当前的,实际上就是remove()然后add()的合体

  • transaction.hide() 隐藏当前的Fragment,仅仅是设为不可见,并不会销毁,

  • transaction.show()

    显示之前隐藏的Fragment

    注意:当使用add(),show(),hide()跳转新的Fragment时,旧的Fragment回调onHiddenChanged(),不会回调onStop()等生命周期方法,而新的Fragment在创建时是不会回调onHiddenChanged(),这点要切记。

  • detach() 会将view从UI中移除,和remove()不同,此时fragment的状态依然由FragmentManager维护。

  • attach() 重建view视图,附加到UI上并显示。

  • transatcion.commit() 提交一个事务

Arguments

对Fragment传递数据使用setArguments(Bundle args),而后在onCreate中使用getArguments()取出,在 “内存重启”前,系统会帮你保存数据,不会造成数据的丢失。和Activity的Intent原理一致。

使用newInstance(参数)创建Fragment对象,优点是调用者只需要关系传递的哪些数据,而无需关心传递数据的Key是什么。

​
public class ContentFragment extends Fragment
{
 
    private String mArgument;
    public static final String ARGUMENT = "argument";
 
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        // mArgument = getActivity().getIntent().getStringExtra(ARGUMENT);
        Bundle bundle = getArguments();
        if (bundle != null)
            mArgument = bundle.getString(ARGUMENT);
 
    }
    /**
     * 传入需要的参数,设置给arguments
     * @param argument
     * @return
     */
    public static ContentFragment newInstance(String argument)
    {
        Bundle bundle = new Bundle();
        bundle.putString(ARGUMENT, argument);
        ContentFragment contentFragment = new ContentFragment();
        contentFragment.setArguments(bundle);
        return contentFragment;
    }
​

注意:

replace 和 add/hide的区别

用replace()方法来替换Fragment,每次切换的时候,Fragment都会重新实例化,重新加载一边数据。replace()这个方法只是在上一个Fragment不再需要时采用的简便方法。

一般的切换方式是add(),切换时hide(),add()另一个Fragment;再次切换时,只需hide()当前,show()另一个。这样就能做到多个Fragment切换不重新实例化:

​
public void switchContent(Fragment from, Fragment to) {
        if (mContent != to) {
            mContent = to;
            FragmentTransaction transaction = mFragmentMan.beginTransaction().setCustomAnimations(
                    android.R.anim.fade_in, R.anim.slide_out);
            if (!to.isAdded()) {    // 先判断是否被add过
                transaction.hide(from).add(R.id.content_frame, to).commit(); // 隐藏当前的fragment,add下一个到Activity中
            } else {
                transaction.hide(from).show(to).commit(); // 隐藏当前的fragment,显示下一个
            }
        }
​

内存重启所带来的fragment的问题

内存重启:系统资源紧张的时候或者应用出现bug奔溃的时候导致把app的资源全部回收(杀死app的进程),或是屏幕旋转等配置变化也会造成当前Activity重启。

系统要把app回收之前,系统会把Activity的状态保存下来,Activity的FragmentManager负责把Activity中的Fragment保存起来。在“内存重启”后,Activity的恢复是从栈顶逐步恢复,Fragment会在宿主Activity的onCreate方法调用后紧接着恢复(从onAttach生命周期开始)。

getActivity()空指针

在调用了getActivity()时,当前的Fragment已经onDetach() 了宿主Activity。在pop了Fragment之后,该Fragment的异步任务仍然在执行,并且在执行完成后调用了getActivity()方法,这样就会空指针。

这里最好在onAttach(Activity activity)里赋值,使用mActivity代替getActivity()。

猜你喜欢

转载自blog.csdn.net/u011486491/article/details/84560760
今日推荐