android 之MVP模式的入门

先说下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 {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mSubView. tv.setText("我要学习MVP模式,听说很吊");
    }
    @Override
    public Class 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,List> {
    public NewsAdapter(LayoutInflater inflater) {
        super(inflater);
    }
    @Override
    protected void onBindData() {
        mSubAdapterView.tv_show_news.setText("刘德华要来杭州了");
    }
    @Override
    public Class 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 {
    private NewsAdapter adapter;
    private List 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 getSubClass() {
        return MainView.class;
    }
}

这样每个继承了MyBaseAdapter里面实现的代码就少了很多! 好了就写到这里



你可能感兴趣的:(android)