课题

  1. 程序界面由3个文本编辑框和1个文本标签组成。
  2. 要求文本标签实时显示3个文本编辑框所输入的数字之和。
  3. 文本编辑框输入的不是合法数字时,将其值视为0。
  4. 3个文本编辑框的初值分别为1,2,3。

创建工程

打开 Android Studio,File / New / Project...

在 New Project 向导的第1页,Application Name 填上 RxExample,选 Include Kotlin support。

在向导的第4页点击 Finish 按钮创建工程

build.gradle 内容如下

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
compileSdkVersion 28
defaultConfig {
applicationId "com.zwstudio.rxexample"
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
} dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation"org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0-rc01'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

在 android 部分加上 buildToolsVersion

android {
compileSdkVersion 28
buildToolsVersion '28.0.2'
// ...
}

在 dependencies 部分加上对4个包的引用

RxAndroid, RxJava, RxKotlin, RxBinding

dependencies {
// ...
implementation 'io.reactivex.rxjava2:rxandroid:2.0.2'
implementation 'io.reactivex.rxjava2:rxjava:2.1.16'
implementation 'io.reactivex.rxjava2:rxkotlin:2.2.0'
implementation 'com.jakewharton.rxbinding2:rxbinding-kotlin:2.1.1'
}

配置 UI

打开 activity_main.xml

将以下"Hello World!"部分

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

改为

<GridLayout
android:layout_width="120dp"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent"
android:rowCount="5"
android:columnCount="2"
> <EditText
android:id="@+id/etNumber1"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:gravity="end"
android:layout_row="0"
android:layout_column="1"
android:inputType="number"
android:hint="0"
android:text="1" /> <EditText
android:id="@+id/etNumber2"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:gravity="end"
android:layout_row="1"
android:layout_column="1"
android:inputType="number"
android:hint="0"
android:text="2" /> <TextView
android:id="@+id/tvAdd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_row="2"
android:layout_column="0"
android:gravity="end"
android:text="+"
android:textAppearance="@style/TextAppearance.AppCompat.Large" /> <EditText
android:id="@+id/etNumber3"
android:layout_width="80dp"
android:layout_height="wrap_content"
android:layout_row="2"
android:layout_column="1"
android:gravity="end"
android:inputType="number"
android:hint="0"
android:text="3" /> <TextView
android:id="@+id/tvResult"
android:layout_row="3"
android:layout_column="1"
android:layout_width="76dp"
android:gravity="end"
android:textAppearance="@style/TextAppearance.AppCompat.Medium"
android:text="16" />
</GridLayout>

控件变量

在 MainActivity 类中的 onCreate 方法中添加以下代码

val etNumber1 = findViewById<EditText>(R.id.etNumber1)
val etNumber2 = findViewById<EditText>(R.id.etNumber2)
val etNumber3 = findViewById<EditText>(R.id.etNumber3)
val tvResult = findViewById<TextView>(R.id.tvResult)

不使用 RxJava 的传统解决方案

在 MainActivity 类中的 onCreate 方法中添加以下代码

val textWatcher = object : TextWatcher {
override fun afterTextChanged(s: Editable?) {
} override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
} override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
val num1 = etNumber1.text.toString().toIntOrNull() ?: 0
val num2 = etNumber2.text.toString().toIntOrNull() ?: 0
val num3 = etNumber3.text.toString().toIntOrNull() ?: 0
tvResult.text = (num1 + num2 + num3).toString()
} }
etNumber1.addTextChangedListener(textWatcher)
etNumber2.addTextChangedListener(textWatcher)
etNumber3.addTextChangedListener(textWatcher)
etNumber1.text = etNumber1.text

使用 RxJava 的解决方案

在 MainActivity 类中的 onCreate 方法中添加以下代码

Observables.combineLatest(RxTextView.textChanges(etNumber1), RxTextView.textChanges(etNumber2), RxTextView.textChanges(etNumber3))
{s1, s2, s3 -> ((s1.toString().toIntOrNull() ?: 0) + (s2.toString().toIntOrNull() ?: 0) + (s3.toString().toIntOrNull() ?: 0)).toString()}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(RxTextView.text(tvResult))

ReactiveX 学习笔记(20)使用 RxJava + RxBinding 进行 GUI 编程的更多相关文章

  1. ReactiveX 学习笔记(0)学习资源

    ReactiveX 学习笔记 ReactiveX 学习笔记(1) ReactiveX 学习笔记(2)创建数据流 ReactiveX 学习笔记(3)转换数据流 ReactiveX 学习笔记(4)过滤数据 ...

  2. Ext.Net学习笔记20:Ext.Net FormPanel 复杂用法

    Ext.Net学习笔记20:Ext.Net FormPanel 复杂用法 在上一篇笔记中我们介绍了Ext.Net的简单用法,并创建了一个简单的登录表单.今天我们将看一下如何更好是使用FormPanel ...

  3. SQL反模式学习笔记20 明文密码

    目标:恢复或重置密码 反模式:使用明文存储密码 1.存储密码 使用明文存储密码或者在网络上传递密码是不安全的. 如果攻击者截取到你用来插入(或者修改)密码的sql语句,就可以获得密码.     黑客获 ...

  4. golang学习笔记20 一道考察对并发多协程操作一个共享变量的面试题

    golang学习笔记20 一道考察对并发多协程操作一个共享变量的面试题 下面这个程序运行的能num结果是什么? package main import ( "fmt" " ...

  5. [原创]java WEB学习笔记20:MVC案例完整实践(part 1)---MVC架构分析

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  6. ‎Cocos2d-x 学习笔记(20) ControlButton

    [Cocos2d-x 学习笔记 目录链接] 1. 简介 ControlButton实现了按钮功能,根据触摸的位置和移动的过程可识别9中EventType类型,执行对应的回调函数. 直接继承了Contr ...

  7. 学习笔记(一)--->《Java 8编程官方参考教程(第9版).pdf》:第一章到六章学习笔记

    注:本文声明事项. 本博文整理者:刘军 本博文出自于: <Java8 编程官方参考教程>一书 声明:1:转载请标注出处.本文不得作为商业活动.违者本人不负法律责任.违法者自负一切法律责任. ...

  8. [原创]java WEB学习笔记27:深入理解面向接口编程

    本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...

  9. ReactiveX 学习笔记(12)调度器

    Schedulers, threading and testing 本文的主题为调度器,多线程以及测试. RxJava操作符(六)Utility SubscribeOn / ObserveOn Sub ...

随机推荐

  1. vs2015和Oracle在一起时的Shit问题

    VS2015在连接Oracle时,必须要安装到一个不含有空格的目录中去,否则连接不上Oracle,至于为什么,不知道,鬼知道,日的. 如果你不幸以前安装过VS2015,安装到它的默认的什么“progr ...

  2. gitlab修改默认端口

    部署gitlab的时候,一启动,发现80和8080端口已经被占用,无奈,只得先将监听80端口的nginx和监听8080端口的jenkins停止.这会儿有空,琢磨一下如何修改gitlab的默认端口. 修 ...

  3. winform获取EXE图片

    winform获取EXE图片 using (FileStream fs = new System.IO.FileStream(n, FileMode.OpenOrCreate, FileAccess. ...

  4. es6学习日记1

    1.let和const ES6新增了let命令,用来声明变量,用法类似于var ,但是声明的变量只在let命令所在代码块内有效. 例如: { let a = 10; var b = 1; } a // ...

  5. redis hset hmset过期时间

    hmset m k v > hset m k v (integer) > hget m k "v" > expire m (integer) > ttl m ...

  6. Go并发编程实战 (郝林 著)

    第1章 初识Go语言 1.1 语言特性 1.2 安装和设置 1.3 工程构造 1.3.1 工作区 1.3.2 GOPATH 1.3.3 源码文件 package main import ( " ...

  7. centos 7.5安装docker-CE 18

    1.查看系统版本 cat /etc/centos-release CentOS Linux release 7.5.1804 (Core) uname -r 3.10.0-862.el7.x86_64 ...

  8. MVC Ajax.BeginForm 提交上传图片

    吃水不忘挖井人,如果对你有帮助,请说声谢谢.如果你要转载,请注明出处.谢谢! 异步提交时,出现图片不能上传. 起初我定格在  System.Web.Mvc  中.查询源码时,也是没有问题的.那问题出现 ...

  9. vscode 调试 TypeScript

    安装 typescript 依赖 npm install typescript --save-dev 目录结构: 添加 tsconfig.json 主要是将 sourceMap 设置为true. { ...

  10. springmvc的简单使用以及ssm框架的整合

    Spring web mvc是基于servlet的一个表现层框架 首先创建一个简单的web工程了解它的使用 web.xml的配置 <?xml version="1.0" en ...