Android-Mvp模式最基础系列

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/DTJ_74/article/details/82797453

MVP 理论知识

在MVP 架构中跟MVC类似的是同样也分为三层。

Activity 和Fragment 视为View层,负责处理 UI。

Presenter 为业务处理层,既能调用UI逻辑,又能请求数据,该层为纯Java类,不涉及任何Android API。

Model 层中包含着具体的数据请求,数据源。

其实道理个个都懂,关键就是代码。

以一个demo 解释:

这个demo 已经充分体现出了mvp模式。

1 Activity 持有Presenter 的引用,当activity 请求数据,做其他操作,或者 设置数据(TextView 设置数据时候,就通过Presenter 进行处理。所以就直接通过Presenter 方法调用。

2Presenter 持有了IUserModel 接口,IUserModel接口的引用,业务逻辑都在这里实现。当业务请求数据时候,就通过Model层进行请求处理。

就如上图mUserModel.load(id); 方法,然后就通过Activity 实现Model进行交互了。


public class UserActivity extends Activity implements OnClickListener,
		IUserView {

	private EditText mFirstNameEditText, mLastNameEditText, mIdEditText;
	private Button mSaveButton, mLoadButton;
	private UserPresenter mUserPresenter;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		findWidgets();
		mUserPresenter = new UserPresenter(this);
		mSaveButton.setOnClickListener(this);
		mLoadButton.setOnClickListener(this);

	}

	@Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
		switch (v.getId()) {
		case R.id.saveButton:
			mUserPresenter.saveUser(getID(), getFristName(),
					getLastName());
			break;
		case R.id.loadButton:
			mUserPresenter.loadUser(getID());
			break;
		default:
			break;
		}
	}

	@Override
	public void setFirstName(String firstName) {
		// TODO Auto-generated method stub
		mFirstNameEditText.setText(firstName);
	}

	@Override
	public void setLastName(String lastName) {
		// TODO Auto-generated method stub
		mLastNameEditText.setText(lastName);
	}

	@Override
	public int getID() {
		// TODO Auto-generated method stub
		return Integer.parseInt(mIdEditText.getText().toString());
	}

	@Override
	public String getFristName() {
		// TODO Auto-generated method stub
		return mFirstNameEditText.getText().toString();
	}

	@Override
	public String getLastName() {
		// TODO Auto-generated method stub
		return mLastNameEditText.getText().toString();
	}

	void findWidgets() {
		mFirstNameEditText = (EditText) findViewById(R.id.first_name_edt);
		mLastNameEditText = (EditText) findViewById(R.id.last_name_edt);
		mIdEditText = (EditText) findViewById(R.id.id_edt);

		mSaveButton = (Button) findViewById(R.id.saveButton);
		mLoadButton = (Button) findViewById(R.id.loadButton);
	}
}

这个是最基础的mvp。

public class UserModel implements IUserModel {

	private String mFristName;
	private String mLastName;
	private int mID;
	private SparseArray<UserBean> mUsererArray = new SparseArray<UserBean>();

	@Override
	public void setID(int id) {
		// TODO Auto-generated method stub
		mID = id;
	}

	@Override
	public void setFirstName(String firstName) {
		// TODO Auto-generated method stub
		mFristName = firstName;
	}

	@Override
	public void setLastName(String lastName) {
		// TODO Auto-generated method stub
		mLastName = lastName;
		UserBean UserBean = new UserBean(mFristName, mLastName);
		mUsererArray.append(mID, UserBean);
	}

	@Override
	public UserBean load(int id) {
		// TODO Auto-generated method stub
		mID = id;
		UserBean userBean = mUsererArray.get(mID, new UserBean("not found",
				"not found"));
		return userBean;

	}

}

由于实际项目开发中,遇到的业务可能比较多,那么就要通过抽象类进行封装。

Presenter :其中开发中肯定会有很多个,所以需要抽取封装,也是通过<P> 进行封装。

Activity :既然Presenter 类是有多个,那么就要抽取BaseMvpActivity 里面进行封装了。

从基本上看,presenter 需要绑定要view 和model ,也就是说view层跟model层必须要引用的。

所以可以抽取封装出来。

========================================封装好的代码·===================================

直接上代码。

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <Button
        android:id="@+id/but"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="获得数据" />

    <TextView
        android:id="@+id/msg"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!" />

</LinearLayout>

普通布局文件。

package com.twc.mvpi;

import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.twc.mvpi.base.BaseMvpActivity;
import com.twc.mvpi.presenter.IMainPresenter;
import com.twc.mvpi.view.IMainView;

public class MainActivity extends BaseMvpActivity<IMainView, IMainPresenter> implements IMainView {
    private TextView msgt;
    private Button but;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        but = findViewById(R.id.but);
        msgt = findViewById(R.id.msg);
        but.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                getmPresenter().getIMainMsg("我是请求接口的参数");
            }
        });
    }

    @Override
    protected IMainPresenter createPresenter() {
        return new IMainPresenter();
    }

    @Override
    public void otherMethod() {
        Toast.makeText(this, "我调用了另外的方法", Toast.LENGTH_LONG).show();
    }

    @Override
    public void refreshView(String msg) {
        msgt.setText(msg);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
    }
}

这个是MainActivity 的文件。

流程,用户点击了按钮,需要请求接口。

getmPresenter(): 方法是什么,其实也是一个创建Presenter 的方法,它是封装到BaseMvpActivity 中,

可以直接获取,这样其他activity 只要继承BasePresenter 这个类就可以直接获取了。

package com.twc.mvpi.base;

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;

public abstract class BaseMvpActivity<V extends MvpView, T extends BasePresenter<V>> extends AppCompatActivity {
    private T mPresenter;

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (mPresenter == null) {
            mPresenter = createPresenter();
        }
        if (mPresenter != null && !mPresenter.isViewAttached()) {
            mPresenter.attachView((V) this);
            mPresenter.baseInit(this);
        }
    }

    public T getmPresenter() {
        return mPresenter;
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mPresenter != null) {
            mPresenter.detchView();
        }
    }

    protected abstract T createPresenter();


}

可以见到有个抽象方法,是在子类实现的东西,就是创建子Presenter。

这个demo 用IMainPresenter 继承封装BasePresenter.

package com.twc.mvpi.presenter;

import android.content.Context;

import com.twc.mvpi.base.BasePresenter;
import com.twc.mvpi.model.IModelImp;
import com.twc.mvpi.view.IMainView;

public class IMainPresenter extends BasePresenter<IMainView> implements OnDataListener {
    private IModelImp iModelImp;

    @Override
    public void init(Context context) {
        iModelImp = new IModelImp(this);
    }

    public void getIMainMsg(String but_is_but) {
        iModelImp.getDataFormNet(but_is_but);
    }

    @Override
    public void getData(String msg) {
        getmMvpView().otherMethod();
        getmMvpView().refreshView(msg);
    }
}

之前也是说了BasePresenter 需要绑定 view,跟model 的引用。

所以,在子的presenter 里面需要初始化 model 的引用。也就是Imodel 

package com.twc.mvpi.model;

import com.twc.mvpi.presenter.OnDataListener;

public class IModelImp implements IModelInterface {
    OnDataListener iMainPresenter;

    public IModelImp(OnDataListener iMainPresenter) {
        this.iMainPresenter = iMainPresenter;
    }

    @Override
    public void getDataFormNet(String msg) {
        iMainPresenter.getData(msg + ",我通过参数从网络获取的数据");
    }
}

这里Model 实现了一个回调接口,进行数据回调。

来到这里,在旅一次流程。

1activity --->按钮点击---> 获取 getPresenter()方法 获取对应的mPresenter 的对象,

2获取对象之后 就getIMainMsg()方法,

3然后就用 iModelImp调用getDataFormNet方法。

这里获取数据之后就回调接口,将数据传递给presenter 。

presenter 里面 就通过

getmMvpView().otherMethod();
getmMvpView().refreshView(msg);

通过开头实现的方法getmMvpView()获取

mMvpView 的引用实例IMainView。

就刷新数据,

最后activity里面就获得了数据。进行数据刷新。

总结:

              activity 里面有业务,就通过 方法 写在子presenter 里面,presenter 里面有model 的实现类,model就请求数据

请求回来后通过接口回调到子presenter 里面,子presenter 里面就通过getView 方法调用,view接口方法刷新调用activity。

代码·在这里

猜你喜欢

转载自blog.csdn.net/DTJ_74/article/details/82797453