本文仅提供TheMVP框架代码(废话少说上代码):
model层其实就是存放我们需要的实体类。及其他数据。本文测试未使用,所以就没有写。
基本框架模型:

1.建包View
1.1view包下创建接口 IDelegate 定出规范:
package com.example.dw.dw20181121moni.view;
import android.content.Context;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public interface IDelegate {
//初始化方法
void initData();
//获取布局
void create(LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle);
//获取视图
View getRootView();
//获取上下文
void getContext(Context context);
}
1.2 view包下创建抽象类 AppDelegate 实现接口 IDeltegate
initData和getContext在这里无用,我把这两个方法此类里删除掉了。另外可以在这里写两个方法,一个get()我是用来获取控件ID,一个setClick()我用来设置点击事件,这样在我的子presenter层只需要get(R.id.xxx);就可以获取的我的控件,而点击事件就更简单了,我只需要setClick(this.R.id.xxx);就可以设置我的点击事件。
我们要在这里拿到我们的layout,但是目前并不存在,所以定义一个抽象方法(getLayoutId()),在我们子persenter继承我们的AppDelete的时候,将对应的layout传过来。这个类只需要以下代码这些操作便完成了(你完全可以在这个类定义任何你觉得可以简化代码的方法,比如Toast)
package com.example.dw.dw20181121moni.view;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
public abstract class AppDelegate implements IDelegate {
private View rootView;
//获取布局
@Override
public void create(LayoutInflater inflater, ViewGroup viewGroup, Bundle bundle) {
rootView = inflater.inflate(getLayoutId(), viewGroup, false);
}
protected abstract int getLayoutId();
//获取视图
@Override
public View getRootView() {
return rootView;
}
//获取控件
SparseArray<View> views = new SparseArray<>();
public <T extends View> T get(int id){
View view = views.get(id);
if (view == null){
view = rootView.findViewById(id);
views.put(id,view);
}
return (T) view;
}
//点击方法
public void setClick(View.OnClickListener listener,int...ids){
if (ids == null){
return;
}
for(int id:ids){
get(id).setOnClickListener(listener);
}
}
}
2.创建presenter包
2.1 presenter包下创建BaseActivityPresenter作为Activity的基类,每一个Activity都对应一个子presenter
这里的 protected T presenter;没有使用private声明,因为某些情况下我们的presenter需要用到Activity(Fragment)的生命周期来进行某些操作,但是我们的子presenter继承的是AppDelegate无法调用生命周期,所以我们可以从Activity(Fragment)中调用生命周期,并在其中创建方法通过presneter.xX();达到我们的目的。
注意:getContext()方法是要在initData()之前调用,否则一些使用context的方法会找不到context。
package com.example.dw.dw20181121moni.presenter;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import com.example.dw.dw20181121moni.view.IDelegate;
public abstract class BaseActivityPresenter<T extends IDelegate> extends AppCompatActivity {
protected T presenter;
//每一个Activity都对应一个Presenter
public abstract Class<T> getPresenter();
public BaseActivityPresenter(){
try {
presenter = getPresenter().newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//创建布局
presenter.create(getLayoutInflater(),null,savedInstanceState);
//创建视图
setContentView(presenter.getRootView());
//获取context
presenter.getContext(this);
//初始化方法
presenter.initData();
}
}
2.2 presenter包下创建BaseFragmentPresenter,做为Fragment的基类
具体操作与BaseActivity相差不多,不多解释
package com.example.dw.dw20181121moni.presenter;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.example.dw.dw20181121moni.view.IDelegate;
public abstract class BaseFragmentPresenter<T extends IDelegate> extends Fragment {
protected T presenter;
//每一个Fragment都对应一个Presenter
public abstract Class<T> getPresenter();
public BaseFragmentPresenter(){
try {
presenter = getPresenter().newInstance();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (java.lang.InstantiationException e) {
e.printStackTrace();
}
}
@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
//创建布局
presenter.create(inflater,container,savedInstanceState);
//返回视图
return presenter.getRootView();
}
@Override
public void onActivityCreated(@Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
//获取context
presenter.getContext(getContext());
//初始化方法
presenter.initData();
}
}
3. 使用测试,很简单的几步,TheMVP的框架就已经搭好了。
接下来使用测试一下
3.1在presenter包下创建MainActivity对应的presneter, MainActivitypresenter继承AppDelegate处理所有逻辑
package com.example.dw.dw20181121moni.presenter;
import android.content.Context;
import com.example.dw.dw20181121moni.R;
import com.example.dw.dw20181121moni.view.AppDelegate;
public class MainActivityPresenter extends AppDelegate {
private Context context;
//返回视图
@Override
protected int getLayoutId() {
return R.layout.activity_main;
}
//初始化方法
@Override
public void initData() {
}
//获取context
@Override
public void getContext(Context context) {
this.context = context;
}
}
3.2 MainActivity不再继承AppCompatActivity而是继承我们的BaseActivityPresenter,实现抽象方法getPresenter(),返回我们Activity对应的一个MainActivityPresenter.
package com.example.dw.dw20181121moni.activity;
import com.example.dw.dw20181121moni.presenter.BaseActivityPresenter;
import com.example.dw.dw20181121moni.presenter.MainActivityPresenter;
public class MainActivity extends BaseActivityPresenter<MainActivityPresenter> {
@Override
public Class getPresenter() {
//返回对应的presenter
return MainActivityPresenter.class;
}
}
3.3简单在activity_main xml下写两个控件用来测试我们的框架
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".activity.MainActivity">
<TextView
android:id="@+id/main_TextView"
android:textSize="20sp"
android:text="测试"
android:layout_width="wrap_content"
android:layout_height="match_parent" />
<Button
android:id="@+id/main_Button"
android:text="点击改变TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</RelativeLayout>
3.4在MainActivityPresenter中的initData()中,
通过get()方法找到main_TextView,
并且通过setClick()给main_Button设置点击事件.测试成功后,我们的框架就没有问题了。
没有最好的只有最合适的,选择最适合自己的,适合自己项目的框架才是王道!
package com.example.dw.dw20181121moni.presenter;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import com.example.dw.dw20181121moni.R;
import com.example.dw.dw20181121moni.view.AppDelegate;
public class MainActivityPresenter extends AppDelegate implements View.OnClickListener {
private Context context;
private TextView main_textView;
//返回视图
@Override
protected int getLayoutId() {
return R.layout.activity_main;
}
//初始化方法
@Override
public void initData() {
main_textView = get(R.id.main_TextView);
setClick(this,R.id.main_Button);
}
//获取context
@Override
public void getContext(Context context) {
this.context = context;
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.main_Button:
main_textView.setText("测试成功");
break;
}
}
}
|