Activity 和Fragment 高层封装(附加个 Presenter 封装)

1,845 阅读5分钟

前言

日常开发中,每个 Activity、Fragment 中都有很多共同的部分,比如 Toast、ButterKnike、startActivity、初始化 init() 等。其实可以根据 Activity 封装一个 BaseActivity,把 ButterKnike 抽取上去,把 注入对象 抽取上去:譬如 presenter 对象。还可以把 Component 抽取到父类(包括通用的 getApplication)。

这样做的目的就是一次封装,方便子类使用,不需要在每个 Activity、Fragment 中写总是写重复的代码了,把重复的工作都抽出来放在父类,自己就继承父类即可。

下面就项目中的封装简单介绍下如何封装 Activity、Fragment、Presenter.

Acitvity 的封装与使用

BaseActivity

继承 AppCompatActivity,重写 onCreate() 方法,并设置布局文件,但是这个布局应该由子类提供(每个 Activity 的布局都不一样),所以代码中定义一个抽象方法 setLayout() 给子类去实现,提供自己的布局。

其他由子类提供的东西,都可以在父类定义一个抽象方法,让子类实现即可。当然,该封装的 Activity 得声明为 abstract 类型的。

也可以提供一些常用的方法:startActivity()

另外,还可以把公共的东西抽取到父类 onCreate() 方法中,如:ButterKnife 控件绑定、Component 的注入。

public abstract class BaseActivity<T extends BasePresenter> extends AppCompatActivity {

    private Unbinder mUnbinder; //用于解除 butterknife 的绑定

    private AppApplication mApplication;  //很常用,不解释

    @Inject
    T mPresenter ;      //把 Presenter 抽出来,泛型表示,因为每个子类需要的 presenter 都不确定

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {

        //字体图标的一些渲染
        LayoutInflaterCompat.setFactory(getLayoutInflater(), new IconicsLayoutInflater(getDelegate()));
        super.onCreate(savedInstanceState);

        setContentView(setLayout());

        mUnbinder = ButterKnife.bind(this);

        this.mApplication = (AppApplication) getApplication();     //常用的东西直接在父类里面获取好,子类直接享用

        setupAcitivtyComponent(mApplication.getAppComponent());

        init(); //在父类留下公共的方法,让子类去实现
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

        if(mUnbinder !=Unbinder.EMPTY){
            mUnbinder.unbind();
        }
    }


//    protected  void  startActivity(Class c){
//
//        this.startActivity(new Intent(this,c));
//    }
//
//    提供很多公共的方法,这样不用每个 Activity 都把需要的再写一遍


    //让子类实现该方法,设置自己的布
    public abstract int setLayout();

    public abstract  void setupAcitivtyComponent(AppComponent appComponent);//把参数 丢给子类 去使用

    //初始化一些数据
    public abstract void  init();
}

MainActivity

上面介绍了 Activity 的封装,下面继承封装的 BaseActivity,实现该抽象类的几个抽象方法。

public class MainActivity extends BaseActivity {


    @BindView(R.id.navigation_view)
    NavigationView mNavigationView;

    @BindView(R.id.drawer_layout)
    DrawerLayout mDrawerLayout;
    @BindView(R.id.tool_bar)
    Toolbar mToolBar;
    @BindView(R.id.tab_layout)
    TabLayout mTabLayout;
    @BindView(R.id.view_pager)
    ViewPager mViewPager;


    private View headerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
    }

    //设置自己的 布局
    @Override
    public int setLayout() {
        return R.layout.activity_main;
    }

    //从父类传过来的 appComponent,这里暂且不使用
    @Override
    public void setupAcitivtyComponent(AppComponent appComponent) {

    }

    @Override
    public void init() {

        initDrawerLayout();

        initTablayout();
    }

   .
   .
   .
}

Fragment 的封装与使用

Fragment 的封装和 Activity 的封装基本一样的,根据上面封装好的 BaseActvity 很快就可以把 BaseFragment 封装妥当。

BaseFragment

继承 Fragment,重写 onCreateView() 方法。

//和 BaseActivity 基本一样

public  abstract  class BaseFragment<T extends BasePresenter> extends Fragment {
    private Unbinder mUnbinder;
    private AppApplication mApplication;
    private View mRootView;

    @Inject
    T mPresenter ;          //和 BaseActivity 一样,抽取出来

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

         mRootView = inflater.inflate(setLayout(), container, false);//和 BaseActivity 一样,layout() 由子类实现,提供布局。
         mUnbinder=  ButterKnife.bind(this, mRootView);//同样把 ButterKnife 抽出来

        return mRootView;
    }

    @Override
    public void onActivityCreated(@Nullable Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);

        this.mApplication = (AppApplication) getActivity().getApplication();  //和 BaseActivity 一样
        setupAcitivtyComponent(mApplication.getAppComponent());

        init();
    }
    @Override
    public void onDestroy() {
        super.onDestroy();

        if(mUnbinder != Unbinder.EMPTY){
            mUnbinder.unbind();
        }
    }
    public abstract int setLayout();  //提供给子类实现的抽象类
    public abstract void setupAcitivtyComponent(AppComponent appComponent);
    public abstract void  init();
}

封装的基本就和 BaseActivity 封装的一样。

RecommendFragment

继承上面封装好的 BaseFragment,实现几个抽象方法即可。

//继承 BaseFragment ,指定 Presenter 的类型:RecommendPresenter
public class RecommendFragment extends BaseFragment<RecommendPresenter>  implements RecommendContract.View {

    @BindView(R.id.recycle_view)
    RecyclerView mRecyclerView;

    private RecomendAppAdatper mAdatper;

    @Inject
    ProgressDialog mProgressDialog;



    @Override
    public int setLayout() {
        return R.layout.fragment_recomend;       //设置 layout(),父类 onCreateView() 方法中调用本方法获得子类的 布局
    }

    @Override
    public void setupAcitivtyComponent(AppComponent appComponent) {

        // 参数 appComponent 从父类传递过来,就是父类调用本方法

        DaggerRecommendComponent.builder().appComponent(appComponent)
                .remmendModule(new RemmendModule(this)).build().inject(this);
    }

    @Override
    public void init() {
        mPresenter.requestDatas();   //mPresenter 是从父类来的
    }

  .
  .
  .
}

Activity、Fragment 的封装就是如此简单,但是具体封装方式还得根据自己的业务需求或者个人喜好来封装。下面说说 Presenter 的封装。

Presenter 的封装与使用

presenter 经常用到两个东西 : Model、View 定义泛型,子类继承 BasePresenter 的时候指定 泛型 的类型即可。

BasePresenter

public class BasePresenter<M,V extends BaseView> {

    protected M mModel;

    protected V mView;

    //M、v 通过子类构造方法传过来
    public BasePresenter(M m,V v){

        this.mModel=m;
        this.mView = v;

    }
}

子类中,通过自己的构造方法调用父类的构造方法,这样子类中就可以很方便的使用 model 、view 对象

RecommendPresenter

BasePresenter 中已经抽取出 model、view ,这样子类就不用总是去 new 来获取对象,仅仅通过构造方法 把对象传过去。

public class RecommendPresenter extends BasePresenter<RecommendModel,RecommendContract.View> {

    //在需要依赖的地方使用这个注释:需要 RecommendModel、RecommendContract.View 对象
    @Inject
    public RecommendPresenter(RecommendModel model, RecommendContract.View view) {
        super(model, view);    //调用父类的构造方法,把 两个对象 传给父类构造方法
    }

    public void requestDatas() {

        mView.showLodading();

        mModel.getApps(new Callback<PageBean<AppInfo>>() {
            @Override
            public void onResponse(Call<PageBean<AppInfo>> call, Response<PageBean<AppInfo>> response) {

                if(response !=null){

                    mView.showResult(response.body().getDatas());
                }
                else{
                    mView.showNodata();
                }

                mView.dimissLoading();

            }

            @Override
            public void onFailure(Call<PageBean<AppInfo>> call, Throwable t) {
                mView.dimissLoading();
                mView.showError(t.getMessage());

            }
        });
    }
}

总结

以上关于 Activity、Fragment、Presenter 的封装都是比较简单的,功能也没有很多,这里只做一个抛砖引玉的作用,更完善的封装还得根据自己业务需求去修改。

本文为菜鸟窝作者 吴威龙 的连载

菜鸟窝是专业的程序猿在线学习平台,提供最系统的 Android 项目实战课程

如需转载,请联系菜鸟窝公众号(cniao5),并注明出处。

菜鸟窝-程序猿的黄埔军校。 如需转载,请注明出处(菜鸟窝 , 原文链接: http://www.cniao5.com/forum/thread/811b02a2437e11e7932a00163e0230fa

关注公众号免费领取"140套优秀开源项目源码"