一个简单的MVP示例,和传统不一样的是,我们把Activity/Fragment作为Presenter,把View单独提出来,扩展了Presenter的能力。
APACHE-2.0 License
MVPMVPGithub
Activity/FragmentViewPresenterViewModuelPresenterPresenterActivity/FragmentPresenter
DemoFragment
ViewViewAndroidandroid.view.View
PresenterPresenterModel
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());
}
}
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.