Android 全新MVVM框架搭建
Linux编程 点击右侧关注,免费入门到精通!
来源丨安卓巴士Android开发者门户
闲话不多少,还是老套路,处理一个登陆的业务。详细的介绍MVVM我就不多说了,网上一大把,毕竟吹水还是我的弱项。
主要实现的功能有两个输入框,一个登陆按钮,两个TextView显示登陆结果。
秀一把我的LoginActivity
@BindLayout(R.layout.activity_login)public class LoginActivity extends BaseActivity<ILoginViewModel, LoginActivityBriefnessor> implements ILoginView { @Override protected ILoginViewModel createViewModel(LoginActivityBriefnessor briefnessor) { return new LoginViewModel(this, briefnessor); }}
是不是超级简洁,点击事件呢?怎么不见了,再看一看ViewModel
public class LoginViewModel extends BaseViewModel<ILoginView, ILoginModel, LoginActivityBriefnessor> implements ILoginViewModel {
public LoginViewModel(ILoginView view, LoginActivityBriefnessor briefnessor) { super(view, briefnessor); }
@Override protected ILoginModel createModel() { return new LoginModel(this); }
@Override public void onLoginClick(String account, String pswd) { if (account.length() < 3) { Toast.makeText(context(), "账号不正确", Toast.LENGTH_SHORT).show(); return; } if (pswd.length() < 3) { Toast.makeText(context(), "密码不正确", Toast.LENGTH_SHORT).show(); return; } model.login(account, pswd); }
@Override public void callbackLogin(LoginResult result) { briefnessor.setResult(result); }}
ViewModel制作了登陆的数据验证,以及登陆回调的实现,model层完成模拟了登陆。
整个登陆的业务流程Activity并没有参与,在这其中就不得不提一个关键的中间件Briefness,它连接了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" app:imports="com.hacknife.demo.bean.LoginResult,result"a app:viewModel="com.hacknife.demo.mvvm.viewmodel.ILoginViewModel" tools:ignore="MissingPrefix">
<EditText android:id="@+id/et_account" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="40dp" android:layout_marginVertical="10dp" android:hint="账号" />
<EditText android:id="@+id/et_pswd" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginHorizontal="40dp" android:layout_marginVertical="10dp" android:hint="密码" />
<Button android:id="@+id/btn_login" android:layout_width="match_parent" android:layout_height="40dp" android:layout_marginHorizontal="40dp" android:layout_marginVertical="10dp" android:text="登陆" app:transfer="onLoginClick($et_account$,$et_pswd$)" />
<LinearLayout style="@style/text_parent" android:layout_marginHorizontal="40dp">
<TextView style="@style/text_childer" android:text="返回码" />
<TextView android:id="@+id/tv_code" android:layout_width="wrap_content" android:layout_height="wrap_content" app:bind="$result.code$" /> </LinearLayout>
<LinearLayout style="@style/text_parent" android:layout_marginHorizontal="40dp">
<TextView style="@style/text_childer" android:text="结果:" />
<TextView android:id="@+id/tv_msg" android:layout_width="wrap_content" android:layout_height="wrap_content" app:bind="$result.msg$" /> </LinearLayout></LinearLayout>
布局中,根布局绑定了ViewModel,以及用于展示登陆结果的数据源。登陆按钮传递单击登陆事件,剩下的两个textView绑定相应的字段。
同时在对应的Activity上绑定相应的布局文件,Briefness就能暂时他强大的功能了,它会自动生成[类名+Briefnessor]的类。
public class LoginActivityBriefnessor implements Briefnessor<LoginActivity> { public EditText et_account; public EditText et_pswd; public Button btn_login; public TextView tv_code; public TextView tv_msg; public LoginResult result; public ILoginViewModel viewModel;
@Override public void bind(final LoginActivity host, Object source) { if (!Utils.contentViewExist(host)) { host.setContentView(R.layout.activity_login); } et_account = (EditText) host.findViewById(R.id.et_account); et_pswd = (EditText) host.findViewById(R.id.et_pswd); btn_login = (Button) host.findViewById(R.id.btn_login); tv_code = (TextView) host.findViewById(R.id.tv_code); tv_msg = (TextView) host.findViewById(R.id.tv_msg); btn_login.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { viewModel.onLoginClick(et_account.getText().toString().trim() , et_pswd.getText().toString().trim()); } });
}
@Override public void clear() { this.result = null; this.viewModel = null; }
@Override public void clearAll() { this.result = null; this.viewModel = null; this.et_account = null; this.et_pswd = null; this.btn_login = null; this.tv_code = null; this.tv_msg = null; } @Override public void bindViewModel(Object viewModel) { this.viewModel = (ILoginViewModel) viewModel; } public void setResult(LoginResult result) { if (result == null) return; this.result = result; BriefnessInjector.injector(tv_code,result.getCode()); BriefnessInjector.injector(tv_msg,result.getMsg()); }}
该类实现了数据绑定,以及向ViewModel发送消息附带输入框中的值。
Briefness的具体用法,请参考
https://github.com/hacknife/briefness
下面说一说BaseActivity
public abstract class BaseActivity<T extends IBaseViewModel,B extends Briefnessor> extends AppCompatActivity implements IBaseView { protected T viewModel; protected B briefnessor;
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); briefnessor = (B )Briefness.bind(this); viewModel = createViewModel(briefnessor); briefnessor.bindViewModel(viewModel); initView(); }
protected abstract T createViewModel(B briefnessor);
@Override protected void onDestroy() { super.onDestroy(); if (viewModel != null) viewModel.dettachView(); }
protected void initView() { }
@Override public Context applicationContext() { return getApplication(); }
@Override public Activity context() { return this; }}
BaseActivity中初始化了Briefness并创建ViewModel绑定到Briefness,并实现了IBaseView
public interface IBaseView {
Context applicationContext();
Activity context();}
BaseViewModel继承AbsViewmodel并实现IBaseViewModel,持有Briefnessor,View,Model。
public abstract class BaseViewModel<V extends IBaseView, M extends IBaseModel, B extends Briefnessor> extends AbsViewModel<V> implements IBaseViewModel {
protected V view; protected M model; protected B briefnessor;
public BaseViewModel(V view, B briefnessor) { this.attachView(view); this.attachBriefnessor(briefnessor); this.view = getView(); this.briefnessor = (B) getBriefnessor(); model = createModel(); }
protected abstract M createModel();
@Override public Context applicationContext() { return view.applicationContext(); }
@Override public Activity context() { return view.context(); }}
AbsViewModel 的作用主要是释放相应的连接关系。
public abstract class AbsViewModel<T> implements IBaseViewModel{ protected WeakReference<T> mViewRef; protected WeakReference<Briefnessor> mBriefnessorRef;
protected void attachView(T view) { mViewRef = new WeakReference<T>(view); }
protected void attachBriefnessor(Briefnessor briefnessor) { mBriefnessorRef = new WeakReference<Briefnessor>(briefnessor); }
protected T getView() { return mViewRef.get(); }
protected Briefnessor getBriefnessor() { return mBriefnessorRef.get(); }
public boolean isViewAttached() { return mViewRef != null && mViewRef.get() != null & mBriefnessorRef != null & mBriefnessorRef.get() != null; }
public void dettachView() { if (mViewRef != null) { mViewRef.clear(); mViewRef = null; } if (mBriefnessorRef != null) { mBriefnessorRef.clear(); mBriefnessorRef = null; } }}
BaseModel 持有ViewModel,并实现了IBaseView。
public abstract class BaseModel<VM extends IBaseViewModel> implements IBaseModel { protected VM viewModel;
public BaseModel(VM viewModel) { this.viewModel = viewModel; }
@Override public Context applicationContext() { return viewModel.applicationContext(); }
@Override public Activity context() { return viewModel.context(); }}
写的不好,请多多见谅,毕竟小学都没毕业
如果还有什么不明白的,代码直通车
https://github.com/hacknife/Briefness/tree/master/example/src/main/java/com/hacknife/demo/mvvm
推荐↓↓↓
长
按
关
注
?【16个技术公众号】都在这里!
涵盖:程序员大咖、源码共读、程序员共读、数据结构与算法、黑客技术和网络安全、大数据科技、编程前端、Java、Python、Web编程开发、Android、iOS开发、Linux、数据库研发、幽默程序员等。
万水千山总是情,点个 “ 好看” 行不行
Android 全新MVVM框架搭建相关推荐
- Android MVVM框架搭建(十)Hilt、ViewBinding、Activity Result API
Android MVVM框架搭建(十)Hilt.ViewBinding.Activity Result API 前言 正文 一.依赖 二.Hilt使用 1. Hilt 应用类 2. ViewModel ...
- Android MVVM框架搭建(八)高德地图定位、天气查询、BottomSheetDialog
Android MVVM框架搭建(八)高德地图定位.天气查询.BottomSheetDialog 前言 正文 一.集成SDK 二.基础配置 ① 权限配置 ② 配置Key 三.显示地图 ① MapFra ...
- Android MVVM框架搭建(三)MMKV + Room + RxJava2
Android MVVM框架搭建(三)MMKV + Room + RxJava2 前言 正文 一.添加依赖 二.MMKV 1. 初始化 2. 数据存取 3. 使用 三.Room 1. @Entity ...
- Android MVVM框架搭建(二)OKHttp + Retrofit + RxJava
Android MVVM框架搭建(二)Retrofit + RxJava 前言 正文 一.引入依赖 二.工具类 三.构建网络框架 1. Base 2. 异常处理 3. 拦截器 4. 网络请求服务 四. ...
- Android MVVM框架搭建(七)Permission、AlertDialog、拍照和相册选取
Android MVVM框架搭建(七)Permission.AlertDialog.拍照和相册选取 前言 正文 一.数据库升级 二.数据操作 二.自定义Dialog ① DialogViewHelpe ...
- Android MVVM框架搭建(九)TabLayout、ViewPager、城市地图天气切换
Android MVVM框架搭建(九)TabLayout.ViewPager.城市地图切换 前言 正文 一.父Fragment加载子Fragment ① Fragment适配器 ② TabLayout ...
- android mvvm框架搭建_轻松搭建基于JetPack组件的MVVM框架
原文链接:轻松搭建基于JetPack组件的MVVM框架 - 掘金 Brick github gitee 介绍 辅助android开发者搭建基于JetPack组件构建MVVM框架的注解处理框架.通过注解 ...
- Android App软件框架搭建
1. App软件框架搭建 1.0软件基本架构 1.1创建MainActivity并设置布局文件 布局文件如下: <?xml version="1.0" encoding=&q ...
- android 换肤框架搭建及使用 (3 完结篇)
本系列计划3篇: Android 换肤之资源(Resources)加载(一) setContentView() / LayoutInflater源码分析(二) 换肤框架搭建(三) - 本篇 tips: ...
最新文章
- 月薪没到30K的程序员必须要背的面试八股文,我先啃为敬。。。
- python list add_用Python创建List对象类
- 【NLP】NLP 语义匹配:经典前沿方案整理
- 【搜索引擎基础知识1】搜索引擎基本架构
- LeetCode--171--Excel表列序号
- 容器中apscheduler不执行_APScheduler:定时任务框架
- 基于Android的聊天软件,Socket即时通信,实现用户在线聊天
- 软件测试基础课程学习笔记4--测试用例设计方法技巧
- C++复习 auto
- CString,string,char*之间的转换
- mysql 数据恢复 binlog
- YTU OJ 3229: 硬币组合
- Day2 Excel与数据处理之定位条件、选择性粘贴及查找功能
- No virtual method
- Golang FORM相关字段理解
- 怎样在网上赚钱啊,小编告诉你6种赚钱方式!
- 程序员幽默:让你笑到抽搐的自黑段子
- web项目经理手册-【7】项目经理需要铭记在心的话
- CFD冲蚀模拟的一些理论
- 使用ARCHPR进行zip明文攻击
热门文章
- Linux阅码场 - Linux内核月报(2020年08月)
- matlab树莓派usb摄像头,求 问Simulink做树莓派摄像头显示的一些问题
- 洛谷P1055 ISBN 号码 —— JAVA
- 便携式移动打印协议CPCL介绍
- 《我的第一本C++书》迷你书——看图学C++免费下载
- 【MySQL】Python3 MySQL数据库的基本操作
- springCloud-OAuth2 客户端,用户认证源码分析
- java int 保留两位小数_java 保留两位小数的几种方法
- 5G赋能智慧城市白皮书 附下载地址
- 小米手机1999元叫板iPhone