RxJavaAndroid开发

RxJava<第二十四篇>:RxBinding3.0

2019-04-01  本文已影响10人  NoBugException
(1)github

以下是RxBing的github地址:

RxBinding

目前RxBinding已经更新到3.0.0-alpha2了。

(2)依赖

RxBinding2.0.0使用量比较多:

implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0'

RxBinding2.2.0之后废弃了一些组件和接口

implementation 'com.jakewharton.rxbinding2:rxbinding:2.2.0'
图片.png 图片.png

另外RxBinding2.2.0提供了对recyclerview组件的扩展

implementation 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.2.0'
图片.png
图片.png

如果用到recyclerview的话可以选择使用 recyclerview-v7:2.2.0这个依赖。

RxBinding现在已经更新到3.0.0了:

我们可以使用以下依赖

implementation 'com.jakewharton.rxbinding3:rxbinding:3.0.0-alpha2'

同时,在2.0.0的基础上废弃了不少接口。

RxBinding3.0.0加入了对AndroidX的支持

implementation 'com.jakewharton.rxbinding3:rxbinding-core:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-appcompat:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-drawerlayout:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-leanback:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-recyclerview:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-slidingpanelayout:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-swiperefreshlayout:3.0.0-alpha2'
implementation 'com.jakewharton.rxbinding3:rxbinding-viewpager:3.0.0-alpha2'

包括Google 'material' library bindings:

implementation 'com.jakewharton.rxbinding3:rxbinding-material:3.0.0-alpha2'

也需要AndroidX的支持。

随着Android SDK版本的迭代,api28之后将不再更新,将传统项目转成AndoridX刻不容缓,RxBinding对AndroidX的支持以后应该还会继续迭代。

本章将针对

implementation 'com.jakewharton.rxbinding3:rxbinding:3.0.0-alpha2'

这个依赖包进行分析。

还有一点需要说明,如果项目中已经导入了以下依赖包,可以直接删除了,因为RxBinding的依赖包自带rxjava和rxandroid。

implementation 'io.reactivex.rxjava2:rxjava:2.1.3'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
(3)相关组件

RxAbsListViewRxAdapterRxAdapterViewRxAutoCompleteTextViewRxCompoundButtonRxPopupMenuRxRadioGroupRxRatingBarRxSearchViewRxSeekBarRxTextViewRxToolbarRxMenuItemRxViewRxViewGroup

(4)RxView

相当于

    bt_1.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Log.d("aaa", "点击事件");
        }
    });

方法一:

    boolean value = false;
    try {
        RxView.visibility(bt_1).accept(value);
    } catch (Exception e) {
        e.printStackTrace();
    }

相当于

    boolean value = false;
    bt_1.setVisibility(value ? View.VISIBLE : View.GONE);

方法二:

    boolean value = false;
    int visibilityWhenFalse = View.VISIBLE;

    try {
        RxView.visibility(bt_1, visibilityWhenFalse).accept(value);
    } catch (Exception e) {
        e.printStackTrace();
    }

相当于

    boolean value = false;
    int visibilityWhenFalse = View.VISIBLE;
    bt_1.setVisibility(value ? View.VISIBLE : visibilityWhenFalse);

相当于

    bt_1.setOnLongClickListener(new View.OnLongClickListener() {
        @Override
        public boolean onLongClick(View v) {
            Log.d("aaa", "1111111111111111");
            return false;
        }
    });

RxView.attaches(bt_1);

RxView.attachEvents(bt_1)

RxView.detaches(bt_1);

    RxView.longClicks(bt_1)
            .subscribe(new Consumer<Unit>() {
                @Override
                public void accept(Unit unit) throws Exception {

                    //设置震动反馈
                    bt_1.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS, HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);

                    // 创建DragShadowBuilder,我把控件本身传进去
                    View.DragShadowBuilder builder = new View.DragShadowBuilder(bt_1);
                    // 剪切板数据,可以在DragEvent.ACTION_DROP方法的时候获取。
                    ClipData data = ClipData.newPlainText("Label", "我是文本内容!");
                    // 开始拖拽
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                        bt_1.startDragAndDrop(data, builder,bt_1, 0);
                    }else{
                        bt_1.startDrag(data, builder, bt_1, 0);
                    }

                }
            });

效果如下:

40.gif

监听某View重绘

随便自定义一个view吧

public class CustomView extends View {
    public CustomView(Context context) {
        super(context);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public CustomView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr, 0);
    }

    int[] colors = {Color.RED, Color.BLACK, Color.CYAN, Color.BLUE};
    int index = 0;
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(colors[index]);
        Log.d("aaa", String.valueOf(index));

        index = (++index >= colors.length) ? 0 : index;
        postInvalidateDelayed(1000);
    }
}

效果如下

41.gif

现在开始监听

            RxView.draws(view_demo)
                    .subscribe(new Consumer<Unit>() {
                        @Override
                        public void accept(Unit unit) throws Exception {
                            Log.d("aaa", "22222");
                        }
                    });

相当于

            view_demo.getViewTreeObserver().addOnDrawListener(new ViewTreeObserver.OnDrawListener() {
                @Override
                public void onDraw() {
                    Log.d("aaa", "22222");
                }
            });

在弹出软键盘,使布局变化的场景常用

    RxView.globalLayouts(rootview)
            .subscribe(new Consumer<Unit>() {
                @Override
                public void accept(Unit unit) throws Exception {
                    Log.d("aaa", "1111111111111111111");
                }
            });

相当于

    rootview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            Log.d("aaa", "1111111111111111111");
        }
    });

相当于

    et_demo.setOnFocusChangeListener(new View.OnFocusChangeListener() {
        @Override
        public void onFocusChange(View v, boolean hasFocus) {
            Log.d("aaa", "11111111111111");
        }
    });

一些平板支持鼠标,当鼠标悬停在某view上时,会有其他效果

图片.png

比如给按钮添加背景,设置state_hovered属性, 当鼠标悬停在view上时会改变颜色。

我们也可以对悬停事件进行监听

    RxView.hovers(bt_1)
            .subscribe(new Consumer<MotionEvent>() {
                @Override
                public void accept(MotionEvent motionEvent) throws Exception {
                    Log.d("aaa", "11111111111111");
                    int what = motionEvent.getAction();
                    switch(what){
                        case MotionEvent.ACTION_HOVER_ENTER: //鼠标进入view
                            break;
                        case MotionEvent.ACTION_HOVER_MOVE: //鼠标在view上
                            break;
                        case MotionEvent.ACTION_HOVER_EXIT: //鼠标离开view
                            break;
                    }
                }
            });

相当于

    bt_1.setOnHoverListener(new View.OnHoverListener() {
        @Override
        public boolean onHover(View v, MotionEvent event) {
            Log.d("aaa", "11111111111111");
            int what = event.getAction();
            switch(what){
                case MotionEvent.ACTION_HOVER_ENTER: //鼠标进入view
                    break;
                case MotionEvent.ACTION_HOVER_MOVE: //鼠标在view上
                    break;
                case MotionEvent.ACTION_HOVER_EXIT: //鼠标离开view
                    break;
            }
            return false;
        }
    });

主要用作于监听物理按键的返回键,当然,软键盘的删除和回车(搜索)也是可以监听到的。

    RxView.keys(et_demo)
            .subscribe(new Consumer<KeyEvent>() {
                @Override
                public void accept(KeyEvent keyEvent) throws Exception {
                    Log.d("aaa", "11111111111111");
                }
            });

相当于

    et_demo.setOnKeyListener(new View.OnKeyListener() {
        @Override
        public boolean onKey(View v, int keyCode, KeyEvent event) {
            Log.d("aaa", "11111111111111:"+event.getAction());
            return false;
        }
    });
    RxView.layoutChangeEvents(rootview)
            .subscribe(new Consumer<ViewLayoutChangeEvent>() {
                @Override
                public void accept(ViewLayoutChangeEvent viewLayoutChangeEvent) throws Exception {
                    Log.d("aaa", "1111111111111111111");
                }
            });

相当于

    rootview.addOnLayoutChangeListener(new View.OnLayoutChangeListener() {
        @Override
        public void onLayoutChange(View v, int left, int top, int right, int bottom, int oldLeft, int oldTop, int oldRight, int oldBottom) {
            Log.d("aaa", "1111111111111111111");
        }
    });

熟悉自定义view或者viewgroup的猿一定知道三个方法:onMeasureonLayoutonDraw,它们的执行顺序是onMeasure-->onLayout-->onDrawpreDraws监听的时机就在onLayoutonDraw之间。

    RxView.preDraws(view_demo, new Function0<Boolean>() {
        @Override
        public Boolean invoke() {
            return false;
        }
    })
            .subscribe(new Observer<Unit>() {
                @Override
                public void onSubscribe(Disposable d) {
                    disposable = d;
                }

                @Override
                public void onNext(Unit unit) {
                    Log.d("aaa", "onPreDraw");
                    //接收一次之后立即移除监听,否则会阻塞UI线程
                    disposable.dispose();
                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onComplete() {

                }
            });

相当于

    view_demo.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
        @Override
        public boolean onPreDraw() {
            Log.d("aaa", "onPreDraw");
            //监听一次之后立即移除监听,否则会阻塞UI线程
            view_demo.getViewTreeObserver().removeOnPreDrawListener(this);
            return false;
        }
    });

这个监听在API 23之后生效

    RxView.scrollChangeEvents(view_demo)
            .subscribe(new Consumer<ViewScrollChangeEvent>() {
                @Override
                public void accept(ViewScrollChangeEvent viewScrollChangeEvent) throws Exception {
                    
                }
            });

相当于

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        view_demo.setOnScrollChangeListener(new View.OnScrollChangeListener() {
            @Override
            public void onScrollChange(View v, int scrollX, int scrollY, int oldScrollX, int oldScrollY) {

            }
        });
    }

相当于

    rootview.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
        @Override
        public void onSystemUiVisibilityChange(int visibility) {

        }
    });

相当于

    et_demo.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            return false;
        }
    });
(5)RxTextView

对文本变化监听。

    RxTextView.beforeTextChangeEvents(et_demo)
            .subscribe(new Consumer<TextViewBeforeTextChangeEvent>() {
                @Override
                public void accept(TextViewBeforeTextChangeEvent textViewBeforeTextChangeEvent) throws Exception {
                    Log.d("aaa", "111111111111111");
                }
            });

    RxTextView.textChangeEvents(et_demo)
            .subscribe(new Consumer<TextViewTextChangeEvent>() {
                @Override
                public void accept(TextViewTextChangeEvent textViewTextChangeEvent) throws Exception {
                    Log.d("aaa", "2222222222222222222");
                }
            });

    RxTextView.afterTextChangeEvents(et_demo)
            .subscribe(new Consumer<TextViewAfterTextChangeEvent>() {
                @Override
                public void accept(TextViewAfterTextChangeEvent textViewAfterTextChangeEvent) throws Exception {
                    Log.d("aaa", "3333333333333333333333");
                }
            });

相当于

    et_demo.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {

        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {

        }

        @Override
        public void afterTextChanged(Editable s) {

        }
    });
    RxTextView.editorActionEvents(et_demo)
            .subscribe(new Consumer<TextViewEditorActionEvent>() {
                @Override
                public void accept(TextViewEditorActionEvent textViewEditorActionEvent) throws Exception {
                    Log.d("aaa", "1111111111111111111111");
                }
            });

相当于

    et_demo.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
            return false;
        }
    });

需要注意的是:在布局文件中需要添加inputType和imeOptions属性。

(6)RxViewGroup

当viewgroup添加或者删除子view时触发

    rootview.addView(view);
    rootview.removeView(view);

代码如下:

    RxViewGroup.changeEvents(rootview)
            .subscribe(new Consumer<ViewGroupHierarchyChangeEvent>() {
                @Override
                public void accept(ViewGroupHierarchyChangeEvent viewGroupHierarchyChangeEvent) throws Exception {
                    Log.d("aaa", "11111111111111111111");
                }
            });

相当于

    rootview.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
        @Override
        public void onChildViewAdded(View parent, View child) {
            Log.d("aaa", "11111111111111111111");
        }

        @Override
        public void onChildViewRemoved(View parent, View child) {
            Log.d("aaa", "22222222222222222222");
        }
    });
(7)RxToolbar

相当于

    toolbar_normal.setNavigationOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

        }
    });

相当于

    toolbar_normal.setOnMenuItemClickListener(new Toolbar.OnMenuItemClickListener() {
        @Override
        public boolean onMenuItemClick(MenuItem menuItem) {
            switch (menuItem.getItemId()){
                case R.id.action_item_one:
                    break;
                case R.id.action_item_two:
                    break;
                case R.id.action_notification:
                    break;
                case R.id.action_search:
                    SearchView searchView = (SearchView) menuItem.getActionView();
                    searchView.setQueryHint("搜索");
                    break;
            }
            return true;
        }
    });
(8)RxMenuItem

对应着Toolbar某Item的点击事件

对应着Toolbar某Item的点击事件

(9)RxRadioGroup

监听选中变化

    RxRadioGroup.checkedChanges(radio_g).subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            
        }
    });

相当于

    radio_g.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId) {

        }
    });

选择单选按钮

    try {
        RxRadioGroup.checked(radio_g).accept(radioButton2.getId());
    } catch (Exception e) {
        e.printStackTrace();
    }

相当于

    radio_g.check(radioButton2.getId());
(10)RxCompoundButton

单选按钮

    RxCompoundButton.checkedChanges(radioButton1)
            .subscribe(new Consumer<Boolean>() {
                @Override
                public void accept(Boolean isChecked) throws Exception {

                }
            });

相当于

    radioButton1.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
        }
    });
(11)RxAutoCompleteTextView

Item点击事件监听

    RxAutoCompleteTextView.itemClickEvents(auto_tv)
            .subscribe(new Consumer<AdapterViewItemClickEvent>() {
                @Override
                public void accept(AdapterViewItemClickEvent adapterViewItemClickEvent) throws Exception {
                    
                }
            });
(12)RxPopupMenu

相当于

    popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
        @Override public boolean onMenuItemClick(MenuItem item) {
            // 控件每一个item的点击事件
            return true;
        }
    });

相当于

    popupMenu.setOnDismissListener(new PopupMenu.OnDismissListener() {
        @Override public void onDismiss(PopupMenu menu) {
            // 控件消失时的事件
        }
    });
(13)RxAdapter、RxAbsListView、RxAdapterView

适配器和listview相关,这个相信大家已经很熟悉了,这里不做过多介绍。

    //适配器Adapter数据改变
    RxAdapter.dataChanges();
    //绝对视图滚动事件
    RxAbsListView.scrollEvents();

    RxAdapterView.selectionEvents();

    RxAdapterView.itemSelections();

    RxAdapterView.itemClicks();

    RxAdapterView.itemLongClicks();

    RxAdapterView.itemLongClickEvents();
(14)RxSeekBar

进度条相关监听

    RxSeekBar.userChanges(seekBar).subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            
        }
    });

    RxSeekBar.systemChanges(seekBar).subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            
        }
    });

    RxSeekBar.changeEvents(seekBar).subscribe(new Consumer<SeekBarChangeEvent>() {
        @Override
        public void accept(SeekBarChangeEvent seekBarChangeEvent) throws Exception {
            
        }
    });

    RxSeekBar.changes(seekBar).subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            
        }
    });
(15)RxRatingBar

RatingBar用作评分的进度条

图片.png

比如上图, 用手指拖动可以进行评分。

    //星级滚动条进度改变事件
    RxRatingBar.ratingChanges();
    //星级滚动条进度改变事件
    RxRatingBar.ratingChangeEvents();

它的用法比较简单,这里就不写完整代码了。

(16)RxSearchView

SearchView的一般监听写法是

    search_view.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String query) {
            //提交后的处理
            return true;
        }

        @Override
        public boolean onQueryTextChange(String newText) {
            //输入文本监听,newText是文本变化后的文本
            return true;
        }
    });

输入文本监听,文本变化后的文本

    RxSearchView.queryTextChanges(search_view)
            .subscribe(new Consumer<CharSequence>() {
                @Override
                public void accept(CharSequence charSequence) throws Exception {
                    //输入文本监听,文本变化后的文本
                    Log.d("aaa", charSequence.toString());
                }
            });
上一篇下一篇

猜你喜欢

热点阅读