快速構建UI開發框架-XNUiFrame

一.CMXnUIFrame介紹

demo下載地址: https://github.com/396640195/CMUiFrame/tree/uiframe1.1

CMXnUIFrame 爲Common XiaoNiu UI Frame 的簡稱(下文簡稱爲UIFrame), 針對安卓應用UI開發的共性進行了封裝, 界面的主要組成部分有:Header,Top,Center,Bottom,Dialog,ErrorShow, 一個完整的移動端app的界面基本全都是由這些部分組成, 所有元素當然是可選. 那麼CMXnUiFrame針對這些界面元素進行了抽象封裝,主要有這麼一些層級管理器:
- 頭部佈局管理 HeaderLayoutManager 管理界面頭部佈局
- 頂部佈局管理 TopLayoutManager 管理界面頂部佈局
- 中間內容佈局管理 CenterLayoutManager 管理界面中間內容區域視圖佈局
- 中間覆蓋層佈局管理 CenterMaskLayoutManager 管理中間內容視圖覆蓋佈局,用來實現特殊場景展示信息
- 對話框佈局管理 DialogLayoutManager 對話框佈局管理
- 全屏佈局管理 FullScreenLayoutManager 全屏信息展示佈局管理類似DialogLayoutManager

使用uiframe和正常佈局的層次差異
這裏寫圖片描述

在此框架之下開發UI, 有如下幾個優點:

  • 1.可以大大提升界面開發效率,很多重複工作可以寫一次整個項目複用
  • 2.在開發之初就已經爲你做了最大布局層級優化,提升了應用效率;
  • 3.抽象了應用層常用的場景, 可以動態定製界面元素;
  • 4.你只需給定一個你關心的最小單元的layout佈局文件即可, 且不影響佈局層級;
    layout可以是一個View,不一定是容器;
  • 5.所有佈局是add到容器中,界面的所有layout處於同一層級;

二.UI開發之基類

UIFrame提供了兩個基類,你可根據實際需求繼承基中一個即可.
- 1. UIFrameBasicActivity
- 2. UIFrameBasicFragment

public abstract class UIFrameBasicActivity extends FragmentActivity implements
        IBasicViewAdapter,
        IViewCommonBehavior,
        OnRefreshListener
{
        //Fragment用法一樣,請下載demo參照例子,這裏只拿Activity舉例;
}

這兩個基類都實現瞭如下幾個接口:
- 1.IBasicViewAdapter 提供界面的基本元素, 按需實現這個適配器的接口,就可生成你想要的界面;
- 2.IViewCommonBehavior 該接口定義了界面具有哪些行爲能力,我們可以具體看一下這個接口定義:

三.快速搭建一個界面

3.1 繼承UI基類

基本常用的接口實現介紹

public class BasicSimpleActivity extends UIFrameBasicActivity {
    @Override
    public boolean isNeedEventBus() {
        return false;  //默認不需要使用EventBus,如果要用EventBus,重寫該方法返回true即可;
    }

    @Override
    public void onLeftHeaderClicked() {
        //頭部左邊點擊事件處理
    }

    @Override
    public void onRightHeaderClicked() {
       //頭部右邊點擊事件處理
    }

    @Override
    public void onAllViewConstructed() {
        //所有佈局加載完成後處理ui邏輯
    }

        @Override
    public void onRefresh() {
        //下拉刷新處理
    }

    @Override
    public void onLoadMore() {
        //加載更多處理
    }
}

3.2 設置界面的統一背景

使用場景: 每個界面的內容區域會與背景有一個margin值,這個時候能看到容器的背景色,此時需要有統一背景色,可以使用如下api:

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

         this.setContainerBackgroundColor(R.color.ui_frame_ripple_color);
         //也可以調用這個接口
         //this.setContainerBackgroundResource(R.drawable.icon_background);

    }

3.3 添加一個頭部元素

使用場景: 每個界面都有一個頭部視圖, 左邊有返回按鈕或圖標, 中音有標題文字, 右邊有可能是圖片 也有可能是文字; 此時可以添加一個HeaderLayoutManager

    @Override
    public HeaderLayoutManager addHeaderView(IContainerManager container) {

        //使用自定義的佈局文件
        //HeaderLayoutManager hlm = HeaderLayoutManager.buildLayoutManager(container, R.layout.layout_header);

        //使用默認ui_frame_common_header_layout的佈局
        HeaderLayoutManager hlm = HeaderLayoutManager.buildLayoutManager(container);

        //設置圖標的大小間距,0.8f爲圖標縮放比例.
        hlm.setHeaderLeftImage(R.mipmap.arrow_left_normal,0.8f);

        //所有佈局管理都可以拿到View視圖對象
        //View view = hlm.getContentView();
        //當有多個視圖層的時候可以這樣,當然這樣拿到視圖的集合用處不大.
        //Viwe views = hlm.getContentViews(); 

        //可以這樣分別拿到某一個視圖對象
        //這裏只是舉例說明,只有在DialogLayoutManager,FullScreenLayoutManager纔可以這樣添加多個佈局;
        // View view = hlm.addLayout(R.layout.layout_header)

        //設置頭部分隔線顏色
        hlm.setHeaderLineColor(R.color.colorAccent);
        return hlm;
    }

頭部佈局需要遵守幾個約定,你纔可以使用框架關於頭部視圖操作的API:

  • 必需的: 1.頭部佈局是三個TextView, 用來實現左中右三個部分的內容;
  • 必需的: 2.左中右TextView的id命名約定,
    ui_frame_header_left,
    ui_frame_header_center,
    ui_frame_header_right;

UIFrame層已定義了一個 ui_frame_common_header_layout.xml佈局內容如下.
默認使用的是這個xml,如果不能滿足你的需求,你可以自已定製. 若想使用框架的api,需要遵守上面兩個約定;

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:background="#FFFFFF"
    >

    <TextView
        android:id="@+id/ui_frame_header_left"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:text="返回"
        android:layout_marginLeft="10dp"
        android:drawablePadding="10dp"
        android:layout_alignParentLeft="true"
        android:textColor="#000000"
        android:gravity="center" />

    <TextView
        android:id="@+id/ui_frame_header_center"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="標題"
        android:textColor="#000000"
        android:layout_centerInParent="true"
        android:gravity="center" />

    <TextView
        android:id="@+id/ui_frame_header_right"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:text="More"
        android:layout_marginRight="10dp"
        android:textColor="#000000"
        android:gravity="center" />
</RelativeLayout>

遵守上面約定後,就可以使用IHeaderViewBehavior中的接口.

例如:

    @Override
    public HeaderLayoutManager addHeaderView(IContainerManager container) {

        HeaderLayoutManager hlm = HeaderLayoutManager.buildLayout(container, R.layout.layout_header);
        //在當前方法中, 只能這樣使用,其它方法類似.
        hlm.setHeaderLeftImage(R.mipmap.arrow_left_normal);

        return  hlm;
    }

IHeaderViewBehavior.java 接口的具體定義如下:

public interface IHeaderViewBehavior {
    /**
     * 設置頭部左邊的文字
     * @param resource 字符資源ID
     * @return 返回當前的TextView對象
     */
    TextView setHeaderLeftText(@StringRes int resource);

    /**
     * 設置頭部左邊的文字
     * @param content 字符
     * @return 返回當前的TextView對象
     */
    TextView setHeaderLeftText(String content);

    /**
     * 設置頭部左邊的圖片資源
     * @param resource 圖片資源ID
     * @return 返回當前的TextView對象
     */
    TextView setHeaderLeftImage(@DrawableRes  int resource);

    /**
     * 設置頭部中間的文字內容
     * @param resource 字符資源ID
     * @return 返回當前的TextView對象
     */
    TextView setHeaderCenterText(@StringRes int resource);

    /**
     * 設置頭部中間的文字內容
     * @param content 字符
     * @return 返回當前的TextView對象
     */
    TextView setHeaderCenterText(String content);

    /**
     * 設置頭部右邊的文字內容
     * @param resource 字符資源ID
     * @return 返回當前的TextView對象
     */
    TextView setHeaderRightText(@StringRes int resource);

    /**
     * 設置頭部右邊的文字內容
     * @param content 字符
     * @return 返回當前的TextView對象
     */
    TextView setHeaderRightText(String content);

    /**
     * 設置頭部右邊的圖片資源
     * @param resource 圖片資源ID
     * @return 返回當前的TextView對象
     */
    TextView setHeaderRightImage(@DrawableRes  int resource);

    /**
     * 設置頭部視圖的點擊事件
     * @param lister
     */
    void setOnHeaderClickLister(HeaderLayoutManager.OnHeaderViewClickListener lister);
}

修改頭部佈局樣式


    <style name="ui_frame_header_left_text_style">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">50dp</item>
        <item name="android:background">#FFFFFF</item>
        <item name="android:textColor">#000000</item>
        <item name="android:textSize">15sp</item>
        <item name="android:drawablePadding">11dp</item>
        <item name="android:layout_marginLeft">11dp</item>
    </style>

    <style name="ui_frame_header_center_text_style">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">50dp</item>
        <item name="android:background">#FFFFFF</item>
        <item name="android:textColor">#000000</item>
        <item name="android:textSize">15sp</item>
        <item name="android:drawablePadding">13dp</item>
    </style>

    <style name="ui_frame_header_right_text_style">
        <item name="android:layout_width">wrap_content</item>
        <item name="android:layout_height">50dp</item>
        <item name="android:background">#FFFFFF</item>
        <item name="android:textColor">#000000</item>
        <item name="android:textSize">15sp</item>
        <item name="android:drawablePadding">13dp</item>
        <item name="android:layout_marginRight">10dp</item>
    </style>

    <style name="ui_frame_header_container_style">
        <item name="android:layout_width">match_parent</item>
        <item name="android:layout_height">wrap_content</item>
        <item name="android:background">#FFFFFF</item>
    </style>

3.4 添加一個頂部視圖

使用場景: 在頭部視圖之下,有時候需要展示一個通知或廣告,你可以利用這個固定位置來做這個功能; 也可以用它來實現其它固定位置的需求和功能;

       @Override
    public TopLayoutManager addTopView(IContainerManager container) {
        TopLayoutManager tlm = TopLayoutManager.buildLayoutManager(container, R.layout.layout_top);
        //頂部視圖只能添加一個視圖,可以直接調用api進行顯隱控制;
        tlm.setVisibility(View.GONE);
        return tlm;
    }

    public void onClick(View v){
        //對通知廣告的區域作動畫顯示, 所有層級都可以這樣實現一個動畫,你也可以擴展動畫功能;
        animateY(ElementView.TopView,1000);
    }

佈局文件內容如下:

<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="50dp"
    android:layout_gravity="center"
    android:background="#FF864A"
    android:gravity="center"
    android:textColor="#000000"
    android:padding="10dp"
    android:text="今日新聞:青海首次發現雪豹 兩隻幼崽都已半個月大小" />

3.5添加一個底部視圖

使用場景: 一般在界面底部有幾個Tab頁,可用使用這個佈局管理實現. 它是一個固定位置不變的和Top,Header類似;

    @Override
    public BottomLayoutManager addBottomView(IContainerManager container) {

        BottomLayoutManager blm = BottomLayoutManager.buildLayout(container, R.layout.layout_simple_bottom);
        //可以通過佈局管理器獲得視圖對象
        View view = blm.getContentView();
        //底部佈局只能添加一個視圖,可以直接調用api進行顯隱控制;
        blm.setVisibility(View.GONE);

        return blm;
    }

3.6 添加一箇中間視圖

使用場景: 每個界面離不開內容展示,所以這個區域幾乎是少不了. CenterLayoutManager提供了兩個靜態方法來構造中間視圖
- buildGeneralLayoutManager(container,layout) 這個是指定一個佈局,你可以自由撐控
- buildPullRefreshLayoutWithListView(container) 這個是框架定義好了一個帶有pullrefresh和listView功能的中間視圖


    @Override
    public CenterLayoutManager addCenterView(IContainerManager container) {
        //添加一個指定的中間視圖佈局,完全由你撐控;
        CenterLayoutManager clt = CenterLayoutManager.buildGeneralLayoutManager(container, R.layout.layout_center);
        return clt;
    }

佈局文件內容如下,這個視圖添加了一個pull refresh功能的容器,一個ScrollView滾動支持的容器


<?xml version="1.0" encoding="utf-8"?>
<com.xn.uiframe.widget.UIFrameRefreshViewLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="vertical">

            <TextView
                android:layout_width="match_parent"
                android:layout_height="500dp"
                android:background="#c0c0c0"
                android:gravity="center"
                android:text="Center View 1"
                android:textColor="#999009"
                android:textSize="22sp" />


            <TextView
                android:layout_width="match_parent"
                android:layout_height="500dp"
                android:background="#c0c0c0"
                android:gravity="center"
                android:text="Center View 2"
                android:textColor="#999009"
                android:textSize="22sp" />

            <TextView
                android:layout_width="match_parent"
                android:layout_height="500dp"
                android:background="#c0c0c0"
                android:gravity="center"
                android:text="Center View 3"
                android:textColor="#999009"
                android:textSize="22sp" />
        </LinearLayout>


    </ScrollView>
</com.xn.uiframe.widget.UIFrameRefreshViewLayout>

開啓pullRefresh功能

    @Override
    public void onRefresh() {
        //uiframe封裝了EventBusProxy的方法,同時增加了這下面靜態方法
        EventBusProxy.dispatcherOnMainThreadDelay(new Runnable() {
            @Override
            public void run() {
                mMask01.setVisibility(View.VISIBLE);
                mMask02.setVisibility(View.VISIBLE);
                animateY(ElementView.CenterMaskView, Easing.EasingAnimation.EaseInOutQuart, 1000);
                stopRefresh(true);
            }
        }, 2000);
    }

    @Override
    public void onLoadMore() {
        EventBusProxy.dispatcherOnMainThreadDelay(new Runnable() {
            @Override
            public void run() {
                stopLoadMore(true);
            }
        }, 2000);
    }

添加一箇中間視圖帶listView,同時帶伴隨視圖的用法

//伴隨視圖必需在有PullRefresh功能下才有效;
    @Override
    public void addCompanionScrollableHeader(CenterLayoutManager container) {
        container.addCompanionScrollableHeader(R.layout.layout_companion_header);
    }

    @Override
    public void addCompanionScrollableFooter(CenterLayoutManager container) {
        container.addCompanionScrollableFooter(R.layout.layout_companion_footer);
    }

    @Override
    public CenterLayoutManager addCenterView(IContainerManager container) {
        //該方法會返回一個帶有ListView,PullRefresh功能的視圖給你,同時你可以添加伴隨視圖;你不需要傳入layout文件,默認使用框架中自帶佈局文件;
        CenterLayoutManager clm = CenterLayoutManager.buildPullRefreshLayoutWithListView(container);
        return clm;
    }

添加完伴隨視圖之後對listview進行處理


  @Override
    public void onCompanionViewAddFinished(CenterLayoutManager container) {

        ListView listview = container.getListView();
        List<String> list = new ArrayList<>();
        for (int i = 0; i < 15; i++) {
            list.add("測試的" + i);
        }
        listview.setAdapter(new ArrayAdapter<>(this.getActivity(), android.R.layout.simple_list_item_1, list));

    }

3.7 添加一箇中間視圖的遮罩層

使用場景: 這種視圖層用來實現網絡請求無數據,請求異常在中間內容區域展示一些提示信息的場景. 這個層級也不限制View的個數;


    @Override
    public CenterMaskLayoutManager addCenterMaskView(IContainerManager container) {

        CenterMaskLayoutManager clt = CenterMaskLayoutManager.buildLayoutManager(container);
        mMask01 = clt.addLayout(R.layout.layout_center_mask01);
        mMask02 = clt.addLayout(R.layout.layout_center_mask02);

        //只有一個mask視圖可以用這個方法,多個的時需要單獨立操作如下持有視圖
        //clt.setVisibility(View.GONE);
        mMask01.setVisibility(View.GONE);
        mMask02.setVisibility(View.GONE);

        mMask01.setOnClickListener(this);
        mMask02.setOnClickListener(this);

        return clt;
    }

3.8 添加一個全屏對話框

使用場景: 這種全屏視圖用來替代對話框的效果,比直接使用Dialog要方便易掌控;


    //最好使用一個DialogViewHoder把Dialog的邏輯從Activity中拆分出去,UI中只保持主線邏輯;
    private View mDialog01, mDialog02; 

    //可以添加多個對話框視圖,理論上不限制Dialog的視圖個數;
    @Override
    public DialogLayoutManager addDialogView(IContainerManager container) {
        DialogLayoutManager fsm = DialogLayoutManager.buildLayoutManager(container);

        //有多個視圖時需要單獨操控,你只需每次addLayout的時候保持View的引用就可以後面自由操控該視圖;
        mDialog01 = fsm.addLayout(R.layout.layout_dialog_01);
        mDialog01.findViewById(R.id.ok_button_of_dialog_01).setOnClickListener(this);
        mDialog01.setVisibility(View.GONE);

        mDialog02 = fsm.addLayout(R.layout.layout_dialog_02);
        mDialog02.findViewById(R.id.ok_button_of_dialog_02).setOnClickListener(this);
        mDialog02.setVisibility(View.GONE);

        return fsm;
    }

3.9 添加一個全屏視圖


    View fullScreen01, fullScreen02;

    @Override
    public FullScreenLayoutManager addExtraFullScreenView(IContainerManager container) {

        //這種全屏視圖用來實現菊花加載進度,或者全屏廣告覆蓋在內容之上的場景;
        FullScreenLayoutManager fullScreenLayoutManager = FullScreenLayoutManager.buildLayoutManager(container);

        fullScreen01 = fullScreenLayoutManager.addLayout(R.layout.layout_full_screen_01);
        fullScreen02 = fullScreenLayoutManager.addLayout(R.layout.layout_full_screen_02);

        fullScreen01.setOnClickListener(this);
        fullScreen02.setOnClickListener(this);

        return fullScreenLayoutManager;

    }

3.9Fragment的支持

如果要使用fragment碎片,api已封裝了相關的方法,可以直接使用;


public class SimplePullRefreshActivity extends BasicSimpleActivity {

    private SimpleFragment mHomeFragment;
    private ListFragment mSetFragment;
    private GeneralFragment mAccountFragment;

    @Override
    public void onTabSelected(int index) {
        if (mHomeFragment == null) {
            mHomeFragment = new SimpleFragment();
            Bundle bundleHome = new Bundle();
            bundleHome.putString("content", "From 首頁");
            mHomeFragment.setArguments(bundleHome);
            //如果fagment還沒有添加調用此api
            addUIFrameFragment(mHomeFragment);
        }else{
            //如果fagment已經添加調用此api
            changeUIFragment(mHomeFragment);
        }
    }

    }

四. 動畫支持

動畫支持不夠強大,但能滿足基本的顯示隱匿動畫,後續再擴展;

動畫接口的使用


 //activity實現了這個接口,可以直接調用
 animateX(ElementView.CenterView, Easing.EasingAnimation.EaseOutBounce, 1500);
 animateY(ElementView.BottomView, Easing.EasingAnimation.EaseInQuart, 500);

 //如果該層級視圖有多個view,那它對可見的視圖View都起作用;
 animateY(ElementView.DialogView, Easing.EasingAnimation.EaseInQuart, 500);

動畫能力的接口定義


public interface IAnimateBehavior {
    /**
     * 針對該視圖進行Y軸動畫
     *
     * @param elementCategory 界面視圖元素類型
     * @param duration
     */
    void animateY(ElementView elementCategory, long duration);

    /**
     * 針對該視圖進行X軸動畫
     *
     * @param elementCategory 界面視圖元素類型
     * @param duration
     */
    void animateX(ElementView elementCategory, long duration);

    /**
     * 針對該視圖進行XY軸動畫
     *
     * @param elementCategory 界面視圖元素類型
     * @param xDuration        x軸動畫時間
     * @param yDuration        y軸動畫時間
     */
    void animateXY(ElementView elementCategory, long xDuration, long yDuration);

    /**
     * 針對該視圖進行Y軸動畫
     *
     * @param elementCategory 界面視圖元素類型
     * @param easing          動畫效果類型 參見{@link com.xn.uiframe.animation.Easing.EasingAnimation}
     * @param duration
     */
    void animateY(ElementView elementCategory, Easing.EasingAnimation easing, long duration);

    /**
     * 針對該視圖進行X軸動畫
     *
     * @param elementCategory 界面視圖元素類型
     * @param easing          動畫效果類型 參見{@link com.xn.uiframe.animation.Easing.EasingAnimation}
     * @param duration
     */
    void animateX(ElementView elementCategory, Easing.EasingAnimation easing, long duration);

    /**
     * 針對該視圖進行XY軸動畫
     *
     * @param elementCategory 界面視圖元素類型
     * @param easing          動畫效果類型 參見{@link com.xn.uiframe.animation.Easing.EasingAnimation}
     * @param xDuration        x軸動畫時間
     * @param yDuration        y軸動畫時間
     */
    void animateXY(ElementView elementCategory, Easing.EasingAnimation easing, long xDuration, long yDuration);
}

每個LayoutManager都可以調用如下api對View執行動畫


    /**
     * 針對該視圖進行Y軸動畫
     *
     * @param duration 動畫時間
     */
    void animateY(long duration);

    /**
     * 針對該視圖進行X軸動畫
     *
     * @param duration 動畫時間
     */
    void animateX(long duration);

    /**
     * 針對該視圖進行XY軸動畫
     *
     * @param xDuration x軸動畫時間
     * @param yDuration y軸動畫時間
     */
    void animateXY(long xDuration, long yDuration);

    /**
     * 針對該視圖進行Y軸動畫
     *
     * @param easing   動畫效果類型 參見{@link com.xn.uiframe.animation.Easing.EasingAnimation}
     * @param duration
     */
    void animateY(Easing.EasingAnimation easing, long duration);

    /**
     * 針對該視圖進行X軸動畫
     *
     * @param easing   動畫效果類型 參見{@link com.xn.uiframe.animation.Easing.EasingAnimation}
     * @param duration
     */
    void animateX(Easing.EasingAnimation easing, long duration);

    /**
     * 針對該視圖進行XY軸動畫
     *
     * @param easing    動畫效果類型 參見{@link com.xn.uiframe.animation.Easing.EasingAnimation}
     * @param xDuration x軸動畫時間
     * @param yDuration y軸動畫時間
     */
    void animateXY(Easing.EasingAnimation easing, long xDuration, long yDuration);

五. 自定義下拉刷新和加載更多

框架中的下拉刷新有可能與你項目的風格不一樣,需要自定義修改那麼按下面的步驟.

在你的工程目錄進行如下步驟,不需要去修改框架的源代碼和文件:

  • 1.自定義容器類,如: UIFrameRefreshViewLayoutEx.java
  • 2.自定義HeaderView,FooterView,請參照uiframe中的 UIFrameRefreshHeader,和FooterView.
  • 3.修改 ui_frame_center_listview_layout.xml中的容器類爲你自定義的容器類 UIFrameRefreshViewLayoutEx.java;
    如果不替換該xml,則CenterLayoutManager.buildPullRefreshLayoutWithListView(…)接口不能使用

//按照下面的寫法,重新實現一個下拉刷新類
public class UIFrameRefreshViewLayout extends RefreshLayout {

    public UIFrameRefreshViewLayout(Context context) {
        super(context);
    }

    public UIFrameRefreshViewLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();
        init();
    }

    public void init() {
        //HeaderView,FooterView用你自已實現的即可;
        UIFrameRefreshHeader header = new UIFrameRefreshHeader(getContext());
        FooterView footer = new FooterView(getContext());

        addHeader(header);
        addFooter(footer);
        setOnHeaderListener(header);
        setOnFooterListener(footer);
    }
}

六. EventBusProxy工具類定義


public class EventBusProxy {

    private static Handler sHandler = new Handler(Looper.getMainLooper());

    /**
     * 主線程中簡單執行一個任務
     * @param task
     */
    public static void dispatcherOnMainThread(Runnable task){
        sHandler.post(task);
    }

    /**
     * 主線程中簡單執行一個延遲任務
     * @param task
     * @param duration
     */
    public static void dispatcherOnMainThreadDelay(Runnable task,long duration){
        sHandler.postDelayed(task,duration);
    }
    /**
     * 發送一個Action的消息,接收該消息的類需要註冊訂閱EventBus消息;
     *
     * @param action
     */
    public static void dispatcher(Action action) {
        EventBus.getDefault().post(action);
    }

    /**
     * 延遲發送消息,用來替代Handler的postDelay方法.
     *
     * @param action
     * @param secondsDelay
     */
    public static void dispatherDelay(final Action action, long secondsDelay) {
        sHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                EventBusProxy.dispatcher(action);
            }
        }, secondsDelay);
    }

    /**
     * 定義一個通用的消息基類
     *
     * @param <T>
     */
    public static class Action<T> {
        public int action;
        public String extra;
        public T t;

        /**
         * 只需要一個類型的時候調用該構造方法
         **/
        public Action(int action) {
            this.action = action;
        }

        /**
         * 需要附帶一個字符串的時候調用該構造方法
         **/
        public Action(int action, String extra) {
            this(action);
            this.extra = extra;
        }

        /**
         * 當一個Integer,String還不構需要帶一個複雜對象的時候調用該方法
         **/
        public Action(int action, String extra, T t) {
            this(action, extra);
            this.t = t;
        }

    }

    /**
     * 註冊訂閱EventBus消息
     * @param subscriber
     */
    public static void register(Object subscriber){
        EventBus.getDefault().register(subscriber);
    }
    /**
     * 反註冊訂閱EventBus消息
     * @param subscriber
     */
    public static void unregister(Object subscriber){
        EventBus.getDefault().unregister(subscriber);
    }
}

發佈了45 篇原創文章 · 獲贊 9 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章