android学习笔记-MVP实例

        最近在疯狂学习mvp架构,看了一堆博文也没整明白,最后还是谷歌的官方案例给整明白了,遂整理记录,有错误的地方,还请大神们指教。

        mvp基本结构如图,view持有presenter,presenter持有view和model,presenter通过持有的model存取数据,通过持有的view获取view中的数据,或改变view的ui显示。可以看到view中有个set方法,主要是方便外部注入presenter实例,这里是通过presenter中持有的view来调用setpresenter()将presenter自己的实例注入到view中去,至于原因请看这里。最后实现了view和model的解耦,所有的业务逻辑都放在presenter内操作,和view解耦,view只负责ui的展示。

        这里以简单的login界面距离介绍。为了简介起见,所有的layout和jdbc相关的操作都不作具体展示。首先是java文件,如下:

首先定义三个接口,代表mvp三个模块,然后用一个contract接口来管理,之后是三个实现类,这里fragment对应的是view,而activity只用来做一些初始化操作。最后需要一个user的pojo,便于从数据库存取数据。具体代码如下:

1、User

public class User {

    private Integer id;
    private String name;
    private String password;

    public User(Integer id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    public User(){}

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

没啥好说,属性对应的数据库列属性,其他方法都自动生成

2、Base

public interface BaseModel<T> {

    T loadModel(Context context, String name);

    void saveModel(T model);

}

public interface BasePresenter {

    void start() throws ExecutionException, InterruptedException;

}

public interface BaseView<T> {

    void setPresenter(T presenter);

}

最顶级抽象

3、contract

public interface LoginContract {

    interface View extends BaseView<Presenter> {

        void setProgressIndicator(boolean active);

        String getName();

        String getPassword();

        void setName(String name);

        void setPassword(String psw);

        void showToast(String text);

    }

    interface Presenter extends BasePresenter{

    }

}

扩展了一些方法,用contract管理

4、activity

public class LoginActivity extends BaseActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        LoginFragment loginFragment = new LoginFragment();
        ActivityUtil.addFragmentToActivity(getSupportFragmentManager(),loginFragment,R.id.loginfrm);

        //初始化整个mvp架构
        new LoginPresenter(loginFragment,new LoginModel(),this);
    }
}

只做初始化,绑定fragmnet

5、view

public class LoginFragment extends Fragment implements LoginContract.View{

    // TODO: Rename parameter arguments, choose names that match
    // the fragment initialization parameters, e.g. ARG_ITEM_NUMBER
    private static final String ARG_PARAM1 = "param1";
    private static final String ARG_PARAM2 = "param2";

    private LoginContract.Presenter mPresenter;
    private EditText nameEdit;
    private EditText pswEdit;
    private Button loginButton;

    // TODO: Rename and change types of parameters
    private String mParam1;
    private String mParam2;

    public LoginFragment() {
        // Required empty public constructor
    }

    /**
     * Use this factory method to create a new instance of
     * this fragment using the provided parameters.
     *
     * @param param1 Parameter 1.
     * @param param2 Parameter 2.
     * @return A new instance of fragment LoginFragment.
     */
    // TODO: Rename and change types and number of parameters
    public static LoginFragment newInstance(String param1, String param2) {
        LoginFragment fragment = new LoginFragment();
        Bundle args = new Bundle();
        args.putString(ARG_PARAM1, param1);
        args.putString(ARG_PARAM2, param2);
        fragment.setArguments(args);
        return fragment;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if (getArguments() != null) {
            mParam1 = getArguments().getString(ARG_PARAM1);
            mParam2 = getArguments().getString(ARG_PARAM2);
        }
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        View root = inflater.inflate(R.layout.fragment_login, container, false);
        nameEdit = root.findViewById(R.id.name);
        pswEdit = root.findViewById(R.id.psw);
        loginButton = root.findViewById(R.id.bt_login);
        loginButton.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View v){
                try {
                    mPresenter.start();
                } catch (ExecutionException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        return root;
    }

    @Override
    public void setProgressIndicator(boolean active) {

    }

    @Override
    public String getName() {
        return nameEdit.getText().toString();
    }

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

    @Override
    public void setName(String name) {

    }

    @Override
    public void setPassword(String psw) {

    }

    @Override
    public void setPresenter(LoginContract.Presenter presenter) {
        this.mPresenter = presenter;
    }

    public void showToast(String text){
        Toast.makeText(getActivity(), text, Toast.LENGTH_SHORT).show();
    }
}

没用到的方法先不管,两个edittext,一个button,两个get方法方便presenter取数据,一个showToast方法显示状态,按下button启动presenter

6、model

public class LoginModel implements BaseModel {

    private User mUser;

    private SharedPreferences mPrefs;

    private Query mQuery;

    LoginModel(){
        mUser = new User();
        mQuery = QueryFactory.createMysqlQuery();
    }

    @Override
    public User loadModel(Context context, String name) {
        //根据用户名返回user对象
        List list = mQuery.queryRows(context,"select * from user where name=?",User.class,new Object[]{name});
        if(list.size()==0){
            return new User();
        }
        return (User)list .get(0);
    }

    @Override
    public void saveModel(Object model) {
        mQuery.insert(model);
    }
}

同样没用到的属性和方法先不管,关键是一个query对象,主要是管理jdbc操作数据库的,然后根据username查找并返回给presenter

7、presenter

public class LoginPresenter implements LoginContract.Presenter{

    private LoginContract.View mView;

    private LoginModel mModel;

    private Context mContext;

    public LoginPresenter(LoginContract.View loginView,LoginModel loginModel,Context context){
        mView = loginView;
        mModel = loginModel;
        mContext = context;
        loginView.setPresenter(this);
    }

    @Override
    public void start() throws ExecutionException, InterruptedException {
        User remoteUser = new User();
        Thread loadThread = new Thread(new Runnable(){
            @Override
            public void run() {
                User user = mModel.loadModel(mContext,mView.getName());
                remoteUser.setId(user.getId());
                remoteUser.setName(user.getName());
                remoteUser.setPassword(user.getPassword());
            }
        });
        loadThread.start();
        loadThread.join();
        User typeUser = new User();
        typeUser.setName(mView.getName());
        typeUser.setPassword(mView.getPassword());
        int state = checkValid(typeUser,remoteUser);
        switch (state){
            case 0:
                mView.showToast("登录成功!");
                break;
            case 1:
                mView.showToast("用户名不存在!");
                break;
            case 2:
                mView.showToast("密码错误!");
                break;
            case 3:
                mView.showToast("请输入用户名!");
                break;
            case 4:
                mView.showToast("请输入密码!");
                break;
        }
    }

    private int checkValid(User typeUser,User remoteUser){
        String typeName = typeUser.getName();
        String typePSW = typeUser.getPassword();
        String remoteName = remoteUser.getName();
        String remotePsw = remoteUser.getPassword();
        if(typeName.equals("")){
            return 3;
        }
        if(typePSW.equals("")){
            return 4;
        }
        if(remoteName==null){
            return 1;
        }
        if(remotePsw!=null&&!typePSW.equals(remotePsw)){
            return 2;
        }
        return 0;
    }
}

presenter分别从view和model两边接收两个user对象,并作比较,从而显示登录状态提示

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值