XMVP(简洁的MVP框架)

更新

v1.2.3-androidx 适配androix

v1.2.3 添加onPresenterCircle方法

v1.2.2 Fragment懒加载数据,添加一些周期方法,修复一些bug

v1.1.5 修复混淆后无法创建presenter

v1.1.4 修复当前页面的子类Activity因无法创建presenter而崩溃的问题

v1.1.3 将Presenter中的star()方法放到了View的onInit()方法之后调用

v1.1.2 XBasePresenter中添加判断view是否还存在的方法

v1.1.1 添加扩展自v4包的Fragment

简介

这是一个MVP框架,帮助项目快速的实现MVP结构。xmvp让所写的代码更加简洁,你无须在意关系依赖问题,xmvp自动完成。这是继《封了一个Android MVP框架,就叫XMVP吧!》后的一次大优化,由于改动的比较多不便再次修改那篇文章,所以新开了这一篇。 使用xmvp能简洁所写代码,使结构清晰,并且我也为它开发了一套MVP管理插件,方便快速管理MVP代码,在文章最后将稍作介绍。

  • 在build.gradle中添加xmvp
dependencies {
    implementation 'com.github.xujiaji:xmvp:1.2.3-androidx'
}
复制代码

使用androidx

dependencies {
    implementation 'com.github.xujiaji:xmvp:1.2.3-androidx'
}
复制代码

项目地址:github.com/xujiaji/XMV…

如何使用?

只需要四部简简单单实现MVP结构

第一步:定义一个Contract

你需要定义一个Contract接口类,来抽象View、Presenter、Model的方法,并且它们需要分别继承XContract.View、XContract.Presenter、XContract.Model接口。

例子:HomeContract

public interface HomeContract {
    interface Presenter extends XContract.Presenter{
        void loadData(Activity activity);
    }

    interface View extends XContract.View{
        void loadStart();
        void loadEnd(List<FileEntity> fileEntities);
    }

    interface Model extends XContract.Model {
        void scanFile(final Activity activity, final FileHelper.Listener<List<FileEntity>> listener);
    }
}
复制代码

第二步:创建一个实现Model接口的实现类

例子:HomeModel

public class HomeModel implements HomeContract.Model {
    @Override
    public void scanFile(final Activity activity, final FileHelper.Listener<List<FileEntity>> listener) {
        new Thread() {
            @Override
            public void run() {
                final FileHelper fileHelper = new FileHelper();
                fileHelper.unzip(activity, listener);
            }
        }.start();
    }
}
复制代码

第三步:创建一个实现Presenter接口的实现类,需要继承XBasePresenter<T extends XContract.View, E extends XContract.Model>

注:

  • 泛型T:View接口
  • 泛型E:Model实现类
  • 在其中可以直接使用viewmodel变量对View和Model进行操作。

例子: HomePresenter

public class HomePresenter extends XBasePresenter<HomeContract.View, HomeModel> implements HomeContract.Presenter {

    @Override
    public void loadData(Activity activity) {
        view.loadStart();
        model.scanFile(activity, new FileHelper.Listener<List<FileEntity>>() {
            @Override
            public void success(List<FileEntity> fileEntities) {
                view.loadEnd(fileEntities);
            }
        });
    }
}
复制代码

第四步:创建一个实现View接口的实现类,这是一个Activity或者Fragment。需要继承XBaseActivity<T extends XBasePresenter>XBaseFragment<T extends XBasePresenter>

注:

  • 泛型T:表示Presenter的实现类

例子: HomeActivity

public class HomeActivity extends XBaseActivity<HomePresenter> implements HomeContract.View {
    @BindView(R.id.toolbar)
    Toolbar toolbar;
    @BindView(R.id.rvFolder)
    RecyclerView rvFolder;
    @BindView(R.id.fragParentLayout)
    FrameLayout fragParentLayout;
    private ProgressDialog dialog;
    private HomeAdapter adapter;
    @BindView(R.id.appBarLayout)
    AppBarLayout appBarLayout;

    @Override
    protected void onInit() {
        super.onInit();
        ButterKnife.bind(this);
        toolbar.setTitle(R.string.xmvp_folder);
        setSupportActionBar(toolbar);
        rvFolder.setLayoutManager(new LinearLayoutManager(this));
        adapter = new HomeAdapter(new ArrayList<FileEntity>());
        rvFolder.setAdapter(adapter);
        presenter.loadData(this);
    }

    @Override
    protected void onListener() {
        super.onListener();
        adapter.setOpenLister(new HomeAdapter.OpenListener() {
            @Override
            public void open(File file) {
                showCode(file);
            }
        });

        toolbar.setNavigationOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onBackPressed();
            }
        });
    }

    /**
     * 显示代码
     *
     * @param file
     */
    private void showCode(File file) {
        FragmentTransaction ft = getFragmentManager().beginTransaction();
        CodeFragment cf = CodeFragment.newInstance(file);
        ft.replace(R.id.fragParentLayout, cf);
        ft.addToBackStack(null);
        ft.commit();
        showBlack(file.getName());
//        rvFolder.setVisibility(View.GONE);
        fragParentLayout.setVisibility(View.VISIBLE);
    }

    /**
     * 显示返回按钮和标题,传入null则隐藏返回按钮
     * @param title
     */
    private void showBlack(String title) {
        if (title != null) {
            toolbar.setNavigationIcon(R.drawable.ic_navigate_before_black_24dp);
            toolbar.setTitle(title);
            appBarLayout.setExpanded(true, true);
        } else {
            toolbar.setNavigationIcon(null);
            toolbar.setTitle(R.string.xmvp_folder);
            fragParentLayout.setVisibility(View.GONE);
        }

    }


    @Override
    public void loadStart() {
        dialog = new ProgressDialog(this);
        dialog.setTitle("正在加载数据");
        dialog.setCancelable(false);
        dialog.show();
    }

    @Override
    public void loadEnd(List<FileEntity> fileEntities) {
        if (dialog != null && dialog.isShowing()) {
            dialog.dismiss();
        }
        adapter.getData().addAll(fileEntities);
        adapter.notifyDataSetChanged();
    }

    @Override
    protected int getContentId() {
        return R.layout.activity_home;
    }

    @Override
    public void onBackPressed() {
        if (fragParentLayout.getVisibility() == View.VISIBLE) {
            showBlack(null);
        }
        super.onBackPressed();
    }
}
复制代码

以上Home相关的类简要关系图


总结

就这么的,只管实现和继承。去掉上面的逻辑代码后,总共就只需下面展示的代码那么点。

public interface HomeContract {
    interface Presenter extends XContract.Presenter{}
    interface View extends XContract.View{}
    interface Model extends XContract.Model {}
}

public class HomeModel implements HomeContract.Model {}

public class HomePresenter 
  extends XBasePresenter<HomeContract.View, HomeModel> 
  implements HomeContract.Presenter {}

public class HomeActivity 
  extends XBaseActivity<HomePresenter> 
  implements HomeContract.View {}
复制代码

为什么不用手动添加依赖关系呢?因为在XBaseActivity中已经帮你实现了。 但是要确保3点:

  1. 抽象的接口必须对应继承:XContract里面的View、Presenter、Model接口。
  2. Presenter实现类必须以XBasePresenter<T extends XContract.View, E extends XContract.Model>为父类,泛型T为View抽象接口,泛型E为Model实现类。
  3. View实现类以XBaseActivity<T extends XBasePresenter>XBaseFragment<T extends XBasePresenter>为父类,泛型T为Presenter的实现类。

提示:当然也可以在如XBaseActivity这个类为父类定义自己的BaseActivity,可参见:BaseActivity.java

听说你MVP代码写烦了?

告诉你一个好消息,有一个Android studio插件:它叫MVPManager,轻轻松松管理你的MVP代码,让你事半功倍。 简单介绍一下MVPManager

  1. mvp编辑面板(通过右键module的包名 -> New -> MVPManager)
  • 给Contract命名
  • 选择View所在包,输入View的名称,如果View存在则不会创建转而直接添加View接口并实现接口中的方法。
  • 添加抽象的M、V、P方法。
  • 点击OK将自动创建Contract,自动创建实现Contract中定义的View、Presenter、Model接口的实现类。
  • Contract在contract包中,View根据你的选择,Presenter在presenter包中,Model在model包中。
  1. mvp修改面板(在对应的Contract类中右键 -> Generate -> MVPManager)
  • 可为Model、View、Presenter添加方法或删除方法,对于的实现类中也会进行添加方法或删除方法。
  1. 已经上传到JetBrains Plugin仓库,可以直接在intellij或Android studio里面搜索MVPManager插件安装了,详细展示地址在下边哦!

END

MVPManager:github.com/xujiaji/MVP…

xmvp:github.com/xujiaji/XMV…

Github:@xujiaji

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值