mvp模式在android中使用

前言:

相信做android开发的都听过mvc和mvp,有的也听过mvvm,不过mvvm现在还不太成熟,而mvc是J2EE开发中使用的,现在使用也用的mvp模式来构建自己的项目,

mvc开发如果项目越来越复杂的话,项目中的actiivty或者fragment代码量也越来越多,这样项目的后期维护也越来越麻烦,在网上可以搜查一下,你会发现现在最适合android开发的构建模式非MVP莫属。


什么是MVP?

MVP是model,view,presenter的缩写,代表了三个不同的模块,

model:用来处理数据的加载或者存储,比如从网络或本地数据库获取数据

view :负责界面数据的展示

presenter:类似于桥梁的功能,是M层和V层的桥梁。

百度一下可得到如下数据:

优点:

1、模型与视图完全分离,我们可以修改视图而不影响模型
2、可以更高效地使用模型,因为所有的交互都发生在一个地方——Presenter 内部
3、我们可以将一个 Presenter 用于多个视图,而不需要改变 Presenter 的逻辑。这个特性非常的有用,因为视图的变化总是比模型的变化频繁。
4、如果我们把逻辑放在 Presenter 中,那么我们就可以脱离用户接口来测试这些逻辑(单元测试)




这样分层的好处就是减少了 Model 与 View 层之间的耦合度。一方面可以使得 View 层和 Model 层单独开发与测试,互不依赖。另一方面 Model 层可以封装复用,可以极大的减少代码量

毕竟一不小心Activity就成为了所谓的上帝类,而mvp避免了activity或者Fragment代码量过多。


接下来我用简单的例子模仿一下mvp模式在项目中的使用,每个人的想法都不一样,我在github上见过有人把activity或者Fragment作为P层去处理的。


项目的结构如图,由于数据都是自己模拟操作的,所以模拟了一下耗时操作,使Demo看起来像联网操作

view层的代码,view层仅仅是负责页面的展示

public interface MainView {

    void setData(List<String> users);

    void showProgress();

    void hideProgress();

    void netWorkError();
}
隐藏进度和显示进度,把数据提供给recyclerView


model的代码,m层用来获取数据或者查询数据库的耗时操作,由于是模式数据,所以传一个int值去控制数据的成功或失败


public interface MainModel {

    void netWorkMain(int i, MainModelImpl.MainData mainData);

}





public class MainModelImpl implements MainModel {


    @Override
    public void netWorkMain(final int i, final MainData mainData) {


        if (i == 0) {
            List<String> list = new LinkedList<>();
            for (int j = 0; j < 15; j++) {
                list.add("" + j);
            }
            mainData.onSuccess(list);
        } else {
            mainData.onError();
        }


    }


    public interface MainData {

        void onSuccess(List<String> data);

        void onError();

    }


}



presenter层持有view和model的对象,在这里P层就是桥梁,而M层和V层就是桥对面居住的人,桥梁搭建好之后双方就可以进行买卖操作,而在代码中,v层就可以获取M层的数据展示在页面上


public interface MainPresenter {

    void netWork(int i);
}



public class MainPresenterImpl implements MainPresenter, MainModelImpl.MainData {

    private final MainView mainView;
    private final MainModel mainModel;

    public MainPresenterImpl(MainView mainView) {
        this.mainView = mainView;
        this.mainModel = new MainModelImpl();
    }


    @Override
    public void netWork(final int i) {
        mainView.showProgress();
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                mainModel.netWorkMain(i, MainPresenterImpl.this);
            }
        }, 1500);
    }

    @Override
    public void onSuccess(List<String> data) {
        mainView.setData(data);
        mainView.hideProgress();
    }

    @Override
    public void onError() {
        mainView.netWorkError();
        mainView.hideProgress();
    }
}


可以看出P层隔离了数据与界面,这样提高了代码的复用性也使代码的结构一目了然

然后在activity里面进行一些view的操作

public class MainActivity extends AppCompatActivity implements MainView {

    private ProgressBar progressBar;
    private List<String> list;
    private RecyclerView recyclerView;
    private RecyclerViewAdapter adapter;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        recyclerView = (RecyclerView) findViewById(R.id.recyclerView);
        progressBar = (ProgressBar) findViewById(R.id.progress);


        list = new LinkedList<>();
        adapter = new RecyclerViewAdapter(list);
        MainPresenter mainPresenter = new MainPresenterImpl(this);
        mainPresenter.netWork(0);
        recyclerView.setLayoutManager(new StaggeredGridLayoutManager(1, LinearLayoutManager.VERTICAL));
    }

    @Override
    public void setData(List<String> data) {
        list.addAll(data);
        recyclerView.setAdapter(adapter);
    }

    @Override
    public void showProgress() {
        progressBar.setVisibility(View.VISIBLE);
    }

    @Override
    public void hideProgress() {
        progressBar.setVisibility(View.GONE);
    }

    @Override
    public void netWorkError() {
        Toast.makeText(getApplicationContext(), "失败", Toast.LENGTH_LONG).show();
    }
}


这里传的0;model层判断是否是0,然后控制view层显示加载失败还是成功,这里仅仅显示一下成功的操作页面,有兴趣的可以去模拟一下失败。


adapter


public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {

    private final List<String> data;

    public RecyclerViewAdapter(List<String> list) {
        this.data = list;
    }


    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item, parent, false);
        return new ViewHolder(view);
    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        holder.setData(data.get(position));
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        private final TextView tv;

        public ViewHolder(View itemView) {
            super(itemView);
            tv = (TextView) itemView.findViewById(R.id.tv);
        }

        public void setData(String data) {
            tv.setText(data);
            Log.i("setdat", data);
        }
    }
}


最终的显示结果:

代码地址:mvpDemo



如果有兴趣的可以去gihub看下我用retrofit和rxjava写的一个小项目,项目是用mvp去构建的。项目的截图:

项目地址:mvp retrofit_rxjava  欢迎star或者 fork




  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值