一、設置setOnClickListener
這應該是最原始的方法了吧,來,先上代碼:
布局文件:
1 <Button 2 android:id="@+id/button1" 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" 5 android:layout_marginLeft="63dp" 6 android:layout_marginStart="63dp" 7 android:layout_marginTop="26dp" 8 android:text="Button1" 9 app:layout_constraintStart_toStartOf="parent" 10 app:layout_constraintTop_toBottomOf="@id/button" />
Java代碼:
1 binding.button1.setOnClickListener(v -> { 2 log("click button1"); 3 });
當然,這里使用了MVVM中的DataBinding來查找控件的,你如果樂意,也可以用findViewById,甚至可以用Kotlin中的自動導入控件功能
二、在布局文件中直接寫onClick屬性
布局文件:
1 <Button 2 android:id="@+id/button3" 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" 5 android:layout_marginLeft="63dp" 6 android:layout_marginStart="63dp" 7 android:layout_marginTop="26dp" 8 android:onClick="onClickButton3" <!-- 可以看到,這里直接寫onClick屬性 --> 9 android:text="Button3" 10 app:layout_constraintStart_toStartOf="parent" 11 app:layout_constraintTop_toBottomOf="@id/button2" />
在Activity中直接實現onClickButton3方法即可:
1 public void onClickButton3(View v) { 2 log("click button 3"); 3 }
三、使用MVVM的DataBinding來實現
我們使用MVVM的設計模式,先看布局文件:
1 <?xml version="1.0" encoding="utf-8"?> 2 <layout xmlns:android="http://schemas.android.com/apk/res/android" 3 xmlns:app="http://schemas.android.com/apk/res-auto" 4 xmlns:bind="http://schemas.android.com/apk/res-auto" 5 xmlns:tools="http://schemas.android.com/tools"> 6 7 <data> 13 <variable 14 name="clickHandler" 15 type="com.plbear.doncal.rxjavademo.MainActivity.ClickHandler" /> 16 </data> 17 18 <android.support.constraint.ConstraintLayout 19 android:layout_width="match_parent" 20 android:layout_height="match_parent"> 55 <Button 56 android:id="@+id/button2" 57 android:layout_width="wrap_content" 58 android:layout_height="wrap_content" 59 android:layout_marginLeft="63dp" 60 android:layout_marginStart="63dp" 61 android:layout_marginTop="26dp" 62 android:onClick="@{clickHandler.onClickButton2}" 63 android:text="Button2" 64 app:layout_constraintStart_toStartOf="parent" 65 app:layout_constraintTop_toBottomOf="@id/button1" /> 88 </android.support.constraint.ConstraintLayout> 89 </layout>
布局文件中onClick直接指向ClickHandler類中的onClickButton2變量,Java中實現該變量即可:
1 public class ClickHandler { 2 public View.OnClickListener onClickButton2 = v -> { 3 log("click button2"); 4 }; 5 }
四、利用RxView來實現
其實這才是今天要說的重點,先導包:
1 api 'io.reactivex:rxandroid:1.2.1' # 這是個RxJava的包 2 api 'io.reactivex:rxjava:1.3.0' #這個是RxJava的包 3 api 'io.reactivex.rxjava2:rxandroid:2.1.0' #這個是Rxjava2的包,下面用到的CompositeDisposable來自這個包 4 api 'com.jakewharton.rxbinding2:rxbinding:2.1.1' #這個是RxView需要用到的包
布局文件:
1 <Button 2 android:id="@+id/button1" 3 android:layout_width="wrap_content" 4 android:layout_height="wrap_content" 5 android:layout_marginLeft="63dp" 6 android:layout_marginStart="63dp" 7 android:layout_marginTop="26dp" 8 android:text="Button1" 9 app:layout_constraintStart_toStartOf="parent" 10 app:layout_constraintTop_toBottomOf="@id/button" />
Java文件:
先全部貼出來吧:
1 package com.plbear.doncal.rxjavademo; 2 3 import android.databinding.DataBindingUtil; 4 import android.support.v7.app.AppCompatActivity; 5 import android.os.Bundle; 6 import android.util.Log; 7 import android.view.View; 8 9 import com.jakewharton.rxbinding2.view.RxView; 10 import com.plbear.doncal.rxjavademo.databinding.ActivityMainBinding; 11 12 import java.util.concurrent.TimeUnit; 13 14 import io.reactivex.disposables.CompositeDisposable; 15 import io.reactivex.schedulers.Schedulers; 16 17 public class MainActivity extends AppCompatActivity { 18 ActivityMainBinding binding; //自動生成ActivityMainBinding類,命名規則是布局文件使用駝峰規則來命名 19 final User mUser = new User(); 20 21 CompositeDisposable compositeDisposable = new CompositeDisposable(); 22 23 @Override 24 protected void onCreate(Bundle savedInstanceState) { 25 super.onCreate(savedInstanceState); 26 binding = DataBindingUtil.setContentView(this, R.layout.activity_main); 27 mUser.setName("plbear"); //修改變量 28 mUser.setPasswd("123456"); 29 binding.setUser(mUser);//設置layout文件中的user值 30 //binding.setClickHandler(new ClickHandler());//2.設置layout文件中的clickHandler值 31 32 compositeDisposable.add(RxView.clicks(binding.button) 33 //.(5, TimeUnit.SECONDS) 34 .throttleFirst(5, TimeUnit.SECONDS) 35 .observeOn(Schedulers.io()) 36 .subscribe(v -> { 37 log("click button"); 38 })); 39 40 } 41 42 public void log(String msg) { 43 Log.e(MainActivity.class.getSimpleName(), "yanlog msg:" + msg); 44 } 45 46 @Override 47 protected void onDestroy() { 48 super.onDestroy(); 49 compositeDisposable.clear(); 50 } 51 }
第一步,先使用CompositeDisposable
有人就要問了,用這個是干啥嘞?
顧名思義,他是一個Disposable的容器類,我們都知道Rxjava是基於觀察者模式的,如上述代碼,我們通過RxView來建立一個觀察者模型(模型??),這個模型只在Activity生命周期內有效,那我們就需要在Activity的onDetory方法中依次調用Disposable的dispose方法,CompositeDisposable就提供了一個容器類,我們每新建一個觀察者模型(就叫模型吧。。。),調用CompositeDisposable.add的方法進行添加,在onDestory中直接clear就好了。clear方法會依次對容器內的Desposable實例進行dispose操作。是不是很簡單??(簡單個👻)
第二步,使用RxView來監聽click事件:
具體的,看代碼就行,這里只強調兩個方法:
- debounce(long timeout, TimeUnit unit),防抖作用,他表示在timeout時間內,如果沒有第二次點擊,我就把事件拋給觀察者,TimeUnit是事件單位
- throttleFirst(long windowDuration, TimeUnit unit),不好意思,也是防抖作用,他表示我第一次拋出事件后,如果在windowDuration時間內再次產生事件,不好意思,忽略。
看明白上面的區別了嗎?沒有看明白請把上面的文字再讀一遍(哈哈😝),反正我建議你用throttleFirst,不要用debounce。
好了,就先這樣,如果有別的方式可以響應Android點擊事件,可以在評論區留言。