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();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM