mvp-sample

一个简单的MVP示例,和传统不一样的是,我们把Activity/Fragment作为Presenter,把View单独提出来,扩展了Presenter的能力。

APACHE-2.0 License

Stars
41

mvp-sample

MVPMVPGithub

Activity/FragmentViewPresenterViewModuelPresenterPresenterActivity/FragmentPresenter

DemoFragment

ViewViewAndroidandroid.view.ViewPresenterPresenterModel

ViewPresenterModule

ActivityPresenterFragmentContract

public final class Contract {

    public interface LauncherPresenter extends BasePresenter {
    }

    public static abstract class LauncherView extends BaseView<LauncherPresenter> {
        public LauncherView(Activity activity, LauncherPresenter presenter) {
            super(activity, presenter);
        }
        
        /**
         * 
         */
        public abstract void bindData(UserInfo userInfo);
    }
}

Presenter

public class LauncherActivity extends BaseActivity implements Contract.LauncherPresenter {

    private Contract.LauncherView mView;
    private BaseModel mModel;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_launcher);
        mView = new LauncherView(this, this); // View
        mModel = new HttpModel(); // Model

        request();
    }

    /**
     * Module
     */
    private void request() {
        Request request = new Request(URLConfig.URL_USER);
        mModel.load(request, new BaseModel.Listener<UserInfo>() {
            @Override
            public void onResult(ModelResult<UserInfo> result) {
                if (result.isSucceed()) {
                    UserInfo userInfo = result.getResult();
                    mView.bindData(userInfo); // 
                } else {
                    mView.toast(result.getMessage());
                }
            }
        });
    }
}

View

public class LauncherView extends Contract.LauncherView {

    @BindView(R.id.tv_message)
    TextView mTvMessage;

    public LauncherView(Activity activity, Contract.LauncherPresenter presenter) {
        super(activity, presenter);
    }

    @Override
    public void bindData(UserInfo userInfo) {
        mTvMessage.setText(userInfo.toString());
    }
}

ViewbindViewunBindViewMenu

@Override
protected void onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main, menu);
}

@Override
protected void onOptionsItemSelected(MenuItem item) {
    int id = item.getItemId();
    if (id == R.id.action_settings) {
        // Setting...
    }
}

ActivityActivity/Fragment:

public class LauncherView extends Contract.LauncherView {

    @BindView(R.id.tv_message)
    TextView mTvMessage;

    public LauncherView(Activity activity, Contract.LauncherPresenter presenter) {
        super(activity, presenter);
    }

    @Override
    protected void onResume() {
    }

    @Override
    protected void onPause() {
    }

    @Override
    protected void onStop() {
    }

    @Override
    protected void onDestroy() {
        // webView
    }
}

colorstringarray

int colorAccent = getColor(R.color.colorAccent); // 
CharSequence text = getText(R.string.app_name); // Text
String appName = getString(R.string.app_name); // String
String appNameFormat = getString(R.string.app_name, "Format"); // String
String[] orderMenu = getStringArray(R.array.order_menu); // StringArray
int[] itemSort = getIntArray(R.array.item_sort); // IntegerArray
Drawable drawable = getDrawable(R.mipmap.ic_launcher); // Drawable

BaseViewDialog

void showMessageDialog(); // 

void toast(String message); // 

void snackBar(String message); // 

Contract:

public final class Contract {

    public interface UserListPresenter extends BasePresenter {

        /**
         * 
         */
        void refresh();

        /**
         * 
         */
        void loadMore();

        /**
         * Item
         */
        void clickItem(int position);
    }

    public static abstract class UserListView extends BaseView<UserListPresenter> {
        public UserListView(Activity activity, UserListPresenter presenter) {
            super(activity, presenter);
        }

        /**
         * View
         */
        public abstract void setRefresh(boolean refresh);

        /**
         * 
         */
        public abstract void bindDataList(List<UserInfo> dataList, Page page);

        /**
         * 
         */
        public abstract void addDataList(Page page);
    }
}

Presenter:

public class UserListActivity extends BaseActivity implements Contract.UserListPresenter {

    private Contract.UserListView mView;
    private BaseModel mModel;

    private List<UserInfo> mUserInfoList; // 
    private Page mPage; // 

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_list);
        mView = new UserListView(this, this);
        mModel = new HttpModel();

        mView.setRefresh(true);
        refresh();
    }

    @Override
    public void refresh() {
        Request request = new Request(URLConfig.URL_USER_LIST);
        mModel.load(request, new BaseModel.Listener<ListWrapper<UserInfo>>() {
            @Override
            public void onResult(ModelResult<ListWrapper<UserInfo>> result) {
                if (result.isSucceed()) { // 
                    ListWrapper<UserInfo> wrapper = result.getResult();
                    mUserInfoList = wrapper.getDataList(); // 
                    mPage = wrapper.getPage(); // 

                    mView.bindDataList(mUserInfoList, mPage); // View
                } else {
                    mView.toast(result.getMessage()); // 
                }

                mView.setRefresh(false); // View
            }
        });
    }

    @Override
    public void loadMore() {
        Request request = new Request(URLConfig.URL_USER_LIST);
        mModel.load(request, new BaseModel.Listener<ListWrapper<UserInfo>>() {
            @Override
            public void onResult(ModelResult<ListWrapper<UserInfo>> result) {
                if (result.isSucceed()) {
                    ListWrapper<UserInfo> wrapper = result.getResult();
                    List<UserInfo> userInfoList = wrapper.getDataList(); // 

                    // 
                    if (userInfoList != null && !userInfoList.isEmpty()) {
                        mUserInfoList.addAll(userInfoList);
                        mPage = wrapper.getPage();
                    }
                } else {
                    mView.toast(result.getMessage()); // 
                }

                // 
                mView.addDataList(mPage);
            }
        });
    }

    @Override
    public void clickItem(int position) {
        mView.toast(mView.getString(R.string.click_item, position));
    }
}

View:

public class UserListView extends Contract.UserListView {

    @BindView(R.id.refresh_layout)
    SwipeRefreshLayout mRefreshLayout;
    @BindView(R.id.recycler_view)
    SwipeMenuRecyclerView mRecyclerView;

    private ListAdapter mAdapter;

    public UserListView(Activity activity, Contract.UserListPresenter presenter) {
        super(activity, presenter);
        // 
        mRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
            @Override
            public void onRefresh() {
                getPresenter().refresh();
            }
        });
        mRecyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        mRecyclerView.addItemDecoration(new DefaultItemDecoration(Color.GRAY));
        mRecyclerView.useDefaultLoadMore();
        // 
        mRecyclerView.setLoadMoreListener(new SwipeMenuRecyclerView.LoadMoreListener() {
            @Override
            public void onLoadMore() {
                getPresenter().loadMore();
            }
        });
        // Item
        mRecyclerView.setSwipeItemClickListener(new SwipeItemClickListener() {
            @Override
            public void onItemClick(View itemView, int position) {
                getPresenter().clickItem(position);
            }
        });

        mAdapter = new ListAdapter(getContext());
        mRecyclerView.setAdapter(mAdapter);
    }

    @Override
    public void setRefresh(boolean refresh) {
        mRefreshLayout.setRefreshing(refresh);
    }

    @Override
    public void bindDataList(List<UserInfo> dataList, Page page) {
        // 
        mAdapter.setUserInfoList(dataList);
        mAdapter.notifyDataSetChanged();

        // 
        boolean isEmpty = dataList == null || dataList.isEmpty();
        mRecyclerView.loadMoreFinish(isEmpty, page.getCurrentPage() < page.getPageCount());
    }

    @Override
    public void addDataList(Page page) {
        // 
        mAdapter.notifyDataSetChanged();
        mRecyclerView.loadMoreFinish(false, page.getCurrentPage() < page.getPageCount());
    }
}

License

Copyright 2018 Yan Zhenjie

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

   http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.