Giter Club home page Giter Club logo

android-mvp's Introduction

#Android MVP框架学习 ###github地址:https://github.com/chenmingIT/Android-MVP


##Android MVC框架

MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)。其中M层处理数据,业务逻辑等;V层处理界面的显示结果;C层起到桥梁的作用,来控制V层和M层通信以此来达到分离视图显示和业务逻辑层。
在Android开发中,比较流行的开发框架模式采用的是MVC框架模式,采用MVC模式的好处是便于UI界面部分的显示和业务逻辑,数据处理分开。
在Android项目中,业务逻辑,数据处理等担任了Model(模型)角色,XML界面显示等担任了View(视图)角色,Activity担任了Contronller(控制器)角色。contronller(控制器)是一个中间桥梁的作用,通过接口通信来协同 View(视图)和Model(模型)工作,起到了两者之间的通信作用。
在MVC模式中我们发现,其实控制器Activity主要是起到解耦作用,将View视图和Model模型分离,虽然Activity起到交互作用,但是找Activity中有很多关于视图UI的显示代码,因此View视图和Activity控制器并不是完全分离的,也就是说一部分View视图和Contronller控制器Activity是绑定在一个类中的。 ##Android MVP框架 ###MVC架构
View:对应于布局文件
Model:业务逻辑和实体模型
Controllor:对应于Activity ###MVP架构 View:对应于Activity,负责View的绘制以及与用户交互
Model:依然是业务逻辑和实体模型
Presenter:负责完成View于Model间的交互
简化了Activity中的代码,将复杂的逻辑代码提取到了Presenter中进行处理。与之对应的好处就是,耦合度更低,更方便的进行测试。 ###实践 以简单的登陆为例子。
1、先做出界面

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/activity_main"
	android:layout_width="match_parent"
	android:layout_height="match_parent"
	android:padding="15dp"
	android:orientation="vertical">
	<EditText
	    android:id="@+id/username"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:hint="用户名"/>
	<EditText
	    android:id="@+id/password"
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:hint="密码"/>
	<LinearLayout
	    android:layout_width="match_parent"
	    android:layout_height="wrap_content"
	    android:orientation="horizontal">
	    <Button
	        android:id="@+id/login"
	        android:layout_width="0dp"
	        android:layout_height="wrap_content"
	        android:layout_weight="1"
	        android:text="登陆"/>
	    <Button
	        android:id="@+id/cancel"
	        android:layout_width="0dp"
	        android:layout_height="wrap_content"
	        android:layout_weight="1"
	        android:text="取消"/>
	</LinearLayout>
</LinearLayout>

2、首先做Model层,Model层主要是包括数据类型bean和业务逻辑biz。创建两个包bean用以放数据类型和biz用以放Model层的业务逻辑。在bean包下面创建User类,包括username和password两个成员并提供set和get方法,比较简单。
3、在biz包中创建一个IUserBiz接口用以放User类的业务逻辑,并创建UserBiz作为IUserBiz接口的实现类,用以放Model层的业务逻辑。
整理逻辑主要有一个登陆的业务逻辑,同时,登陆需要回调,所以在biz下面添加一个回调接口OnLoginListener,下面放成功和失败的方法。

public interface OnLoginListener {
	void loginSuccess(User user);
	void loginFailed();
}

在IUserBiz加入登陆业务逻辑方法。

public class UserBiz implements IUserBiz {
	@Override
	public void login(String username, String password, OnLoginListener loginListener) {
		if(username.equals("username")&&password.equals("password")){
			User user = new User() ;
			user.setPassword(password);
			user.setUsername(username);
			loginListener.loginSuccess( user );
		}else {
			loginListener.loginFailed();
		}
	}
}

4、View层
Presenter与View交互是通过接口,因此要新建一个ILoginView接口,用途是放View层的方法。
首先获取用户输入的用户名密码需要方法,登陆按钮对应登陆成功和失败的方法,和取消登录需要清空用户名和密码的方法,因此ILoginView如下。

public interface ILoginView {
	public String getUsername() ;
	public String getPassword() ;
	public void loginSuccess(User user) ;
	public void loginFail() ;
	public void clearUsername() ;
	public void clearPassword() ;
}

之后写Activity,需要实现ILoginView。

public class LoginActivity extends AppCompatActivity implements ILoginView{

	EditText username,password ;
	Button login,cancel ;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		username = (EditText)findViewById(R.id.username) ;
		password = (EditText)findViewById(R.id.password) ;
		login = (Button)findViewById(R.id.login) ;
		cancel = (Button)findViewById(R.id.cancel) ;	
	}

	@Override
	public String getPassword() {
		return password.getText().toString() ;
	}

	@Override
	public String getUsername() {
		return username.getText().toString() ;
	}

	@Override
	public void clearPassword() {
		password.setText("");
	}

	@Override
	public void clearUsername() {
		username.setText("");
	}

	@Override
	public void loginFail() {
		Toast.makeText(this,"登陆失败",Toast.LENGTH_SHORT).show(); 
	}

	@Override
	public void loginSuccess(User user) {
		Toast.makeText(this,"登陆成功",Toast.LENGTH_SHORT).show(); 
	}
}

5、Presenter层
已经有了Model层和View层了,现在需要有Presenter层。新建presenter包,下面新建一个ILoginPresenter接口和LoginPresenter实现(接口的意义就在于便于扩展和维护)。
ILoginPresenter接口方法无非就两个,登陆和取消。

public interface ILoginPresenter {
	public void login() ;
	public void clear() ;
}

实现中,Presenter层就像粘合剂,因此需要引入IUserBiz和ILoginView成员。

public class LoginPresenter implements ILoginPresenter {
	IUserBiz userBiz ;
	ILoginView iLoginView ;
	public LoginPresenter(ILoginView iLoginView){
		this.userBiz = new UserBiz() ;
		this.iLoginView = iLoginView ;
	}

	@Override
	public void login() {
		String username = iLoginView.getUsername() ;
		String password = iLoginView.getPassword() ;
		userBiz.login(username, password, new OnLoginListener() {
			@Override
			public void loginSuccess(User user) {
				iLoginView.loginSuccess(user);
			}
			@Override
			public void loginFailed() {
				iLoginView.loginFail();
			}
		});
	}
	@Override
	public void clear() {
		iLoginView.clearPassword();
		iLoginView.clearUsername();
	}
}

6、回到Activity,需要加入ILoginPresenter成员。交互的时候,需要调用它的方法。

loginPresenter = new LoginPresenter(this) ;
login.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
		loginPresenter.login();
	}
});
cancel.setOnClickListener(new View.OnClickListener() {
	@Override
	public void onClick(View v) {
		loginPresenter.clear();
	}
});

###总结 MVP中把Layout布局和Activity作为View层,增加了Presenter,Presenter层与Model层进行业务的交互,完成后再与View层交互(也就是Activity)进行回调来刷新UI。这样一来,所有业务逻辑的工作都交给了Presenter中进行,使得View层与Model层的耦合度降低,Activity中的工作也进行了简化。
MVP之Model
模型这一层之中做的工作是具体业务逻辑处理的实现,都伴随着程序中各种数据的处理,复杂一些的就明显需要实现一个Interface来松耦合了。一般分为数据类型bean和业务逻辑处理与数据库交互等等biz(business缩写)。
MVP之View
视图这一层体现的很轻薄,负责显示数据、提供友好界面跟用户交互就行。MVP下Activity和Fragment体现在了这一 层,Activity一般也就做加载UI视图、设置监听再交由Presenter处理的一些工作,所以也就需要持有相应Presenter的引用。例 如,Activity上滚动列表时隐藏或者显示Acionbar(Toolbar),这样的UI逻辑时也应该在这一层。另外在View上输入的数据做一些 判断时,例如,EditText的输入数据,假如是简单的非空判断则可以作为View层的逻辑,而当需要对EditText的数据进行更复杂的比较时,如 从数据库获取本地数据进行判断时明显需要经过Model层才能返回了,所以这些细节需要自己掂量。即这一层主要是View显示和View操作控件操作,如监听按钮然后把事件交给Presenter,由它进行分发。
MVP之Presenter
Presenter这一层处理着程序各种逻辑的分发,收到View层UI上的反馈命令、定时命令、系统命令等指令后分发处理逻辑交由Model层做具体的业务操作。
可以看见,这样能脱离View进行调试,而且代码结构更清楚,当然,代码量也变多了。

android-mvp's People

Contributors

chenmingit avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.