2016-01-19 13 views
5

W android Mam widoku tekstu zdefiniowany następująco:RxJava - jak wywołać abonenta 4 zdarzeń kliknij Androida

<TextView 
    android:id="@+id/text1"  
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="@string/hello_world" 
    android:textColorHighlight="#000000" 
    android:textIsSelectable="true" /> 

Moim celem jest to, że po kliknięciu 4 razy, chcę zacząć nowy czynność. Muszę to zrobić z RXJava; to jest wymaganie. Lub rxAndroid, rxBinding itp

Moja aktywność wygląda następująco:

public class MainActivity extends Activity implements onClickListener { 
    TextView tv; 
    /** Called when the activity is first created. */ 
    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setContentView(R.layout.activity_main); 
     tv=(TextView)findViewById(R.id.text1); 
     tv.setOnClickListener(this); 
    } 

    @Override 
    public void onClick(View v) { 
     if(v.getId() == R.id.text1){ 

     } 
    } 
} 

UPDATE: ale jest to po prostu standardowy sposób to zrobić. Z reaktywnym interfejsem API rxJava musi być jakiś sposób.

Więc zamiast używać onClicklistener z rxBinding czytałem możemy to zrobić:

RxView.clicks(tv).flatMap(tv -> { 
     // another observable which can throw onError. 
     return Observable.error(null); 
    }).subscribe(object -> { 
     Log.d("CLICK", "textview clicked", start activity); 
    }, error -> { 
     Log.d("CLICK", "ERROR"); 
    }); 

można jakoś użyć polecenia w rxBinding aby wykonać dopiero po 4 kliknięcia? Nie chcę przechowywać zmiennej statycznej, lub użyć anonimowej klasy i przechowywać zmienną składową, aby ją policzyć. Powinna istnieć możliwa do zaobserwowania metoda.

+0

Próbujesz uzyskać czterokrotne kliknięcie lub tylko 4 kliknięcia o nieokreślonej ilości czasu między nimi? – skywall

+0

Czterokrotne kliknięcie, ale mogę rozliczać się za 4 kliknięcia z limitem czasu pomiędzy. to działa równie dobrze. – j2emanue

Odpowiedz

2

Można utworzyć obserwowalne, aby emitować za każdym razem, gdy kliknięto przycisk, a następnie policzyć całkowite czasy emisji, a następnie użyć filtra, aby subskrybent zobaczył je tylko po czterokrotnym wyemitowaniu.

Observable<View> buttonObservable = ViewObservable.clicks(initiateButton, false); 
buttonObservable.count() 
     .filter(count -> (count >= 4)) 
     .subscribe(object -> { 
      //Your code here 
     }); 
+0

czy możesz pokazać pełny kod, jak się policzyłeś? – j2emanue

+0

Metoda "Observable.count" po prostu zwraca liczbę wyświetleń elementu "Observable". Jest to część RxJava – TheoKanning

+1

count nie może być tutaj użyta, ponieważ będzie emitować tylko element po zakończeniu obserwowalnych emisji (http: // rxmarbles.com/# liczą) kliknięcie obserwowalne z drugiej strony jest nieskończona – ndori

4

można osiągnąć coś takiego:

Observable.create((Observable.OnSubscribe<Void>) subscriber -> { 
    if (!subscriber.isUnsubscribed()) { 
     button.setOnClickListener(v -> subscriber.onNext(null)); 
    } 
}).buffer(1000, TimeUnit.MILLISECONDS) 
     .filter(clicks -> clicks.size() == 4) 
     .observeOn(AndroidSchedulers.mainThread()) 
     .subscribe(clicks -> { 
      Log.d("CLICK", "CLICK"); 
     }); 
  • buffer() - gromadzić kliknięcia na oknie 1s
  • filter() - filtrowania wszystkich emitowanych buforowane elementy, gdzie jest liczba elementów w buforze nie równe 4 (wyłącz podwójne, potrójne, pięciokrotne kliknięcia)

Najtrudniejszą częścią jest określenie czasu "okna" bufora. Jedna sekunda czasami nie wystarcza, ale w innych przypadkach użytkownik musi odczekać kilka milisekund.

+0

Co to jest "stworzenie ((Observable.OnSubscribe "? Im przy rxjava2 –

+0

@PabloCegarra Jest to przykład jest oparty na RxJava1. Metoda 'create()' jest używane, gdy potrzebujesz utworzyć obserwowalne od jakiegoś dostawcy ('OnClickListener' w tym przypadku)' Observable.OnSubscribe 'jest po prostu definicją typu subskrybenta.W RxJava2 powinieneś użyć' Płynnego '. – skywall

+0

Czy możesz zaktualizować swój post do rxjava2 Proszę, zagłosuję, jeśli to zadziała, teraz używam rxbinding właśnie do tego –

1

@skywall odpowiedź jest najbardziej kompletny, jednak jeśli nie dbają o przedziałach czasowych najprostsza odpowiedź będzie używać skip

Observable<Void> fourClicksView = RxView.clicks(tv).skip(3); 
fourClicksView.subscribe(...); 
+0

To zależy, czy potrzebujesz dokładnie 4 kliknięć, a nie więcej Pytanie zostało zadeklarowane dokładnie jako czterokrotny clic k. – skywall

+0

Pytanie wymagane 4, oczywiście można je dowolnie zmieniać, jeśli chcesz tylko jedno wydarzenie, możesz również użyć first() lub take (1) później – ndori

0

Jeśli chcesz rozpocząć działalność po pewnej liczbie kliknięć w okno czasowe, a następnie spróbuj tego:

RxView.clicks(tv) 
    .map(e -> SystemClock.elapsedRealtime()) 
    .buffer(NUM_CLICKS, 1) //Grab every sub-sequence of however many clicks 
    .filter(times -> times.size() == NUM_CLICKS) //Last values will be truncated 
    .filter(times -> times.get(NUM_CLICKS - 1) - times.get(0) < ALLOWED_TIME) //check times 
    .subscribe(ignore -> startActivity()); 
0

Użyj bufora i operatora odbicia.

val clickStream = RxView.clicks(view) 
    clickStream.buffer(clickStream.debounce(250, TimeUnit.MILLISECONDS)) 
      .map { it.size } 
      .filter { it == 4 } 
      .subscribe({ 
      }) 
Powiązane problemy