• Basefragment的封装使用


    1、前言

    封装作为面向对象的三大特性之一,在我们平时的coding过程用的那是非常的多的。大多数时候,我们可以根据封装情况评判代码的质量水平。

    本文主要讲解的是fragment的封装。大体上,在项目的初期,我们都会在基类中把一些常用的东西封装起来,以供子类方便的调用。这用做的好处是显而易见的:

    • 将一些共用的东西集中放在base基类中
    • 方便后期修改维护
    • 避免子类代码冗余
    • 消除不必要的重复代码
    • 方便子类的使用

    2、开始封装

    2.1 获取mActivity

    在fragment中,我们可以通过getActivity()方法获取到当前依附的activity实例。但是如果在使用的时候直接获取有时候可能会报空指针,那么我们可以在fragment生命周期的onAttach(Context context)方法中获取到并提升为全局变量。

      /**
         * 贴附的activity
         */
        protected FragmentActivity mActivity;
    
        @Override
        public void onAttach(Context context)
        {
            super.onAttach(context);
    
            mActivity = getActivity();
        }

    2.2 onCreateView方法的封装

    通常,我们需要在fragment的onCreateView方法中做一些初始化的事情,比如加载布局文件,findview,网络加载数据,初始化数据等,将这些事情都写在一个方法中显得onCreateView非常的庞大,我们可以分成几个方法抽离出来,这样代码既美观又方便阅读:

    @Override
        @Nullable
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                @Nullable Bundle savedInstanceState)
        {
            mRootView = inflater.inflate(setLayoutResouceId(), container, false);
    
            initData(getArguments());
    
            initView();
    
            mIsPrepare = true;
    
            onLazyLoad();
    
            setListener();
    
            return mRootView;
        }

    以上代码我们根据功能进行以下封装,注意方法调用顺序不可调换:

    • setLayoutResouceId():设置布局资源id
    • initData(getArguments()) :数据初始化,主要包括拆包从activity传递过来的参数,适配器初始化,集合初始化等,不可进行view的操作
    • mIsPrepare置为true:mIsPrepare 表示是否已经加载view,该属性主要用于懒加载(下文会详细介绍懒加载)
    • onLazyLoad():懒加载数据,在oncreatview方法中调用可以直接理解为加载数据,方法中可以进行view的操作
    • setListener():各种监听事件的统一设置

    2.3 field介绍

    封装的属性代码注释已经写的很清楚了:

      /**
         * 贴附的activity
         */
        protected FragmentActivity mActivity;
    
        /**
         * 根view
         */
        protected View mRootView;
    
        /**
         * 是否对用户可见
         */
        protected boolean mIsVisible;
        /**
         * 是否加载完成
         * 当执行完oncreatview,View的初始化方法后方法后即为true
         */
        protected boolean mIsPrepare;

    2.4 封装的方法

    以下封装的三个方法用于子类的实现:

       /**
         * 初始化数据
         * @author 漆可
         * @date 2016-5-26 下午3:57:48  
         * @param arguments 接收到的从其他地方传递过来的参数
         */
        protected void initData(Bundle arguments)
        {
    
        }
    
        /**
         * 初始化View
         * @author 漆可
         * @date 2016-5-26 下午3:58:49
         */
        protected void initView()
        {
    
        }
    
        /**
         * 设置监听事件
         * @author 漆可
         * @date 2016-5-26 下午3:59:36
         */
        protected void setListener()
        {
    
        }

    2.5 setLayoutResouceId方法

    setLayoutResouceId()是一个抽象方法,子类必须实现,用于获取布局文件的资源id,加载到fragment中,并在onCreatview方法中用mRootView保存其引用

     /**
         * 设置根布局资源id
         * @author 漆可
         * @date 2016-5-26 下午3:57:09  
         * @return
         */
        protected abstract int setLayoutResouceId();

    2.6 打造专属的findViewById()方法

    是不是很羡慕activity的findViewById()方法,在我们封装的basefragment中,也有自己的findViewById()方法,而且比activity的更加强大,因为它可以直接转化成我们相对应的view,而不需要强制转化。有了它,我们的fragment子类就可以直接使用了。

       @SuppressWarnings("unchecked")
        protected <T extends View> T findViewById(int id)
        {
            if (mRootView == null)
            {
                return null;
            }
    
            return (T) mRootView.findViewById(id);
        }

    2.7 懒加载

    何为懒加载,就是view没有与用户交互的话并不会加载,但是他的加载顺序又非常快。该方法主要在viewpager嵌套fragment中使用得多。我们都知道,viewpager可以提前加载左右指定数目(当然这个数目可以通过setOffscreenPageLimit(int limit)设置)的fragment,如果我们使用懒加载,就只会做些view的创建等操作,避免提前执行其他页面的网络请求。

    一下代码中,setUserVisibleHint(boolean isVisibleToUser)表示是否与用户可交互,他在onCreatview方法前执行,当isVisibleToUser为true时表示对用户可见,在这里我们执行自定义的onVisibleToUser() 
    方法,在onVisibleToUser()中,我们进行判断,当mIsPrepare为true且与用户可交互时执行我们的onLazyLoad()方法进行懒加载。

      @Override
        public void setUserVisibleHint(boolean isVisibleToUser)
        {
            super.setUserVisibleHint(isVisibleToUser);
    
            this.mIsVisible = isVisibleToUser;
    
            if (isVisibleToUser)
            {
                onVisibleToUser();
            }
        }
    
        /**
         * 用户可见时执行的操作
         * @author 漆可
         * @date 2016-5-26 下午4:09:39
         */
        protected void onVisibleToUser()
        {
            if (mIsPrepare && mIsVisible)
            {
                onLazyLoad();
            }
        }

    3 结束

    好了,整个basefragment的封装就做好了,下面是完整代码,由于代码量不多,本篇博客就不上传完整demo了。

    public abstract class BaseFragment extends Fragment
    {
        /**
         * 贴附的activity
         */
        protected FragmentActivity mActivity;
    
        /**
         * 根view
         */
        protected View mRootView;
    
        /**
         * 是否对用户可见
         */
        protected boolean mIsVisible;
        /**
         * 是否加载完成
         * 当执行完oncreatview,View的初始化方法后方法后即为true
         */
        protected boolean mIsPrepare;
    
        @Override
        public void onAttach(Context context)
        {
            super.onAttach(context);
    
            mActivity = getActivity();
        }
    
        @Override
        @Nullable
        public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container,
                @Nullable Bundle savedInstanceState)
        {
            mRootView = inflater.inflate(setLayoutResouceId(), container, false);
    
            initData(getArguments());
    
            initView();
    
            mIsPrepare = true;
    
            onLazyLoad();
    
            setListener();
    
            return mRootView;
        }
    
        /**
         * 初始化数据
         * @author 漆可
         * @date 2016-5-26 下午3:57:48  
         * @param arguments 接收到的从其他地方传递过来的参数
         */
        protected void initData(Bundle arguments)
        {
    
        }
    
        /**
         * 初始化View
         * @author 漆可
         * @date 2016-5-26 下午3:58:49
         */
        protected void initView()
        {
    
        }
    
        /**
         * 设置监听事件
         * @author 漆可
         * @date 2016-5-26 下午3:59:36
         */
        protected void setListener()
        {
    
        }
    
        @Override
        public void setUserVisibleHint(boolean isVisibleToUser)
        {
            super.setUserVisibleHint(isVisibleToUser);
    
            this.mIsVisible = isVisibleToUser;
    
            if (isVisibleToUser)
            {
                onVisibleToUser();
            }
        }
    
        /**
         * 用户可见时执行的操作
         * @author 漆可
         * @date 2016-5-26 下午4:09:39
         */
        protected void onVisibleToUser()
        {
            if (mIsPrepare && mIsVisible)
            {
                onLazyLoad();
            }
        }
    
        /**
         * 懒加载,仅当用户可见切view初始化结束后才会执行
         * @author 漆可
         * @date 2016-5-26 下午4:10:20
         */
        protected void onLazyLoad()
        {
    
        }
    
        @SuppressWarnings("unchecked")
        protected <T extends View> T findViewById(int id)
        {
            if (mRootView == null)
            {
                return null;
            }
    
            return (T) mRootView.findViewById(id);
        }
    
        /**
         * 设置根布局资源id
         * @author 漆可
         * @date 2016-5-26 下午3:57:09  
         * @return
         */
        protected abstract int setLayoutResouceId();
    }
  • 相关阅读:
    批量改主机名报错:Address 192.168.43.117 maps to bogon, but this does not map back to the address
    ssh远程登录连接慢的解决方法
    expect脚本远程登录、远程执行命令和脚本传参简单用法
    将集群WEB节点静态数据迁移到共享存储器(LNMP环境)
    LAMP环境搭建之编译安装指南(php-5.3.27.tar.gz)
    手把手教你设置MongoDB密码
    手把手教你在Linux系统下安装MongoDB
    手把手教你在Linux系统下安装MySQL
    在Linux下使用rm -rf /*后会怎样?
    Failed to configure a DataSource 'url' attribute问题解决
  • 原文地址:https://www.cnblogs.com/zhujiabin/p/5632112.html
Copyright © 2020-2023  润新知