之前在网上看了很多关于MVP模式的文章,看了文字描述总是可以看懂的。但是,写的时候却无从下手。
MVP模式MVP(Model-View-Presenter)是MVC的演化版本,MVP的角色定义如下。
- Model:主要提供数据的存取功能。Presenter需要通过Model层来存储、获取数据。
- View:负责处理用户事件和视图部分的展示。在Android中,它可能是Activity、Fragment类或者是某
个View控件。- Presenter:作为View和Model之间沟通的桥梁,它从Model层检索数据后返回给View层,使得View和
Model之间没有耦合。 在MVP里,Presenter完全将Model和View进行了分离,主要的程序逻辑在Presenter里实现。而且,Presenter与具体的View是没有直接关联的,而是通过定义好的接口进行交互,从而使得在变更View时可以保持Presenter的不变,这点符合面向接口编程的特点。View只应该有简单的Set/Get方法,以及用户输入和设置界面显示的内容,除此之外就不应该有更多的内容。绝不允许View直接访问Model,这就是其与MVC的很大不同之处。
所以,俺将之前写的demo转变为MVP模式,实际操作一番,加深理解。
总共可以分为4步:
- 首先创建一个契约接口MainContract来管理接口
- 创建model类来接收返回的数据
- 创建一个presenter类来实现程序逻辑
- 在View层进行UI的更新
这个demo主要实现的功能是:
点击按钮拍照,调用API对图片进行文字识别,并返回识别数据,显示在TextView上。
demo截图1.MainContract
首先定义一个契约接口MainContract,契约接口主要用来存放相同业务的Presenter和View的接口,便于查找和维护。
public class MainContract {
interface Presenter{
void getText(Bitmap bitmap);//得到识别的文字
}
interface View{
void updateText(String text);//更新UI,显示文字
}
}
2.Model
用来接收服务器传回的数据。
public class HttpResult{
private String request_id;
private List<Bean> ret;
private boolean success;
}
class Bean{
private Rect rect;
private String word;
class Rect{
private float angle;
private float height;
private float left;
private float top;
private float width;
}
}
3.Presenter
创建Mainpresenter类,实现MainContract.Presenter接口,在getText()方法里调用文字识别的API,返回数据后更新UI。
public class MainPresenter implements MainContract.Presenter {
private MainContract.View mView;
public MainPresenter(MainContract.View mView) {
this.mView = mView;
}
@Override
public void getText(Bitmap bitmap) {
//这里请求的是阿里云的ocr接口
call.enqueue(new Callback<HttpResult>() {
@Override
public void onResponse(Call<HttpResult> call, Response<HttpResult> response) {
List<Bean> beans = response.body().getRet();
String text = "";
for (Bean bean : beans)
text += bean.getWord()+"\n";
mView.updateText(text);//得到返回的数据后更新UI
}
}
@Override
public void onFailure(Call<HttpResult> call, Throwable t) {
Log.e(TAG, "onFailure: "+t.getMessage());
}
});
}
}
4.View
在activity中实现MainContract.View的接口。
public class MainActivity extends AppCompatActivity implements MainContract.View{
Button button;
private MainPresenter presenter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
presenter.getText(bitmap);//调用文字识别的接口
}
});
}
@Override
public void updateText(String text) {
textView.setText(text);//拿到数据,更新UI
}
}
整个目录的结构如下:
目录结构通过以上代码可以看出,View与Presenter通过接口互相交互,并在Activity中进行相互注入,而与Model之间没有联系。
在这里我只给出了核心代码内容,重要的不是如何实现,而是理解其中的思想~
将自己之前的代码改一改,多写几遍,你也可以理解的。
加油,一起努力吧!
网友评论