Android的一种MVP模式框架
今天给大家分享的是一种将view的初始化和逻辑与activity分离的架构,采用的是mvp模式。但令人遗憾的是,这仅仅是一个新的思路,我在实际使用中发现其并不能完全将UI逻辑与activity分开,所以在实际中没办法认为这种设计是合理的。设计的初衷是觉得activity要接收intent或者要进行很多其他的处理,很难让人认为activity是一个与View相关的类,所以我们的想法是将view的逻辑从activity中分离,这种分离的方式我们就要用到一个UI类的接口。这个思路来自:https://github.com/wongcain/MVP-Simple-Demo,我仅仅是对作者的代码进行了分析和小部分修改。
ViewUiImp.java
package frame.kale.com.frame; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup; /**
* @author Jack Tony
* @brief
* @date 2015/4/4
*/
public interface ViewUiImp { /**
*
* @param inflater
* @param container
*/
public void initViews(LayoutInflater inflater, ViewGroup container); public View getRootView();
}
这个接口中只有两个方法,一个是初始化views的方法,一个是得到根view的方法。我们希望activity仅仅与这个接口进行交互,而不用管view的逻辑。view的逻辑判断都是在实现这个接口的类中来进行的。为了让activity能更好的复用 代码,这里我们需要创建一个 activity的基类。
BasePresenterActivity.java
package frame.kale.com.frame; import android.app.Activity;
import android.os.Bundle; /**
* @author Jack Tony
* @brief 与activity有关的表现层的基类
* @date 2015/4/4
*/
public abstract class BasePresenterActivity <V extends ViewUiImp> extends Activity {
protected V uiImp; // ViewUiImp的对象 @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
try {
// 产生一个对象,并且调用initViews方法来初始化views
uiImp = getViewUiClass().newInstance();
uiImp.initViews(getLayoutInflater(), null);
// 把根view设置到activity中
setContentView(uiImp.getRootView());
// 绑定views
onBindViewUi();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
} /**
* 当activity退出后,通过onDestroyViewUi来销毁views
*/
@Override
protected final void onDestroy() {
onDestroyViewUi();
uiImp = null;
super.onDestroy();
} protected abstract Class<V> getViewUiClass(); /**
* 绑定views时触发的方法
*/
protected void onBindViewUi(){} /**
* 移出views时触发的方法
*/
protected void onDestroyViewUi() {}
}
可以看到我们通过newInstance()来初始化了一个ViewUiImp对象,并且通过getRootView()来得到根view,之后将这个根view设置进了activity中。这些步骤中我们看到的都是接口对象,没有任何实体,灵活性很强。此外,在activity初始化或者销毁时都会触发view被绑定或被销毁时的回调,便于我们在activity的子类中进行操作。
现在,我们搭好了框架,那么就来尝试写一个实现类来看看效果如何吧。
package frame.kale.com.frame; import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView; /**
* @author Jack Tony
* @brief
* @date 2015/4/4
*/
public class HelloWorldViewUi implements ViewUiImp{ private View rootView; public TextView helloWorldTv;
public EditText msgEt; @Override
public void initViews(LayoutInflater inflater, ViewGroup container) {
rootView = inflater.inflate(R.layout.activity_main, container, false);
helloWorldTv = (TextView) rootView.findViewById(R.id.textView);
msgEt = (EditText) rootView.findViewById(R.id.editText);
} @Override
public View getRootView() {
return rootView;
}
}
这个类很简单,做了初始化views和返回根view的操作。目前看来findviewById的方法和view的逻辑都可以在这里进行。那么我们在activity的实现类中会做什么事情呢?我们做的事情也很简单,只需要继承我们刚写的基类,并且注入一个HelloWorldViewUi对象就可以了。
public class MainActivity extends BasePresenterActivity<HelloWorldViewUi> { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
uiImp.helloWorldTv.setText("12345");
} @Override
protected Class<HelloWorldViewUi> getViewUiClass() {
return HelloWorldViewUi.class;
} }
我们可以利用这个uiImp对象来操作布局中定义的各种view,确实很简洁方便。但问题又来了!这里看到的确实是将ui和activity进行了抽离,但activity仍旧会进行ui逻辑的操作,对于menu这样的初始化和定义还是在activity中进行的,所以目前来看view和activity没有完全的独立开。比如下面的代码就很难放入uiImp接口中去。
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId(); //noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
} return super.onOptionsItemSelected(item);
}
总结一下就是这个思路很不错,但在实际使用中还是有一定问题的,以后还得多思考多研究啊。
源码下载:http://download.csdn.net/detail/shark0017/8565091
参考自:
https://github.com/wongcain/MVP-Simple-Demo
https://github.com/bboyfeiyu/android-tech-frontier/tree/master/androidweekly/%E4%B8%80%E7%A7%8D%E5%9C%A8android%E4%B8%AD%E5%AE%9E%E7%8E%B0MVP%E6%A8%A1%E5%BC%8F%E7%9A%84%E6%96%B0%E6%80%9D%E8%B7%AF
Android的一种MVP模式框架的更多相关文章
- Android开发之初识MVP模式
各位亲爱的小伙伴,有没有想我啊,我胡汉wing又回来了. 很长一段时间没有更新博客..原因是..从离职回到学校以后,一直在享受最后的学生时光(打游戏).. 游戏固然很爽,但是觉得实在很荒废,于是半夜诈 ...
- 高通方案的Android设备几种开机模式的进入与退出
高通方案的Android设备主要有以下几种开机模式,Android.EDL.Fastboot.Recovery和FFBM,其进入及退出的方式如下表. 开机模式 屏幕显示 冷启动 热启动 按键退出 命令 ...
- android:Activity四种启动模式简单介绍
Activity启动模式 能够依据实际的需求为Activity设置相应的启动模式,从而能够避免创建大量反复的Activity等问题 Activity有四种载入模式 1.standard(默认启动模式, ...
- Java(Android)编程思想笔记03:在Android开发中使用MVP模式
1. MVP模式简介: MVC模式相信大家肯定是比较熟悉的:M-Model-模型.V-View-视图.C-Controller-控制器. MVP作为MVC的演化版本,那么类似的MVP所对应的意义:M- ...
- Android Activity 四种启动模式
task和back stack(任务和回退栈) 任务启动,task被加入到回退栈的栈顶,返回的时候回退栈的栈顶任务会被弹出,并被销毁,栈中的前一任务恢复运行,当activity销毁是,系统不会保留ac ...
- 理解Android的四种启动模式
一:前言 四种模式分别为standard, singleTop, singleTask, singleInstance.自己应该明确一个概念先,single到底要single什么.每一个应用app都有 ...
- Android 知识杂记(MVP模式)
MVP的模式在于将原来activity中业务逻辑的部分剥离出来,代码示例如下: Account public class Account { private String mUsername; pri ...
- android launchmode(四种启动模式)应用场景及实例
模式介绍 [1] standard 模式 这是默认模式,每次激活Activity时都会创建Activity实例,并放入任务栈中. [2] singleTop 模式 如果在任务的栈顶正好存在该Activ ...
- android activity四种启动模式
1.standard <activity android:name=".MainActivity" android:launchMode="standard&quo ...
随机推荐
- 入门:PHP:hello world!
<?php echo 'hello'."\n"." world!"."good night!";//2016.09.18 22:57? ...
- Photoshop 融合属性 Unity Shader
http://forum.unity3d.com/threads/free-photoshop-blends.121661/
- AspnetIdentitySample
https://github.com/rustd/AspnetIdentitySample http://www.asp.net/web-forms/overview/getting-started/ ...
- System.out.println与System.err.println的区别(输出顺序!!!)
System.out.println与System.err.println的区别(输出顺序!!!) 分类:java (208) (0) System.out.println与System.err.p ...
- linux 下 zip unzip压缩与解压
注:*压缩成限.zip格式文件 常用解压缩: [root@mysql test]# unzip -o test.zip -d tmp/ 将压缩文件test.zip在指定目录tmp下解压缩,如果已有相同 ...
- 使用Alcatraz来管理Xcode插件(转)
转自唐巧的博客:http://blog.devtang.com/blog/2014/03/05/use-alcatraz-to-manage-xcode-plugins/ 简介 Alcatraz是一个 ...
- ASP.NET MVC使用Bootstrap系列(1)——开始使用Bootstrap
阅读目录 Bootstrap结构介绍 在ASP.NET MVC 项目中添加Bootstrap文件 为网站创建Layout布局页 使用捆绑打包和压缩来提升网站性能 在Bootstrap项目中使用捆绑打包 ...
- 脱离 Spring 实现复杂嵌套事务,之一(必要的概念)
事务传播行为种类 Spring在TransactionDefinition接口中规定了7种类型的事务传播行为, 它们规定了事务方法和事务方法发生嵌套调用时事务如何进行传播: 表1事务传播行为类型 事务 ...
- Linux服务器管理: 系统的定时任务crond
cornd 是定时任务的守护进程 这个服务系统是默认启动的 [root@localhost/]#/etc/init.d/crond strat|restart|stop [root@localhos ...
- Spring与Quartz的整合实现定时任务调度(转)
源:http://kevin19900306.iteye.com/blog/1397744 最近在研究Spring中的定时任务功能,最好的办法当然是使用Quartz来实现.对于一个新手来说,花了我不少 ...