您的位置:首页 > 移动开发 > Android开发

android 之MVP模式的入门

2016-02-23 10:54 543 查看
先说下MVC模式,我们知道在web中有一个经典的模式就是MVC模式,那么三者分别是什么角色呢?

M:业务实体

C:Controller (一般是servlet)

V:视图 一般是jsp,

比如每个网站都有系统注册功能,而我们所看到的要填写一些相关信息的页面上的东西就是jsp,当然了还可以是什么asp之类的,当我们填写好了以后就按一下注册按钮,其实这个操作是交给了servlet去处理,当servelt去查下数据库中没有该用户时(业务逻辑,这个时候一般会产生实体),会提示用户注册成功,然后servlet会把数据传递给jsp,jsp会把这些数据显示出来,告诉用户注册成功,

而在android中,其实MVC提现的不够明显,因为activity即使C(Controller)也是V(显示视图) ,所以很多人问android MVC模式开发,他的逻辑和显示是怎么分离的,而MVP模式就能做到这点,现在我们来写个例子就知道了,然后讲下MVP模式

我们传统的在activity做这些工作,

package com.zhimore.mvppatterndemo;
import android.app.Activity;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;
public class MainActivity extends Activity {
private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
tv = (TextView) findViewById(R.id.tv);
tv.setText("我要学习MVP模式,听说很吊");

}
}


这里就明显看到setContentView(),而且还有什么findViewById()的显示视图的,而tv.setText("我要学习MVP模式,听说很吊");这样代码耦合度就有点高,我们最好把它分离开,现在我们就使用MVP模式怎么把它分开,

我们知道每个activity都要setContentView(),按照我们java面向对象的思想就是要复用,抽取出来一个父类,让每个子类继承就行,而又不知道具体的子类实现,所以要定义一个抽象的,那我们就定义一个BaseActivity

public class BaseActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
}
}


但是在BaseActivity类中这么写也不行啊,因为不知道具体的子类 视图是什么,所以我们必须要抽象出来让子类去实现自己的视图,我们知道在android中LayoutInflater类可以把一个layout文件转换成View,然后通过setContnetView(view)就行,定义一个接口:

package com.zhimore.impl.view;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
/**
* Created by Administrator on 2016/2/23.
*/
public interface IView {
//初始化view
public  void initView(LayoutInflater inflater ,ViewGroup viewGroup);
//获取view
public View getView();
}


package com.zhimore.base;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;

import com.zhimore.impl.view.IView;
import com.zhimore.mvppatterndemo.R;

/**
* Created by Administrator on 2016/2/23.
*/
public abstract class BaseActivity<SubView extends IView> extends Activity {
public  SubView mSubView;
public  View mView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
LayoutInflater inflater =  getLayoutInflater();
mSubView = getSubClass().newInstance();//获取泛型传递过来的对象
mSubView.initView(inflater,null);//初始化view
mView = mSubView.getView();//根view
setContentView(mView);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
public abstract  Class<SubView> getSubClass() ;
}


package com.zhimore.mvppatterndemo;
import android.app.Activity;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.TextView;

import com.zhimore.base.BaseActivity;
import com.zhimore.view.MainView;

public class MainActivity extends BaseActivity<MainView> {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSubView. tv.setText("我要学习MVP模式,听说很吊");
}
@Override
public Class<MainView> getSubClass() {
return MainView.class;
}
}


package com.zhimore.view;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.zhimore.impl.view.IView;
import com.zhimore.mvppatterndemo.R;

/**
* Created by Administrator on 2016/2/23.
*/
public class MainView implements IView {
public View mView;
public TextView tv;
@Override
public void initView(LayoutInflater inflater, ViewGroup viewGroup) {
mView = inflater.inflate(R.layout.content_main,viewGroup);
findView();
}
private void findView() {
tv = (TextView) mView.findViewById(R.id.tv);
}

@Override
public View getView() {
return mView;
}
}


我们发现现在在activity中直接处理我们的业务就行,什么findViewById()和setContentView()都封装在一个类中了,使用接口分离开了,

在这些操作中,MVP的角色是

M:这个由于简单的使用没有使用mode,

C:现在的activity真正做到了控制和处理业务逻辑了

P:MainView就是连接M和C的桥梁了,

这样更好的维护,而且代码比之前的更加清晰,但是引入了更多的类,这算是MVP的缺点吧

那我们在adapter使用这个试试,

MyBaseAdapter.java 这个类做了些封装,具体的请看代码

package com.zhimore.base;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import com.zhimore.impl.view.IView;
import java.util.List;

/**
* Created by Administrator on 2016/2/23.
*/
public abstract  class MyBaseAdapter<SubAdapterView extends IView,Y extends List> extends BaseAdapter {
private static final String TAG ="MyBaseAdapter" ;
public SubAdapterView mSubAdapterView;
private LayoutInflater inflater;
private Y tempT;

public void setTempT(Y tempT) {
this.tempT = tempT;
}

public MyBaseAdapter(LayoutInflater inflater)  {
this.inflater = inflater;
try {
mSubAdapterView = getSubAdapterClass().newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
if(convertView==null){
try {
mSubAdapterView.initView(inflater,parent);
convertView =  mSubAdapterView.getView();
convertView.setTag(mSubAdapterView);
} catch (Exception e) {
e.printStackTrace();
}
}else{
mSubAdapterView = (SubAdapterView) convertView.getTag();
}
if(convertView!=null){
onBindData();
}
return convertView;
}
//绑定数据
protected abstract void onBindData();
public abstract Class<SubAdapterView> getSubAdapterClass();
@Override
public int getCount() {
return tempT!=null?tempT.size():0;
}
@Override
public Object getItem(int position) {
return tempT.get(position);
}
@Override
public long getItemId(int position) {
return position;
}
}


子类的实现:

package com.adapter;
import android.view.LayoutInflater;
import com.zhimore.base.MyBaseAdapter;
import com.zhimore.view.NewsView;
import java.util.List;
/**
* Created by Administrator on 2016/2/23.
*/
public class NewsAdapter extends MyBaseAdapter<NewsView,List<String>> {
public NewsAdapter(LayoutInflater inflater) {
super(inflater);
}
@Override
protected void onBindData() {
mSubAdapterView.tv_show_news.setText("刘德华要来杭州了");
}
@Override
public Class<NewsView> getSubAdapterClass() {
return NewsView.class;
}
}


显示:

package com.zhimore.mvppatterndemo;
import android.os.Bundle;
import com.adapter.NewsAdapter;
import com.zhimore.base.BaseActivity;
import com.zhimore.view.MainView;
import com.zhimore.view.MainView;
import java.util.ArrayList;
import java.util.List;

public class MainActivity extends BaseActivity<MainView> {
private NewsAdapter adapter;
private List<String> mDatas;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDatas = new ArrayList<>();
for(int i=0;i<100;i++){
mDatas.add("mvp模式上今日头条了,我擦");
}
adapter = new NewsAdapter(getLayoutInflater());
adapter.setTempT(mDatas);
mSubView.listview.setAdapter(adapter);
}
@Override
public Class<MainView> getSubClass() {
return MainView.class;
}
}


这样每个继承了MyBaseAdapter里面实现的代码就少了很多! 好了就写到这里
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: