MVP模式的经典封装

protected abstract void getData();

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

if (null != mPresenter) {
mPresenter.detachView();
}
}
}

BaseActivity设置两个泛型——V和P,明显地,分别代表对应的View和Presenter。

其持有一个BasePresenter,在onCreated方法中,使用createPresenter方法返回对应的BasePresenter的子类,我们就可以使用了。

这里注意一下view和presenter的处理:在onCreated中创建Presenter对象,但其内部的view软引用还是空;在onResume中关联view,此时presenter已经持有view的软引用;当然,还需要在onDestroy中取消关联。

至于其他的封装就不再介绍了,相信大家肯定还有更优的封装方法。

2.2 BaseFragment

public abstract class BaseFragment<V, T extends BasePresenter> extends Fragment {

public String TAG = getClass().getSimpleName() + “”;

private static final String STATE_SAVE_IS_HIDDEN = “STATE_SAVE_IS_HIDDEN”;
protected T mPresenter;

//定义一个View用来保存Fragment创建的时候使用打气筒工具进行的布局获取对象的存储
protected View view;

/**

  • 当Fragment进行创建的时候执行的方法
    */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

mPresenter = createPresenter();//创建presenter

}

@Override
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean(STATE_SAVE_IS_HIDDEN, isHidden());
}

/**

  • 这个方法是关于Fragment完成创建的过程中,进行界面填充的方法,该方法返回的是一个view对象
  • 在这个对象中封装的就是Fragment对应的布局
    */
    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    view = initFragmentView(inflater);
    return view;
    }

/**

  • 这个方法当onCreateView方法中的view创建完成之后,执行
  • 在inflate完成view的创建之后,可以将对应view中的各个控件进行查找findViewById
    */
    @Override
    public void onViewCreated(View view, Bundle savedInstanceState) {
    initFragmentChildView(view);
    }

/**

  • 这个方法是在Fragment完成创建操作之后,进行数据填充操作的时候执行的方法
    */
    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
    super.onActivityCreated(savedInstanceState);
    initFragmentData(savedInstanceState);
    }

/**

  • 完成打气筒操作
    */
    protected abstract View initFragmentView(LayoutInflater inflater);

/**

  • 进行findViewById的操作
  • @param view 打气筒生成的View对象
    */
    protected abstract void initFragmentChildView(View view);

/**

  • 网络数据填充的操作
  • @param savedInstanceState
    */
    protected abstract void initFragmentData(Bundle savedInstanceState);

/**

  • 创建Presenter对象
    */
    protected abstract T createPresenter();

@Override
public void onResume() {
super.onResume();
if (null != mPresenter) {
mPresenter.attachView((V) this);
}
}

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

}

BaseFragment与BaseA类似就不再累赘。

3、Contract契约类

契约,顾名思义,规范定义,定义功能和模板。

在契约类中定义View的接口,Model的接口。因为Model将数据返给Presenter是使用回调方式,所以还需要再契约类中定义对应的回调。

具体看示例吧。

实战

这里我们以登录功能模块为例:

1、契约类

/**

  • Description:
  • Created by jia on 2017/12/20.
  • 人之所以能,是相信能
    */
    public class LoginContract {

public interface LoginView{

void onCheckFormatSuccess();

void onCheckFormatFail(String info);

void onLoginSuccess(Login login);

void onLoginFail(String errorInfo);
}

public interface LoginModel{
void login(String name,String password,LoginCallBack callBack);
}

public interface LoginCallBack{
void onSuccess(Login login);

void onFail(String errorInfo);
}
}

这里定义了登录页面的view接口、model接口和对应的回调。

在view中,只定义与UI展示的相关方法,如检查账号密码格式成功(失败)、登录成功(失败)等。

model负责数据请求,所以在接口中只定义了登录的方法。

回调定义了登录成功还是失败的方法。

2、Model实现类

/**

  • Description: 登录 Model实现类
  • Created by jia on 2017/12/20.
  • 人之所以能,是相信能
    */
    public class LoginModelImpl implements LoginContract.LoginModel {

/**

  • 登录方法
  • @param name
  • @param password
  • @param callBack
    */
    @Override
    public void login(String name, String password, final LoginContract.LoginCallBack callBack) {
    LoginNetUtils.getInstance().login(name, password, new BaseSubscriber() {
    @Override
    public void onSuccess(Login login) {
    callBack.onSuccess(login);
    }

@Override
public void onFail(String info) {
callBack.onFail(info);
}
});
}
}

创建Model实现类,重写其登录方法既可,将登录接口交给回调。

3、Presenter

/**

  • Description: 登录主持类
  • Created by jia on 2017/12/20.
  • 人之所以能,是相信能
    */
    public class LoginPresenter extends BasePresenter<LoginContract.LoginView> {

private LoginModelImpl model;

public LoginPresenter() {
model = new LoginModelImpl();
}

/**

  • 检查格式
  • @param name
  • @param password
    */
    public void checkFormat(String name, String password) {
    if (TextUtils.isEmpty(name)) {
    getView().onCheckFormatFail(“请输入用户名”);
    } else if (TextUtils.isEmpty(password)) {
    getView().onCheckFormatFail(“请输入密码”);
    } else if (password.length() < 6 || password.length() > 18) {
    getView().onCheckFormatFail(“密码格式不正确”);
    } else {
    getView().onCheckFormatSuccess();
    login(name, password);
    }
    }

/**

  • 登录
  • @param name
  • @param password
    */
    public void login(String name, String password) {
    model.login(name, password, new LoginContract.LoginCallBack() {
    @Override
    public void onSuccess(Login login) {
    getView().onLoginSuccess(login);
    }

@Override
public void onFail(String errorInfo) {
getView().onLoginFail(errorInfo);
}
});
}

}

LoginPresenter集成BasePresenter,传入LoginView最为泛型T。

内部持有Model实现类对象。

创建两个方法,一个是检查格式,一个是登录。两个方法就是业务的处理。

如登录方法,登录返回后,在回调中得到数据,也可以再进行一些逻辑判断,将结果交给view的对应的方法。

注意这里使用getView()方法就可以,因为在父类中getView方法直接返回的对应的view实例。

4、View

/**

  • 登录界面
    */
    public class LoginActivity extends BaseActivity<LoginContract.LoginView, LoginPresenter>
    implements LoginContract.LoginView, View.OnClickListener {

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

}

@Override
protected void findViewById() {

}

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

@Override
protected void getData() {
}

@Override
public void onCheckFormatSuccess() {
loading.show();
}

@Override
public void onCheckFormatFail(String info) {
RxToast.error(mContext, info).show();
}

@Override
public void onLoginSuccess(Login login) {

}

@Override
public void onLoginFail(String errorInfo) {

}

@Override
public void onClick(View view) {

}

}
这里的LoginActivity就是登录功能模块的view,其集成BaseActivity,传入view和presenter泛型。
实现LoginView接口,重写接口定义好的UI方法。
在createPresenter方法中创建LoginPresenter对象并返回。这样,就可以使用mPresenter直接操作逻辑了。
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数初中级Android工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则近万的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Android移动开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。

img

img

img

img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Android开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注:Android)

结语

看到这篇文章的人不知道有多少是和我一样的Android程序员。

35岁,这是我们这个行业普遍的失业高发阶段,这种情况下如果还不提升自己的技能,进阶发展,我想,很可能就是本行业的职业生涯的终点了。

我们要有危机意识,切莫等到一切都成定局时才开始追悔莫及。只要有规划的,有系统地学习,进阶提升自己并不难,给自己多充一点电,你才能走的更远。

千里之行始于足下。这是上小学时,那种一元钱一个的日记本上每一页下面都印刷有的一句话,当时只觉得这句话很短,后来渐渐长大才慢慢明白这句话的真正的含义。

有了学习的想法就赶快行动起来吧,不要被其他的事情牵绊住了前行的脚步。不要等到裁员时才开始担忧,不要等到面试前一晚才开始紧张,不要等到35岁甚至更晚才开始想起来要学习要进阶。

给大家一份系统的Android学习进阶资料,希望这份资料可以给大家提供帮助。

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

你才能走的更远。

千里之行始于足下。这是上小学时,那种一元钱一个的日记本上每一页下面都印刷有的一句话,当时只觉得这句话很短,后来渐渐长大才慢慢明白这句话的真正的含义。

有了学习的想法就赶快行动起来吧,不要被其他的事情牵绊住了前行的脚步。不要等到裁员时才开始担忧,不要等到面试前一晚才开始紧张,不要等到35岁甚至更晚才开始想起来要学习要进阶。

给大家一份系统的Android学习进阶资料,希望这份资料可以给大家提供帮助。
[外链图片转存中…(img-MkJOrjt0-1713396658202)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 10
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值