Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱
MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina.com

RxJava RxBinding RxView 控件事件 MD

demo地址

GitHub


目录

简介

按需添加相应的依赖:

implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-design:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-leanback-v17:2.1.1'

通过将【-kotlin】附加到依赖项的'artifactId'后,可以获得所有上述库的 Kotlin 扩展方法。例如:

implementation 'com.jakewharton.rxbinding2:rxbinding-kotlin:2.1.1'
implementation 'com.jakewharton.rxbinding2:rxbinding-support-v4-kotlin:2.1.1'

特点

  • 可以对 View 事件使用 RxJava 的各种操作
  • 提供了与 RxJava 一致的回调,使得代码简洁明了。尤其是页面中充斥着大量的监听事件,各种各样的匿名内部类时
  • 几乎支持我们常用的所有控件及事件,每个库还有对应的Kotlin支持库





使用案例

public class RxBindingActivity extends RxFragmentActivity {
private static final String[] ARRAY = {"包青天", "白乾涛", "baiqiantao", "bqt", "RxBinding", "RxView", "1", "2", "3", "4", "5",};
private ImageView iv1, iv2, iv3, iv4, iv5;
private EditText et1, et2, et3;
private Button btn;
private CheckBox cb;
private ListView listView;
private int type; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_rxbinding); iv1 = findViewById(R.id.iv1);
iv2 = findViewById(R.id.iv2);
iv3 = findViewById(R.id.iv3);
iv4 = findViewById(R.id.iv4);
iv5 = findViewById(R.id.iv5);
btn = findViewById(R.id.btn);
et1 = findViewById(R.id.et1);
et2 = findViewById(R.id.et2);
et3 = findViewById(R.id.et3);
cb = findViewById(R.id.cb);
listView = findViewById(R.id.lv);
listView.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, Arrays.asList(ARRAY))); type = getIntent().getIntExtra("type", 0);
log("type=" + type);
switch (type) {
case 0:
event();
break;
case 1:
accept();
break;
case 2:
usefulDemo();
break;
}
} @Override
protected void onResume() {
super.onResume();
if (type == 3) {
bufferDemo();
}
} @SuppressLint("NewApi")
private void event() {
RxView.attaches(iv1).subscribe(o -> log("attach event"));
RxView.attachEvents(iv1).subscribe(viewAttachEvent -> log("attach event"));
RxView.clicks(iv1).subscribe(o -> log("click event")); //setOnClickListener
RxView.detaches(iv1).subscribe(o -> log("detach event"));
RxView.drags(listView).subscribe(dragEvent -> log("drag event:" + dragEvent.getAction())); //setOnDragListener
RxView.draws(listView).subscribe(o -> log("draw event")); // ViewTreeObserver#addOnDrawListener
RxView.focusChanges(iv1).subscribe(hasFocus -> log("focus change event:" + hasFocus)); //setOnFocusChangeListener
RxView.globalLayouts(listView).subscribe(o -> log("global event")); //ViewTreeObserver#addOnGlobalLayoutListener
RxView.hovers(iv1).subscribe(motionEvent -> log("hover event:" + motionEvent.getAction())); //setOnHoverListene,悬停事件
RxView.keys(iv1).subscribe(keyEvent -> log("key event:" + keyEvent.getAction())); //setOnKeyListener
RxView.layoutChanges(listView).subscribe(o -> log("layout event")); //addOnLayoutChangeListener
RxView.layoutChangeEvents(listView).subscribe(viewLayoutChangeEvent -> log("layout event"));//addOnLayoutChangeListener
RxView.longClicks(iv1).subscribe(o -> log("long click event")); //setOnLongClickListener
RxView.scrollChangeEvents(listView).subscribe(viewScrollChangeEvent -> log("scroll event")); //setOnScrollChangeListener
RxView.systemUiVisibilityChanges(listView).subscribe(vii -> log("visible event" + vii)); //setOnSystemUiVisibilityChangeListener
RxView.touches(listView).subscribe(motionEvent -> { //setOnTouchListener
log("touch event:" + motionEvent.getAction());
listView.onTouchEvent(motionEvent);//如果不传给listView,则listView将不能获取到Touch事件,那么listView会出现不能滑动等问题
}); RxAdapterView.itemClicks(listView).subscribe(position -> log("item click event:" + position)); //setOnItemClickListener
RxAdapterView.itemClickEvents(listView).subscribe(adapterViewItemClickEvent -> log("item click event")); //点击
RxAdapterView.itemLongClicks(listView).subscribe(position -> log("item long click event:" + position)); //setOnItemLongClickListener
RxAdapterView.itemLongClickEvents(listView).subscribe(adapterViewItemLongClickEvent -> log("item long click event")); //长点击
RxAdapterView.itemSelections(listView).subscribe(position -> log("item select event:" + position)); //setOnItemSelectedListener
RxAdapterView.selectionEvents(listView).subscribe(adapterViewSelectionEvent -> log("item select event")); //选择 RxAdapter.dataChanges(listView.getAdapter()).subscribe(listAdapter -> log("data change event"));//registerDataSetObserver
RxAbsListView.scrollEvents(listView).subscribe(absListViewScrollEvent -> log("scroll event")); //setOnScrollListener
RxViewGroup.changeEvents(listView).subscribe(viewGroupHierarchyChangeEvent -> log("哈"));//setOnHierarchyChangeListener RxCompoundButton.checkedChanges(cb).subscribe(isChecked -> log("check event:" + isChecked)); //setOnCheckedChangeListener RxTextView.textChanges(et1).subscribe(cs -> log("text change event:" + cs.toString())); //addTextChangedListener
RxTextView.textChangeEvents(et2).subscribe(textViewTextChangeEvent -> log("text change event")); //addTextChangedListener
RxTextView.afterTextChangeEvents(et3).subscribe(textViewAfterTextChangeEvent -> log("aftet text change event"));
RxTextView.beforeTextChangeEvents(et3).subscribe(textViewBeforeTextChangeEvent -> log("before text change event"));
RxTextView.editorActions(et1).subscribe(actionId -> log("editor event:" + actionId)); //setOnEditorActionListener,需要设置inputType
RxTextView.editorActionEvents(et2).subscribe(textViewEditorActionEvent -> log("editor event")); //点击软键盘上的回车键
} private void accept() {
try {
RxView.visibility(iv1).accept(false);//view.setVisibility(value ? View.VISIBLE : View.GONE)
RxView.visibility(iv2, View.GONE).accept(true);//view.setVisibility(value ? View.VISIBLE : visibilityWhenFalse)
RxView.visibility(iv3, View.GONE).accept(false);
RxView.visibility(iv4, View.INVISIBLE).accept(false);
RxView.visibility(iv5, View.INVISIBLE).accept(true); RxAdapterView.selection(listView).accept(1); //view.setSelection(position) RxCompoundButton.checked(cb).accept(true); //view.setChecked(value)
RxCompoundButton.toggle(cb).accept(null); //view.toggle(),切换状态 RxTextView.color(et1).accept(Color.RED); //view.setTextColor(color)
RxTextView.textRes(et1).accept(R.string.app_name); //view.setText(int resId)
RxTextView.hintRes(et2).accept(R.string.app_name); //view.setHint(int resId)
RxTextView.errorRes(et3).accept(R.string.app_name); //view.setError(int resId)
RxTextView.text(et1).accept("text"); //view.setText(String text)
RxTextView.hint(et2).accept("hint"); //view.setHint(String text)
RxTextView.error(et3).accept("error"); //view.setError(String text)
} catch (Exception e) {
e.printStackTrace();
}
} private void usefulDemo() {
RxView.clicks(iv1)
.throttleFirst(2, TimeUnit.SECONDS) //throttleFirst只响应第一次,throttleLast只响应最后一次
.subscribe(o -> log("防抖动")); RxView.clicks(iv2)
.compose(new RxPermissions(this).ensure(Manifest.permission.CAMERA)) //动态获取权限
.subscribe(granted -> log(granted ? "已赋予权限" : "已拒绝权限")); RxTextView.textChanges(et1)
.debounce(500, TimeUnit.MILLISECONDS) //防抖动,控件操作时间间隔,去除发送频率过快的项
.subscribe(charSequence -> log(charSequence.toString())); Observable<CharSequence> observable1 = RxTextView.textChanges(et2).skip(1);
Observable<CharSequence> observable2 = RxTextView.textChanges(et3).skip(1);
Observable.combineLatest(observable1, observable2, //合并监听、表单验证
(phone, password) -> {
log(phone + "_" + password);
return phone.toString().startsWith("1") && password.toString().endsWith("1");
}).subscribe(isValid -> btn.setEnabled(isValid)); RxView.clicks(btn) //发送验证码功能
.doOnNext(o -> btn.setEnabled(false))
.subscribe(o -> Observable.interval(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread())
.take(10)
.compose(bindToLifecycle())
.map(aLong -> 10 - aLong + " 秒后重新获取")
.subscribe(string -> btn.setText(string),
Throwable::printStackTrace,
() -> {
btn.setEnabled(true);
btn.setText("重新获取");
}));
} private void bufferDemo() {
RxView.clicks(iv1)
.buffer(1000, TimeUnit.MILLISECONDS, 5) //效果仅仅是,每隔1秒钟收集一下此1秒钟内的点击次数
.compose(bindUntilEvent(ActivityEvent.STOP))//在 onStop 时取消
.subscribe(list -> Log.i("【bqt】", "iv1一秒钟内的点击次数:" + list.size())); RxView.clicks(iv2)
.map(obj -> 1) //和上面的情况基本一致
.buffer(1000, TimeUnit.MILLISECONDS)
.compose(bindUntilEvent(ActivityEvent.STOP))
.subscribe(list -> Log.i("【bqt】", "iv2一秒钟内的点击次数:" + list.size())); //这种效果可能不是你想要的效果,你想要的效果可能是:在1秒钟内点击次数为多少次就是几次连击
Observable<Object> observable = RxView.clicks(iv3).share();
observable.buffer(observable.debounce(200, TimeUnit.MILLISECONDS).compose(bindUntilEvent(ActivityEvent.STOP)))
.subscribe(list -> Log.i("【bqt】", "iv3连续点击次数:" + list.size()));//这里的时间指的是任意两次点击最长间隔时间);
} private void log(String s) {
Log.i("【bqt】", s);
}
}

布局

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv1"
android:layout_width="50dp"
android:layout_height="match_parent"
android:src="@drawable/icon"/>
<ImageView
android:id="@+id/iv2"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:background="#f00"/>
<ImageView
android:id="@+id/iv3"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:background="#0f0"/>
<ImageView
android:id="@+id/iv4"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:background="#00f"/>
<ImageView
android:id="@+id/iv5"
android:layout_width="50dp"
android:layout_height="match_parent"
android:layout_marginLeft="20dp"
android:background="#000"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<EditText
android:id="@+id/et1"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:hint="et1"
android:inputType="text"/>
<EditText
android:id="@+id/et2"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:hint="et2"
android:imeOptions="actionDone"
android:inputType="phone"/>
<EditText
android:id="@+id/et3"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:hint="et3"
android:imeOptions="actionSearch"
android:inputType="textPassword"/>
</LinearLayout>
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="点击获取验证码"
android:textSize="12sp"/>
<CheckBox
android:id="@+id/cb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#300f"
android:checked="true"
android:text="已阅读并同意用户协议"/>
<ListView
android:id="@+id/lv"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</LinearLayout>

2018-9-15

RxJava RxBinding RxView 控件事件 MD的更多相关文章

  1. (转)客户端触发Asp.net中服务端控件事件

    第一章. Asp.net中服务端控件事件是如何触发的 Asp.net 中在客户端触发服务端事件分为两种情况: 一. WebControls中的Button 和HtmlControls中的Type为su ...

  2. MFC 设置控件事件对应的函数

    在项目中,右击你想设置的控件,打开属性. 然后找到:控件事件,如果在Visual Studio 2015中操作,显示如图: 然后,以设定单击事件为例: 点击右边的三角,选择 <Edit Code ...

  3. Python pyQt4/pyQt5 学习笔记1(空白窗口,按钮,控件事件,控件提示,窗体显示到屏幕中间,messagebox)

    PyQt4是用来编写有图形界面程序(GUI applications)的一个工具包.PyQt4作为一个Python模块来使用,它有440个类和超过6000种函数和方法.同时它也是一个可以在几乎所有主流 ...

  4. JQuery 点击子控件事件,不会触发父控件的事件

     $('.order-delete').on('tap', function (e) {                  console.log('删除1');                  c ...

  5. Android开发之解决父控件拦截子控件事件问题

    以ViewPager为例: public class TopNewsViewPager extends ViewPager { public TopNewsViewPager(Context cont ...

  6. .net控件事件中的Sender

    private void button2_Click(object sender, RoutedEventArgs e) { } 最近看WPF内容,回顾下.net大家天天都在用,却不是十分关注的一个对 ...

  7. ASP.NET用户控件事件的定义和实践

    假定用户控件(UserControl.ascx)中包含按钮控件  AButton,希望实现按  Button  按钮时,包含该用户控件的页面可以接收到事件. UserControl.ascx.cs   ...

  8. webbrowser控件事件

    Beforenavigate2: Fired before navigate occurs in the given WebBrowser(window or frameset element). T ...

  9. 转:HTML 5 控件事件属性

    Window 事件属性 window 对象触发的事件. 适用于 <body> 标签: 属性 值 描述 onafterprint script 在打印文档之后运行脚本 onbeforepri ...

随机推荐

  1. BEM

    BEM代表块(Block),元素(Element),修饰符(Modifier).BEM是由Yandex团队提出的一种CSS Class 命名方法,旨在更好的创建CSS/Sass模块.通过增加前缀的办法 ...

  2. List,Set的区别

    1.List,Set都是继承自Collection接口2.List特点:元素有放入顺序,元素可重复 ,Set特点:元素无放入顺序,元素不可重复(注意:元素虽然无放入顺序,但是元素在set中的位置是有该 ...

  3. BZOJ.4514.[SDOI2016]数字配对(费用流SPFA 二分图)

    BZOJ 洛谷 \(Solution\) 很显然的建二分图后跑最大费用流,但有个问题是一个数是只能用一次的,这样二分图两部分都有这个数. 那么就用两倍的.如果\(i\)可以向\(j'\)连边,\(j\ ...

  4. hdu 1073 字符串处理

    题意:给一系列的输出和标准答案,比较二者是AC,PE或WA 字符串处理还是比较薄弱,目前没什么时间搞字符串专题,所以遇到一题就努力搞懂 #include<cstdio> #include& ...

  5. SGU 104. Little shop of flowers (DP)

    104. Little shop of flowers time limit per test: 0.25 sec. memory limit per test: 4096 KB PROBLEM Yo ...

  6. Webpack 性能优化 (一)(使用别名做重定向)

    前言 Webpack 是 OneAPM 前端技术栈中非常重要的一部分.它非常好用,假设你还不了解它,建议你阅读这篇Webpack 入门指迷,在 OneAPM 我们用它完毕静态资源打包.ES6 代码的转 ...

  7. WinForm基于插件开发实现多项配置存储

    一.课程介绍和实例在线演示 明人不说暗话,跟着阿笨一起玩WinForm.本次分享课程属于<C#高级编程实战技能开发宝典课程系列>中的一部分,阿笨后续会计划将实际项目中的一些比较实用的关于C ...

  8. vs2012\vs2013\vs2015碰到生成时报该错误:项目中不存在目标“GatherAllFilesToPublish”

    手头一个vs2010升级到vs2012后,web项目发布到本地目录时项目报错:“该项目中不存在目标“GatherAllFilesToPublish”” 通过谷歌大神的帮助,找到了解决方法.共享之. 原 ...

  9. 在ASP.NET MVC中使用jQuery的Load方法加载静态页面的一个注意点

    使用使用jQuery的Load方法可以加载静态页面,本篇就在ASP.NET MVC下实现. Model先行: public class Article { public int Id { get; s ...

  10. Spring Boot 2.0 + zipkin 分布式跟踪系统快速入门

    原文:https://www.jianshu.com/p/9bfe103418e2 注意 Spring Boot 2.0之后,使用EnableZipkinServer创建自定义的zipkin服务器已经 ...