Android开发开源项目Android开发

Android-MVP Demo

2016-09-23  本文已影响988人  c37d344afd22

说在前面

引用Rocko说过的一段话

MVP作为一种MVC的演化版本在Android开发中受到了越来越多的关注,但在项目开发中选择一种这样的软件设计模式需保持慎重心态,一旦确定使用MVP作为你App的开发模式那么你就最好坚持做下去,如果在使用MVP模式开发过程中发现问题而且坑越来越大,这时你想用MVC等来重新设计的话基本上就等于推倒重来了。要知道在Android上MVP在现在为止并没有统一的标准或者框架,不像SSH这三个成熟稳重强而有力的三剑客支持推动着Java EE的开发,所以在运用MVP时一定要做好自己的理解,并且尽量预知自己App各模块的需求以便提前做好充分的设计工作。

其实关于MVP的文章已经很多了,我觉得我再去说一些理论性的东西显得有点“老套”,所以我直接上一个小的项目(知乎日报)。关于理论知识这里推荐两篇文章,我也是按照这个来自己学习的。仔细想一想,多写一写。

Android MVP 详解(上)

Android MVP 详解(下)

关于知乎日报的实现

我的MVP学的还不是很到位,所以有出错的地方请各位指正

MVP实现的是View和Model的解耦,View中只需要实现接口来接收数据显示界面即可

所以,当我们开始写一个界面的时候,我们就应该想这个界面需要“哪些数据”?我们就根据这个想法来定义接口,至于处理数据/提供数据就交给Presenter去处理。

知乎日报大家都熟悉,我这里只写了一个首页,应该说很简单。

如图:

然后看一下工程的目录,如下

model就是我们的数据了,presenter就是我们的中间层,来处理数据,至于ui就更不用说了,我们的activity、fragment等都放在这。

首先我们要构思一下,这个页面需要什么?

根据这几个我们就可以定义出来一个view的接口IZhiHuFgView,接口如下:

public interface IZhiHuFgView {
    /**
     * 加载的的数据
     */
    void setStories(List<Stories> stories);

    /**
     * 设置banner的View
     */
    void setBanner(View bannerView);

    /**
     * 出错
     */
    void onError();
}

然后我们的ZhiHuFragment来实现这个接口,实现这些方法就可以来添加数据了

public class ZhiHuFragment extends Fragment implements IZhiHuFgView, AbsListView.OnScrollListener, SwipeRefreshLayout.OnRefreshListener {

    @Bind(R.id.stories_list)
    ListView storiesList;
    @Bind(R.id.refresh_view)
    SwipeRefreshLayout refreshView;

    /**
     * 持有presenter的对象来处理数据
     */
    private IZhiHuFgPresenter zhiHuFgPresenter;
    private List<Stories> stories;
    private StoriesAdapter storiesAdapter;
    private boolean isRequest = false;

    @Nullable
    @Override
    public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
        View view = LayoutInflater
                .from(getContext())
                .inflate(R.layout.fragment_zhihu, container, false);
        ButterKnife.bind(this, view);

        init();
        return view;
    }

    /**
     * 初始化一些view
     */
    private void init() {
        zhiHuFgPresenter = new ZhiHuFgPresenter(getActivity(), this);
        storiesAdapter = new StoriesAdapter(getContext());
        storiesList.setAdapter(storiesAdapter);
        stories = new ArrayList<>();

        refreshView.setColorSchemeColors(
                getActivity().getResources().getColor(R.color.colorPrimary));
        refreshView.post(new Runnable() {
            @Override
            public void run() {
                refreshView.setRefreshing(true);
            }
        });
        refreshView.setOnRefreshListener(this);
        storiesList.setOnScrollListener(this);
        zhiHuFgPresenter.getZhiHuStories();

    }

    /**
     * 设置加载的数据
     */
    @Override
    public void setStories(List<Stories> stories) {
        isRequest = false;
        this.stories.addAll(stories);
        storiesAdapter.setData(this.stories);

        refreshView.post(new Runnable() {
            @Override
            public void run() {
                refreshView.setRefreshing(false);
            }
        });
    }

    /**
     * 设置banner
     */
    @Override
    public void setBanner(View bannerView) {
        storiesList.addHeaderView(bannerView);
    }


    /**
     * 出错
     */
    @Override
    public void onError() {
        Toast.makeText(getContext(), "error", Toast.LENGTH_SHORT).show();
    }

    /**
     * 加载更多滑动监听
     */
    @Override
    public void onScrollStateChanged(AbsListView view, int scrollState) {
        if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_IDLE
                && view.getLastVisiblePosition() == (view.getCount() - 1) && !isRequest) {
            isRequest = true;
            zhiHuFgPresenter.getBeforeStories();
        }
    }

    @Override
    public void onScroll(AbsListView absListView, int i, int i1, int i2) {

    }

    /**
     * 刷新
     */
    @Override
    public void onRefresh() {
        stories.clear();
        zhiHuFgPresenter.getZhiHuStories();
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        ButterKnife.unbind(this);
    }

}

可以清楚的看到,我们的view层只是用来展示数据,调理是不是清晰了很多,剩下的就是用presenter这个中间层来处理数据回调给view层了,代码很简单,就不贴了,有需要的可以移步GitHub查看详细代码


自我理解

MVP最大的好处就是View和Model的解耦,方便单元测试等。但是代码量很多,会创建出很多的View层接口。

我觉得写MVP的一个难点就是在于抽离,要思考这个页面需要什么,然后设计成接口

文笔不佳,抱歉了各位


最后

爱生活,爱小丽,爱Android

上一篇 下一篇

猜你喜欢

热点阅读