先说下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里面实现的代码就少了很多! 好了就写到这里