1 BaseView搭建(统一的耗时(网络/子线程)过程提示,即结束处理)
public interface BaseView {
void showLoading(String content);//统一的加载中处理
void hideLoading();//加载结束
void showError(String error);//错误提示
void closeFresh();//关闭刷新加载的控件
}
2 BasePresenter--绑定页面生命周期,防止内存泄漏+提取一些统一的请求处理方法
public abstract class BasePresenter<T extends BaseView> {
public T mView;
public void attach(T mView) {//onCreate中绑定
this.mView = mView;
}
public void dettach() {//onDestroy中解绑,防止内存泄露
mView = null;
}
public void showResponseFail(){//统一的请求onFail处理
if (mView != null) {
mView.hideLoading();
mView.showError("网络异常");
}
}
public void showLoading(String content){//加载中非空检测抽取方法
if (mView != null){
mView.showLoading(content);
}
}
}
3 BaseMvpActivity 可以整合自定义控件中的DialogShow 与之前的baseActivity基础上进行强化MVP
public abstract class BaseMvpActivity<V extends BaseView,T extends BasePresenter<V>> extends BaseActivity {
public T presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
presenter = initPresenter();
presenter.attach((V)this);
}
@Override
protected void onDestroy() {
presenter.dettach();
super.onDestroy();
}
// 实例化presenter
public abstract T initPresenter();
public void showLoading(String content) {
DialogShow.showRoundProcessDialog(this,content);
}
public void hideLoading() {
DialogShow.closeDialog();
}
public void showError(String error) {
ToastUtils.showToast(this,error);
}
public void closeFresh(){}
}
4 未进行使用,可以自己再添加公共方法
public abstract class BaseMvpFragment<V extends BaseView,T extends BasePresenter<V>> extends BaseFragment {
public T presenter;
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
presenter = initPresenter();
return super.onCreateView(inflater, container, savedInstanceState);
}
@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
presenter.attach((V)this);
}
@Override
public void onDestroyView() {
presenter.dettach();
super.onDestroyView();
}
// 实例化presenter
public abstract T initPresenter();
}
5 Controller控制器拓展View的显示方法,和presenter对应
public interface JobController {
interface View extends BaseView {
void showFTJobs(List<Job.RowsBean> rows);
void showMorJobs(List<Job.RowsBean> rows);
}
interface Presenter {
void getFTJob(Map<String, String> map,boolean more);
}
}
6 Presenter的实例化例子 继承Base实现要展示的presenter接口
public class JobPresenter extends BasePresenter<JobController.View> implements JobController.Presenter {
@Override
public void getFTJob(Map<String, String> map, boolean more) {
showLoading("数据加载中...");
HttpUtils.getInstance().getAppJobReleasList(App.tokenId,map).enqueue(new Callback<Job>() {
@Override
public void onResponse(Call<Job> call, Response<Job> response) {
if (mView != null){
mView.hideLoading();
mView.closeFresh();
if (response.body() != null){
if (response.body().getnRes() == 1){
if (more){
mView.showMorJobs(response.body().getRows());
}else {
mView.showFTJobs(response.body().getRows());
}
}else {
mView.showError(response.body().getVcRes());
}
}else {
mView.showError("获取响应为空");
}
}
}
@Override
public void onFailure(Call<Job> call, Throwable t) {
showResponseFail();
}
});
}
}
7 Activity实例
public class JobSearchActivity extends BaseMvpActivity<JobController.View, JobPresenter> implements JobController.View {
@BindView(R.id.topbar_left)
RelativeLayout topbarLeft;
@BindView(R.id.topbar_title)
TextView topbarTitle;
@BindView(R.id.rv_hot_search)
RecyclerView rvHotSearch;
@BindView(R.id.et_search)
EditText etSearch;
@BindView(R.id.rv_ft_job)
RecyclerView rvFtJob;
@BindView(R.id.refreshlayout)
SmartRefreshLayout refreshlayout;
private int PAGE = 1;
private int ROWS = 10;
private Map<String, String> map = new HashMap<>();
private int currentType;//0企业招聘,,1求职简历 ,, 2零活 ,, 3散工
private JobFTAdapter ftAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_job_search);
ButterKnife.bind(this);
currentType = getIntent().getIntExtra(Constans.INTENT_SEARCH_TYPE, Constans.TYPE_FT_JOB);
initTitle();
initEditSearch();
initFreshLayout();
presenter.getClassifyJob();
}
private void initFreshLayout() {
rvFtJob.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
refreshlayout.setEnableLoadMore(false);
refreshlayout.setOnRefreshListener(new OnRefreshListener() {
@Override
public void onRefresh(@NonNull RefreshLayout refreshLayout) {
RushType(Constans.TYPE_REFRESH);
}
});
refreshlayout.setOnLoadMoreListener(new OnLoadMoreListener() {
@Override
public void onLoadMore(@NonNull RefreshLayout refreshLayout) {
RushType(Constans.TYPE_LOADMORE);
}
});
}
/**
* 刷新类型
*
* @param Type 刷新和加载更多
*/
private void RushType(int Type) {
switch (Type) {
case Constans.TYPE_REFRESH:
PAGE = 1;
map.put("page", String.valueOf(PAGE));
if (currentType == Constans.TYPE_FT_JOB) {
presenter.getFTJob(map,false);
} else if (currentType == Constans.TYPE_FT_CV){
presenter.getCVs(map,false);
}else if (currentType == Constans.TYPE_PT_JOB){
presenter.getPTJob(map,false);
}else {
presenter.getPtCVs(map,false);
}
break;
case Constans.TYPE_LOADMORE:
PAGE += 1;
map.put("page", String.valueOf(PAGE));
if (currentType == Constans.TYPE_FT_JOB) {
presenter.getFTJob(map,true);
} else if (currentType == Constans.TYPE_FT_CV){
presenter.getCVs(map,true);
}else if (currentType == Constans.TYPE_PT_JOB){
presenter.getPTJob(map,true);
}else {
presenter.getPtCVs(map,true);
}
break;
}
}
@Override
public JobPresenter initPresenter() {
return new JobPresenter();
}
private void initTitle() {
topbarLeft.setVisibility(View.VISIBLE);
map.put("page", String.valueOf(PAGE));
map.put("rows", String.valueOf(ROWS));
if (currentType == Constans.TYPE_FT_JOB) {
topbarTitle.setText("职位搜索");
map.put("jobSort", "1");
} else if (currentType == Constans.TYPE_FT_CV){
topbarTitle.setText("简历搜索");
}else if (currentType == Constans.TYPE_PT_JOB){
topbarTitle.setText("零活搜索");
}else {
topbarTitle.setText("散工搜索");
}
}
@OnClick({R.id.topbar_left_img, R.id.topbar_left})
public void onViewClicked(View view) {
switch (view.getId()) {
case R.id.topbar_left_img:
case R.id.topbar_left:
finish();
break;
}
}
@Override
public void showFTJobs(List<Job.RowsBean> rows) {
if (ftAdapter == null) {
ftAdapter = new JobFTAdapter(rows);
ftAdapter.setOnItemClickListener((adapter, view, position) -> {
Intent intent = new Intent(JobSearchActivity.this, JobDetailActivity.class);
Job.RowsBean rowsBean = (Job.RowsBean) adapter.getData().get(position);
intent.putExtra("id", rowsBean.id);
startActivity(intent);
});
rvFtJob.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
rvFtJob.setAdapter(ftAdapter);
} else {
ftAdapter.setNewData(rows);
}
//判断数据是否为空
if (ftAdapter.getData().isEmpty()) {
View emptyView = getLayoutInflater().inflate(R.layout.empty_view, (ViewGroup) rvFtJob.getParent(), false);
ftAdapter.setEmptyView(emptyView);
}
closeFreshlayout(rows == null ? 0 : rows.size());
}
@Override
public void showMorJobs(List<Job.RowsBean> rows) {
if (ftAdapter != null){
ftAdapter.addData(rows);
}
closeFreshlayout(rows == null ? 0 : rows.size());
}
private void closeFreshlayout(int size) {
if (size < ROWS) {
refreshlayout.setEnableLoadMore(false);
} else {
refreshlayout.setEnableLoadMore(true);
}
refreshlayout.setEnableRefresh(true);
refreshlayout.finishRefresh();
refreshlayout.finishLoadMore();
}
@Override
public void closeFresh() {
refreshlayout.finishLoadMore();
refreshlayout.finishRefresh();
}
@Override
public void hideLoading() {
super.hideLoading();
if (refreshlayout != null){
refreshlayout.finishRefresh();
refreshlayout.finishLoadMore();
}
}
}
8 layout 布局
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@color/white"
tools:context=".activity.JobSearchActivity">
<include layout="@layout/include_topbar" />
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/refreshlayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
>
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_ft_job"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
</LinearLayout>
9 Fragment中的使用(中间添加一个统一刷新列表的BaseFragment)
public abstract class BaseListFragment<V extends BaseView,T extends BasePresenter<V>> extends BaseMvpFragment<V,T> implements BaseView{
@BindView(R.id.rv_list)
RecyclerView rvList;
@BindView(R.id.refresh_layout)
SmartRefreshLayout refreshLayout;
Unbinder unbinder;
private int PAGE = 1;
private int ROWS = 10;
Map<String, String> map = new HashMap<>();
@Nullable
@Override
public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
super.onCreateView(inflater, container, savedInstanceState);
View view = inflater.inflate(R.layout.fragment_base_list, container, false);
unbinder = ButterKnife.bind(this, view);
initFreshLayout();
return view;
}
private void initFreshLayout() {
refreshLayout.setEnableLoadMore(false);
refreshLayout.autoRefresh();
refreshLayout.setOnRefreshListener(refreshLayout -> RushType(Constans.TYPE_REFRESH));
refreshLayout.setOnLoadMoreListener(refreshLayout -> RushType(Constans.TYPE_LOADMORE));
}
/**
* 刷新类型
*
* @param Type 刷新和加载更多
*/
private void RushType(int Type) {
switch (Type) {
case Constans.TYPE_REFRESH:
PAGE = 1;
map.put("page", String.valueOf(PAGE));
doFresh(false);
break;
case Constans.TYPE_LOADMORE:
PAGE += 1;
map.put("page", String.valueOf(PAGE));
doFresh(true);
break;
}
}
public abstract void doFresh(boolean more);
protected void closeFreshlayout(int size) {
if (size < ROWS) {
refreshLayout.setEnableLoadMore(false);
} else {
refreshLayout.setEnableLoadMore(true);
}
refreshLayout.finishRefresh();
refreshLayout.finishLoadMore();
}
@Override
public void onDestroyView() {
super.onDestroyView();
unbinder.unbind();
}
@Override
public void showLoading(String content) {
DialogShow.showRoundProcessDialog(getActivity(),content);
}
@Override
public void hideLoading() {
DialogShow.closeDialog();
}
@Override
public void showError(String error) {
ToastUtils.showToast(getContext(),error);
}
@Override
public void closeFresh() {
refreshLayout.finishRefresh();
refreshLayout.finishLoadMore();
}
}
10 fragment布局
//1.1.0 API改动过大,老用户升级需谨慎 implementation 'com.scwang.smartrefresh:SmartRefreshLayout:1.1.0-alpha-12' implementation 'com.scwang.smartrefresh:SmartRefreshHeader:1.1.0-alpha-12' implementation 'com.android.support:design:27.1.1'
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<com.scwang.smartrefresh.layout.SmartRefreshLayout
android:id="@+id/refresh_layout"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/rv_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</com.scwang.smartrefresh.layout.SmartRefreshLayout>
</LinearLayout>
11 fragment实例
public class CollectFTJobFragment extends BaseListFragment<CollectJobController.CollectJobView,CollectJobPresenter> implements CollectJobController.CollectJobView {
private int TYPE = Constans.TYPE_FT_JOB;
private JobFTAdapter ftAdapter;
private JobCVAdapter cvAdapter;
public static Fragment getInstance(int Type) {
CollectFTJobFragment collectFTJobFragment = new CollectFTJobFragment();
collectFTJobFragment.TYPE = Type;
return collectFTJobFragment;
}
@Override
public void doFresh(boolean more) {
if (TYPE == Constans.TYPE_FT_JOB) {
presenter.getCollectJobs(map,more);
} else {
presenter.getCollectCVs(map,more);
}
}
public void showFTJobs(List<Job.RowsBean> rows, boolean more) {
if (getActivity() == null || getActivity().isFinishing()) {
return;
}
if (ftAdapter == null) {
ftAdapter = new JobFTAdapter(rows);
ftAdapter.setOnItemClickListener((adapter, view, position) -> {
Intent intent = new Intent(getContext(), JobDetailActivity.class);
Job.RowsBean rowsBean = (Job.RowsBean) adapter.getData().get(position);
intent.putExtra("id", rowsBean.id);
startActivity(intent);
});
rvList.setLayoutManager(new LinearLayoutManager(getContext()));
rvList.setAdapter(ftAdapter);
} else {
if (more) {
ftAdapter.addData(rows);
} else {
ftAdapter.setNewData(rows);
}
}
//判断数据是否为空
if (ftAdapter.getData().isEmpty()) {
View emptyView = getLayoutInflater().inflate(R.layout.empty_view, (ViewGroup) rvList.getParent(), false);
ftAdapter.setEmptyView(emptyView);
}
closeFreshlayout(rows == null ? 0 : rows.size());
}
public void showCVs(List<CVBean.RowsBean> rows, boolean more) {
if (cvAdapter == null) {
cvAdapter = new JobCVAdapter(rows);
cvAdapter.setOnItemClickListener((adapter, view, position) -> {
Intent intent = new Intent(getContext(), JobCVDetailActivity.class);
CVBean.RowsBean rowsBean = (CVBean.RowsBean) adapter.getData().get(position);
intent.putExtra("id", rowsBean.id);
startActivity(intent);
});
rvList.setLayoutManager(new LinearLayoutManager(getContext()));
rvList.setAdapter(cvAdapter);
} else {
if (more) {
cvAdapter.addData(rows);
} else {
cvAdapter.setNewData(rows);
}
}
//判断数据是否为空
if (cvAdapter.getData().isEmpty()) {
View emptyView = getLayoutInflater().inflate(R.layout.empty_view, (ViewGroup) rvList.getParent(), false);
cvAdapter.setEmptyView(emptyView);
}
closeFreshlayout(rows == null ? 0 : rows.size());
}
@Override
public CollectJobPresenter initPresenter() {
return new CollectJobPresenter();
}
}