前言
框架发展mvc mvp mvvm mvpvm
MVP把Activity,Framgent中的UI逻辑抽象成View接口
把业务逻辑交给Presenter主持
Model类还是原来的Model
使用MVP的好处
分离了视图逻辑和业务逻辑,降低了耦合
Activity只处理生命周期的任务,代码变得更加简洁
视图逻辑和业务逻辑分别抽象到了View和Presenter的接口中去,提高代码的可阅读性
业务逻辑抽到Presenter中去,避免后台线程引用着Activity导致Activity的资源无法被系统回收从而引起内存泄露和OOM
- 目录结构
- MVP实例
把一个大虾串通过mvp模式下载,并在recycleView中展示.
IModel
public interface IModel {
//销毁方法
void destroy();
}
IPrsenter
public interface IPresenter {
//销毁方法
void destroy();
}
IView
public interface IView {
//展示吐司
void showToast(String msg);
//展示消息
void showLoading();
//隐藏消息
void hideLoading();
}
IActivity
public interface IActivity {
//绑定布局
int bindLayout();
//获取数据
void initData();
//初始化控件
void initView();
}
IFragment
//所有fragment的顶层接口
public interface IFragment extends IActivity {
View getViewById(@IdRes int id);
}
BaseFragment
public abstract class BaseFragment<P extends IPresenter> extends Fragment implements IView,IFragment {
protected View mView;
protected P mPresenter;
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
return mView = inflater.inflate(bindLayout(),container,false);
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
initView();
initData();
}
@Override
public View getViewById(int id) {
return mView.findViewById(id);
}
@Override
public void onDestroy() {
super.onDestroy();
if(mPresenter != null){
mPresenter.destroy();
}
}
@Override
public void showLoading() {
}
@Override
public void hideLoading() {
}
@Override
public void showToast(String msg) {
}
}
BaseActivity
public abstract class BaseActivity<P extends IPresenter> extends AppCompatActivity implements IView,IActivity {
protected P mPresenter;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(bindLayout());
initView();
initData();
}
@Override
public void showToast(String msg) {
Toast.makeText(this,msg,Toast.LENGTH_SHORT).show();
}
@Override
protected void onDestroy() {
super.onDestroy();
if (mPresenter!=null){
mPresenter.destroy();
}
}
}
BaseModel
public class BaseModel implements IModel {
@Override
public void destroy() {
}
}
BaseIPresenter
public class BasePresenter<M extends IModel,V extends IView> implements IPresenter {
protected M mModel;
protected V mView;
public BasePresenter(M mModel, V mView) {
this.mModel = mModel;
this.mView = mView;
}
@Override
public void destroy() {
}
}
到此准备架构结束
实现展示大虾串:http://www.qubaobei.com/ios/cf/dish_list.php?stage_id=1&limit=20&page=1
FoodAdapter
import android.widget.ImageView;
import com.bumptech.glide.Glide;
import com.chad.library.adapter.base.BaseMultiItemQuickAdapter;
import com.chad.library.adapter.base.BaseViewHolder;
import com.example.a12_8mvp_lx.R;
import com.example.a12_8mvp_lx.food.entity.FoodEntity;
import java.util.List;
//适配器
public class FoodAdapter extends BaseMultiItemQuickAdapter<FoodEntity.DataBean, BaseViewHolder> {
/**
* Same as QuickAdapter#QuickAdapter(Context,int) but with
* some initialization data.
*
* @param data A new list is created out of this one to avoid mutable list
*/
public FoodAdapter(List<FoodEntity.DataBean> data) {
super(data);
addItemType(0, R.layout.item);
}
@Override
protected void convert(BaseViewHolder helper, FoodEntity.DataBean item) {
helper.setText(R.id.tv,item.getTitle());
Glide.with(mContext).load(item.getPic()).into((ImageView)helper.getView(R.id.img));
}
}
FoodEntity
package com.example.a12_8mvp_lx.food.entity;
import com.chad.library.adapter.base.entity.MultiItemEntity;
import java.util.List;
public class FoodEntity {
/**
* ret : 1
* data : [{"id":"8289","title":"油焖大虾","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/9/8289.jpg","collect_num":"1670","food_str":"大虾 葱 生姜 植物油 料酒","num":1670},{"id":"2127","title":"四川回锅肉","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/3/2127.jpg","collect_num":"1591","food_str":"猪肉 青蒜 青椒 红椒 姜片","num":1591},{"id":"30630","title":"超简单芒果布丁","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/31/30630.jpg","collect_num":"1552","food_str":"QQ糖 牛奶 芒果","num":1552},{"id":"9073","title":"家常红烧鱼","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/10/9073.jpg","collect_num":"1426","food_str":"鲜鱼 姜 葱 蒜 花椒","num":1426},{"id":"10097","title":"家常煎豆腐","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/11/10097.jpg","collect_num":"1420","food_str":"豆腐 新鲜红椒 青椒 葱花 油","num":1420},{"id":"10509","title":"水煮肉片","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/11/10509.jpg","collect_num":"1342","food_str":"瘦猪肉 生菜 豆瓣酱 干辣椒 花椒","num":1342},{"id":"46968","title":"红糖苹果银耳汤","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/47/46968.jpg","collect_num":"1253","food_str":"银耳 苹果 红糖","num":1253},{"id":"10191","title":"麻婆豆腐","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/11/10191.jpg","collect_num":"1224","food_str":"豆腐 肉末 生抽 白糖 芝麻油","num":1224},{"id":"2372","title":"皮蛋瘦肉粥","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/3/2372.jpg","collect_num":"1151","food_str":"大米 皮蛋 猪肉 油条 香葱","num":1151},{"id":"2166","title":"蚂蚁上树","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/3/2166.jpg","collect_num":"1145","food_str":"红薯粉 肉 姜 蒜 花椒","num":1145},{"id":"2262","title":"糖醋肉","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/3/2262.jpg","collect_num":"1082","food_str":"猪肉 红椒 黄椒 洋葱 蛋清","num":1082},{"id":"9971","title":"鱼香豆腐","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/10/9971.jpg","collect_num":"1010","food_str":"豆腐 木耳 胡萝卜 香葱 番茄酱","num":1010},{"id":"10172","title":"干煸四季豆","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/11/10172.jpg","collect_num":"993","food_str":"四季豆 干辣椒 蒜头 酱油 糖","num":993},{"id":"2685","title":"胡萝卜肉末蒸蛋","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/3/2685.jpg","collect_num":"929","food_str":"胡萝卜 肉 蛋 生抽 盐","num":929},{"id":"9972","title":"虎皮青椒","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/10/9972.jpg","collect_num":"892","food_str":"青辣椒 大蒜 香醋 白糖 生抽","num":892},{"id":"10437","title":"叉烧排骨","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/11/10437.jpg","collect_num":"806","food_str":"排骨 李锦记叉烧酱 植物油 清水 油菜","num":806},{"id":"2892","title":"\u201c五行\u201d彩蔬汤","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/3/2892.jpg","collect_num":"761","food_str":"黑木耳 玉米 牛蒡 胡萝卜 西兰花","num":761},{"id":"2348","title":"麻辣肉丝面","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/3/2348.jpg","collect_num":"760","food_str":"面条 肉丝 淀粉 酱油 辣椒","num":760},{"id":"10044","title":"土豆炖翅根","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/11/10044.jpg","collect_num":"758","food_str":"土豆 翅根 葱 姜 料酒","num":758},{"id":"33783","title":"美人豆浆","pic":"http://www.qubaobei.com/ios/cf/uploadfile/132/34/33783.jpg","collect_num":"758","food_str":"黄豆 红豆 绿豆 黑豆 黑米","num":758}]
*/
private int ret;
private List<DataBean> data;
public int getRet() {
return ret;
}
public void setRet(int ret) {
this.ret = ret;
}
public List<DataBean> getData() {
return data;
}
public void setData(List<DataBean> data) {
this.data = data;
}
//实现MultiItemEntity 方法
public static class DataBean implements MultiItemEntity {
/**
* id : 8289
* title : 油焖大虾
* pic : http://www.qubaobei.com/ios/cf/uploadfile/132/9/8289.jpg
* collect_num : 1670
* food_str : 大虾 葱 生姜 植物油 料酒
* num : 1670
*/
private String id;
private String title;
private String pic;
private String collect_num;
private String food_str;
private int num;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
public String getCollect_num() {
return collect_num;
}
public void setCollect_num(String collect_num) {
this.collect_num = collect_num;
}
public String getFood_str() {
return food_str;
}
public void setFood_str(String food_str) {
this.food_str = food_str;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
//添加类型type
private int type;
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
@Override
public int getItemType() {
return type;
}
}
}
FoodContract
import com.example.a12_8mvp_lx.food.entity.FoodEntity;
import com.example.a12_8mvp_lx.mvp.model.IModel;
import com.example.a12_8mvp_lx.mvp.view.IView;
import java.util.List;
import okhttp3.Callback;
public interface FoodContract {
public interface IFoodModel extends IModel{
void getFoodData(Callback callback);
}
public interface IFoodView extends IView{
void initAdapter(List<FoodEntity.DataBean> list);
}
}
M层
FoodModel
import com.example.a12_8mvp_lx.food.mvp.contract.FoodContract;
import com.example.a12_8mvp_lx.mvp.model.BaseModel;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
public class FoodModel extends BaseModel implements FoodContract.IFoodModel {
@Override
public void getFoodData(Callback callback) {
OkHttpClient.Builder builder = new OkHttpClient.Builder();
OkHttpClient build = builder.build();
Request.Builder request = new Request.Builder();
Request build1 = request.get().url("http://www.qubaobei.com/ios/cf/dish_list.php?stage_id=1&limit=20&page=1").build();
build.newCall(build1).enqueue(callback);
}
}
P层
FoodPresenter
package com.example.a12_8mvp_lx.food.mvp.presenter;
import com.example.a12_8mvp_lx.food.entity.FoodEntity;
import com.example.a12_8mvp_lx.food.mvp.contract.FoodContract;
import com.example.a12_8mvp_lx.mvp.presenter.BasePresenter;
import com.google.gson.Gson;
import org.jetbrains.annotations.NotNull;
import java.io.IOException;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;
public class FoodPresenter extends BasePresenter<FoodContract.IFoodModel,FoodContract.IFoodView> {
public FoodPresenter(FoodContract.IFoodModel mModel, FoodContract.IFoodView mView) {
super(mModel, mView);
}
public void getData(){
mModel.getFoodData(new Callback() {
@Override
public void onFailure(@NotNull Call call, @NotNull IOException e) {
}
@Override
public void onResponse(@NotNull Call call, @NotNull Response response) throws IOException {
String string = response.body().string();
FoodEntity foodEntity = new Gson().fromJson(string, FoodEntity.class);
mView.initAdapter(foodEntity.getData());
}
});
}
}
V 层
MainActivity
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.StaggeredGridLayoutManager;
import com.example.a12_8mvp_lx.food.adapter.FoodAdapter;
import com.example.a12_8mvp_lx.food.entity.FoodEntity;
import com.example.a12_8mvp_lx.food.mvp.contract.FoodContract;
import com.example.a12_8mvp_lx.food.mvp.model.FoodModel;
import com.example.a12_8mvp_lx.food.mvp.presenter.FoodPresenter;
import com.example.a12_8mvp_lx.mvp.presenter.BasePresenter;
import com.example.a12_8mvp_lx.mvp.view.BaseActivity;
import java.util.List;
public class MainActivity extends BaseActivity<BasePresenter> implements FoodContract.IFoodView {
RecyclerView rv;
FoodPresenter foodPresenter;
@Override
public int bindLayout() {
//绑定布局
return R.layout.activity_main;
}
@Override
public void initView() {
rv = findViewById(R.id.rv);
//new 一个p层对象
foodPresenter = new FoodPresenter(new FoodModel(), this);
}
@Override
public void initData() {
//获取数据
foodPresenter.getData();
}
@Override
public void showLoading() {
}
@Override
public void hideLoading() {
}
@Override
public void initAdapter(List<FoodEntity.DataBean> list) {
//new适配器
final FoodAdapter foodAdapter = new FoodAdapter(list);
runOnUiThread(new Runnable() {
@Override
public void run() {
//设置适配器
rv.setLayoutManager(new StaggeredGridLayoutManager(2,StaggeredGridLayoutManager.VERTICAL));
rv.setAdapter(foodAdapter);
}
});
}
}