lists interface a bit changed

This commit is contained in:
Gavriil Sitnikov 2016-07-26 22:17:13 +03:00
parent 0ff35b0f60
commit 582c7ff9dd
7 changed files with 513 additions and 53 deletions

View File

@ -2,8 +2,8 @@ apply plugin: 'com.android.library'
apply plugin: 'me.tatarka.retrolambda'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
compileSdkVersion 24
buildToolsVersion "24.0.1"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
@ -12,13 +12,15 @@ android {
defaultConfig {
minSdkVersion 9
targetSdkVersion 23
targetSdkVersion 24
}
}
dependencies {
compile project(':libraries:core')
provided 'com.android.support:appcompat-v7:23.4.0'
provided 'io.reactivex:rxandroid:1.2.0'
provided 'com.android.support:appcompat-v7:24.1.1'
compile 'com.android.support:recyclerview-v7:24.1.1'
provided 'io.reactivex:rxandroid:1.2.1'
}

View File

@ -0,0 +1,152 @@
/*
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
*
* This file is part of RoboSwag library.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package ru.touchin.roboswag.components.adapters;
import android.support.annotation.CallSuper;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import java.util.concurrent.TimeUnit;
import ru.touchin.roboswag.components.utils.LifecycleBindable;
import ru.touchin.roboswag.core.log.Lc;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.subjects.BehaviorSubject;
/**
* Created by Gavriil Sitnikov on 12/8/2016.
* TODO: fill description
*/
public class BindableViewHolder extends RecyclerView.ViewHolder implements LifecycleBindable {
// it is needed to delay detach to avoid re-subscriptions on fast scroll
private static final long DETACH_DELAY = TimeUnit.SECONDS.toMillis(1);
@NonNull
private final LifecycleBindable baseLifecycleBindable;
@NonNull
private final BehaviorSubject<Boolean> attachedToWindowSubject = BehaviorSubject.create();
private final Observable<Boolean> attachedObservable;
public BindableViewHolder(@NonNull final LifecycleBindable baseLifecycleBindable, @NonNull final View itemView) {
super(itemView);
this.baseLifecycleBindable = baseLifecycleBindable;
attachedObservable = attachedToWindowSubject
.switchMap(attached -> attached
? Observable.just(true)
: Observable.timer(DETACH_DELAY, TimeUnit.MILLISECONDS).map(ignored -> false))
.distinctUntilChanged()
.replay(1)
.refCount();
}
@CallSuper
public void onAttachedToWindow() {
attachedToWindowSubject.onNext(true);
}
public boolean isAttachedToWindow() {
return attachedToWindowSubject.hasValue() && attachedToWindowSubject.getValue();
}
@CallSuper
public void onDetachedFromWindow() {
attachedToWindowSubject.onNext(false);
}
@SuppressWarnings("CPD-START")
//CPD: it is same as in other implementation based on BaseLifecycleBindable
@NonNull
@Override
public <T> Subscription bind(@NonNull final Observable<T> observable, @NonNull final Action1<T> onNextAction) {
final Observable<T> safeObservable = observable
.onErrorResumeNext(throwable -> {
Lc.assertion(throwable);
return Observable.never();
})
.observeOn(AndroidSchedulers.mainThread());
return attachedObservable.switchMap(attached -> attached ? safeObservable : Observable.never())
.subscribe(onNextAction);
}
@NonNull
@Override
public <T> Subscription untilStop(@NonNull final Observable<T> observable) {
return baseLifecycleBindable.untilStop(observable);
}
@NonNull
@Override
public <T> Subscription untilStop(@NonNull final Observable<T> observable, @NonNull final Action1<T> onNextAction) {
return baseLifecycleBindable.untilStop(observable, onNextAction);
}
@NonNull
@Override
public <T> Subscription untilStop(@NonNull final Observable<T> observable,
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction) {
return baseLifecycleBindable.untilStop(observable, onNextAction, onErrorAction);
}
@NonNull
@Override
public <T> Subscription untilStop(@NonNull final Observable<T> observable,
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction,
@NonNull final Action0 onCompletedAction) {
return baseLifecycleBindable.untilStop(observable, onNextAction, onErrorAction, onCompletedAction);
}
@NonNull
@Override
public <T> Subscription untilDestroy(@NonNull final Observable<T> observable) {
return baseLifecycleBindable.untilDestroy(observable);
}
@NonNull
@Override
public <T> Subscription untilDestroy(@NonNull final Observable<T> observable, @NonNull final Action1<T> onNextAction) {
return baseLifecycleBindable.untilDestroy(observable, onNextAction);
}
@NonNull
@Override
public <T> Subscription untilDestroy(@NonNull final Observable<T> observable,
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction) {
return baseLifecycleBindable.untilDestroy(observable, onNextAction, onErrorAction);
}
@NonNull
@Override
public <T> Subscription untilDestroy(@NonNull final Observable<T> observable,
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction,
@NonNull final Action0 onCompletedAction) {
return baseLifecycleBindable.untilDestroy(observable, onNextAction, onErrorAction, onCompletedAction);
}
}

View File

@ -0,0 +1,307 @@
/*
* Copyright (c) 2015 RoboSwag (Gavriil Sitnikov, Vsevolod Ivanov)
*
* This file is part of RoboSwag library.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package ru.touchin.roboswag.components.adapters;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.view.ViewGroup;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import ru.touchin.roboswag.components.utils.LifecycleBindable;
import ru.touchin.roboswag.components.utils.UiUtils;
import ru.touchin.roboswag.core.log.Lc;
import ru.touchin.roboswag.core.observables.collections.Change;
import ru.touchin.roboswag.core.observables.collections.ObservableCollection;
import ru.touchin.roboswag.core.observables.collections.ObservableList;
import rx.Observable;
import rx.Subscription;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Actions;
import rx.subjects.BehaviorSubject;
/**
* Created by Gavriil Sitnikov on 20/11/2015.
* TODO: fill description
*/
public abstract class ObservableCollectionAdapter<TItem, TViewHolder extends ObservableCollectionAdapter.ViewHolder>
extends RecyclerView.Adapter<BindableViewHolder> {
private static final int PRE_LOADING_COUNT = 10;
private static final int LIST_ITEM_TYPE = 12313212;
@NonNull
private final BehaviorSubject<ObservableCollection<TItem>> observableCollectionSubject
= BehaviorSubject.create((ObservableCollection<TItem>) null);
@NonNull
private final LifecycleBindable lifecycleBindable;
@Nullable
private OnItemClickListener<TItem> onItemClickListener;
private int lastUpdatedChangeNumber = -1;
@NonNull
private final Observable<?> historyPreLoadingObservable;
@NonNull
private final ObservableList<TItem> innerCollection = new ObservableList<>();
private boolean anyChangeApplied;
@NonNull
private final List<RecyclerView> attachedRecyclerViews = new LinkedList<>();
public ObservableCollectionAdapter(@NonNull final LifecycleBindable lifecycleBindable) {
super();
this.lifecycleBindable = lifecycleBindable;
innerCollection.observeChanges().subscribe(this::onItemsChanged);
lifecycleBindable.untilDestroy(observableCollectionSubject
.doOnNext(collection -> innerCollection.set(collection != null ? collection.getItems() : new ArrayList<>()))
.switchMap(observableCollection -> observableCollection != null
? observableCollection.observeChanges().observeOn(AndroidSchedulers.mainThread())
: Observable.empty()),
changes -> {
anyChangeApplied = true;
for (final Change<TItem> change : changes.getChanges()) {
switch (change.getType()) {
case INSERTED:
innerCollection.addAll(change.getStart(), change.getChangedItems());
break;
case CHANGED:
innerCollection.update(change.getStart(), change.getChangedItems());
break;
case REMOVED:
innerCollection.remove(change.getStart(), change.getCount());
break;
default:
Lc.assertion("Not supported " + change.getType());
break;
}
}
});
historyPreLoadingObservable = observableCollectionSubject
.switchMap(observableCollection -> {
final int size = observableCollection.size();
return observableCollection.loadRange(size, size + PRE_LOADING_COUNT);
});
}
@Override
public void onAttachedToRecyclerView(@NonNull final RecyclerView recyclerView) {
super.onAttachedToRecyclerView(recyclerView);
attachedRecyclerViews.add(recyclerView);
}
@Override
public void onDetachedFromRecyclerView(@NonNull final RecyclerView recyclerView) {
super.onDetachedFromRecyclerView(recyclerView);
attachedRecyclerViews.remove(recyclerView);
}
@NonNull
public LifecycleBindable getLifecycleBindable() {
return lifecycleBindable;
}
protected long getItemClickDelay() {
return UiUtils.RIPPLE_EFFECT_DELAY;
}
public void setItems(@NonNull final List<TItem> items) {
setObservableCollection(new ObservableList<>(items));
}
@Nullable
public ObservableCollection<TItem> getObservableCollection() {
return observableCollectionSubject.getValue();
}
@NonNull
public Observable<ObservableCollection<TItem>> observeObservableCollection() {
return observableCollectionSubject.distinctUntilChanged();
}
protected int getHeadersCount() {
return 0;
}
protected int getFootersCount() {
return 0;
}
private void refreshUpdate() {
notifyDataSetChanged();
lastUpdatedChangeNumber = innerCollection.getChangesCount();
}
public void setObservableCollection(@Nullable final ObservableCollection<TItem> observableCollection) {
this.observableCollectionSubject.onNext(observableCollection);
refreshUpdate();
}
private boolean anyRecyclerViewShown() {
for (final RecyclerView recyclerView : attachedRecyclerViews) {
if (recyclerView.isShown()) {
return true;
}
}
return false;
}
protected void onItemsChanged(@NonNull final ObservableCollection.CollectionChange<TItem> collectionChange) {
if (Looper.myLooper() != Looper.getMainLooper()) {
Lc.assertion("Items changes called on not main thread");
return;
}
if (!anyChangeApplied || !anyRecyclerViewShown()) {
anyChangeApplied = true;
refreshUpdate();
return;
}
if (collectionChange.getNumber() != innerCollection.getChangesCount()
|| collectionChange.getNumber() != lastUpdatedChangeNumber + 1) {
if (lastUpdatedChangeNumber < collectionChange.getNumber()) {
refreshUpdate();
}
return;
}
notifyAboutChanges(collectionChange.getChanges());
lastUpdatedChangeNumber = innerCollection.getChangesCount();
}
private void notifyAboutChanges(@NonNull final Collection<Change<TItem>> changes) {
for (final Change change : changes) {
switch (change.getType()) {
case INSERTED:
notifyItemRangeInserted(change.getStart() + getHeadersCount(), change.getCount());
break;
case CHANGED:
notifyItemRangeChanged(change.getStart() + getHeadersCount(), change.getCount());
break;
case REMOVED:
if (getItemCount() == 0) {
//TODO: bug of recyclerview?
notifyDataSetChanged();
} else {
notifyItemRangeRemoved(change.getStart() + getHeadersCount(), change.getCount());
}
break;
default:
Lc.assertion("Not supported " + change.getType());
break;
}
}
}
public void setOnItemClickListener(@Nullable final OnItemClickListener<TItem> onItemClickListener) {
this.onItemClickListener = onItemClickListener;
refreshUpdate();
}
@Override
public int getItemViewType(final int position) {
return LIST_ITEM_TYPE;
}
@Override
public BindableViewHolder onCreateViewHolder(@NonNull final ViewGroup parent, final int viewType) {
return onCreateItemViewHolder(parent, viewType);
}
public abstract TViewHolder onCreateItemViewHolder(@NonNull ViewGroup parent, int viewType);
@SuppressWarnings("unchecked")
@Override
public void onBindViewHolder(final BindableViewHolder holder, final int position) {
lastUpdatedChangeNumber = innerCollection.getChangesCount();
if (position - getHeadersCount() >= innerCollection.size()) {
return;
}
final TItem item = innerCollection.get(position - getHeadersCount());
onBindItemToViewHolder((TViewHolder) holder, position, item);
((TViewHolder) holder).bindPosition(position);
if (onItemClickListener != null && !isOnClickListenerDisabled(item)) {
UiUtils.setOnRippleClickListener(holder.itemView, () -> onItemClickListener.onItemClicked(item, position), getItemClickDelay());
}
}
protected abstract void onBindItemToViewHolder(@NonNull TViewHolder holder, int position, @NonNull TItem item);
@Nullable
public TItem getItem(final int position) {
final int positionInList = position - getHeadersCount();
return positionInList >= innerCollection.size() ? null : innerCollection.get(positionInList);
}
@Override
public int getItemCount() {
return getHeadersCount() + innerCollection.size() + getFootersCount();
}
@Override
public void onViewAttachedToWindow(@NonNull final BindableViewHolder holder) {
super.onViewAttachedToWindow(holder);
holder.onAttachedToWindow();
}
@Override
public void onViewDetachedFromWindow(@NonNull final BindableViewHolder holder) {
holder.onDetachedFromWindow();
super.onViewDetachedFromWindow(holder);
}
public boolean isOnClickListenerDisabled(@NonNull final TItem item) {
return false;
}
public interface OnItemClickListener<TItem> {
void onItemClicked(@NonNull TItem item, int position);
}
public class ViewHolder extends BindableViewHolder {
@Nullable
private Subscription historyPreLoadingSubscription;
public ViewHolder(@NonNull final LifecycleBindable baseBindable, @NonNull final View itemView) {
super(baseBindable, itemView);
}
@SuppressWarnings("unchecked")
public void bindPosition(final int position) {
if (historyPreLoadingSubscription != null) {
historyPreLoadingSubscription.unsubscribe();
historyPreLoadingSubscription = null;
}
if (position - getHeadersCount() > innerCollection.size() - PRE_LOADING_COUNT) {
historyPreLoadingSubscription = bind(historyPreLoadingObservable, Actions.empty());
}
}
}
}

View File

@ -33,8 +33,8 @@ import android.view.ViewGroup;
import ru.touchin.roboswag.components.navigation.activities.ViewControllerActivity;
import ru.touchin.roboswag.components.navigation.fragments.ViewControllerFragment;
import ru.touchin.roboswag.components.observables.ui.BaseUiBindable;
import ru.touchin.roboswag.components.observables.ui.UiBindable;
import ru.touchin.roboswag.components.utils.BaseLifecycleBindable;
import ru.touchin.roboswag.components.utils.LifecycleBindable;
import rx.Observable;
import rx.Subscription;
import rx.functions.Action0;
@ -49,7 +49,7 @@ import rx.functions.Action1;
*/
public class ViewController<TActivity extends ViewControllerActivity<?>,
TFragment extends ViewControllerFragment<?, TActivity>>
implements UiBindable {
implements LifecycleBindable {
@NonNull
private final TActivity activity;
@ -58,13 +58,12 @@ public class ViewController<TActivity extends ViewControllerActivity<?>,
@NonNull
private final ViewGroup container;
@NonNull
private final BaseUiBindable baseUiBindable = new BaseUiBindable();
private final BaseLifecycleBindable baseLifecycleBindable = new BaseLifecycleBindable();
private boolean destroyed;
@SuppressWarnings({"unchecked", "PMD.UnusedFormalParameter"})
//UnusedFormalParameter: savedInstanceState could be used by children
public ViewController(@NonNull final CreationContext creationContext,
@Nullable final Bundle savedInstanceState) {
public ViewController(@NonNull final CreationContext creationContext, @Nullable final Bundle savedInstanceState) {
this.activity = (TActivity) creationContext.activity;
this.fragment = (TFragment) creationContext.fragment;
this.container = creationContext.container;
@ -147,7 +146,7 @@ public class ViewController<TActivity extends ViewControllerActivity<?>,
*/
@CallSuper
public void onCreate() {
baseUiBindable.onCreate();
baseLifecycleBindable.onCreate();
}
/**
@ -156,7 +155,7 @@ public class ViewController<TActivity extends ViewControllerActivity<?>,
*/
@CallSuper
public void onStart() {
baseUiBindable.onStart();
baseLifecycleBindable.onStart();
}
/**
@ -175,7 +174,7 @@ public class ViewController<TActivity extends ViewControllerActivity<?>,
*/
@CallSuper
public void onStop() {
baseUiBindable.onStop();
baseLifecycleBindable.onStop();
}
/**
@ -184,7 +183,7 @@ public class ViewController<TActivity extends ViewControllerActivity<?>,
*/
@CallSuper
public void onDestroy() {
baseUiBindable.onDestroy();
baseLifecycleBindable.onDestroy();
destroyed = true;
}
@ -199,23 +198,23 @@ public class ViewController<TActivity extends ViewControllerActivity<?>,
}
@SuppressWarnings("CPD-START")
//CPD: it is same as in other implementation based on BaseUiBindable
//CPD: it is same as in other implementation based on BaseLifecycleBindable
@NonNull
@Override
public <T> Subscription bind(@NonNull final Observable<T> observable, @NonNull final Action1<T> onNextAction) {
return baseUiBindable.bind(observable, onNextAction);
return baseLifecycleBindable.bind(observable, onNextAction);
}
@NonNull
@Override
public <T> Subscription untilStop(@NonNull final Observable<T> observable) {
return baseUiBindable.untilStop(observable);
return baseLifecycleBindable.untilStop(observable);
}
@NonNull
@Override
public <T> Subscription untilStop(@NonNull final Observable<T> observable, @NonNull final Action1<T> onNextAction) {
return baseUiBindable.untilStop(observable, onNextAction);
return baseLifecycleBindable.untilStop(observable, onNextAction);
}
@NonNull
@ -223,7 +222,7 @@ public class ViewController<TActivity extends ViewControllerActivity<?>,
public <T> Subscription untilStop(@NonNull final Observable<T> observable,
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction) {
return baseUiBindable.untilStop(observable, onNextAction, onErrorAction);
return baseLifecycleBindable.untilStop(observable, onNextAction, onErrorAction);
}
@NonNull
@ -232,19 +231,19 @@ public class ViewController<TActivity extends ViewControllerActivity<?>,
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction,
@NonNull final Action0 onCompletedAction) {
return baseUiBindable.untilStop(observable, onNextAction, onErrorAction, onCompletedAction);
return baseLifecycleBindable.untilStop(observable, onNextAction, onErrorAction, onCompletedAction);
}
@NonNull
@Override
public <T> Subscription untilDestroy(@NonNull final Observable<T> observable) {
return baseUiBindable.untilDestroy(observable);
return baseLifecycleBindable.untilDestroy(observable);
}
@NonNull
@Override
public <T> Subscription untilDestroy(@NonNull final Observable<T> observable, @NonNull final Action1<T> onNextAction) {
return baseUiBindable.untilDestroy(observable, onNextAction);
return baseLifecycleBindable.untilDestroy(observable, onNextAction);
}
@NonNull
@ -252,7 +251,7 @@ public class ViewController<TActivity extends ViewControllerActivity<?>,
public <T> Subscription untilDestroy(@NonNull final Observable<T> observable,
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction) {
return baseUiBindable.untilDestroy(observable, onNextAction, onErrorAction);
return baseLifecycleBindable.untilDestroy(observable, onNextAction, onErrorAction);
}
@NonNull
@ -261,11 +260,11 @@ public class ViewController<TActivity extends ViewControllerActivity<?>,
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction,
@NonNull final Action0 onCompletedAction) {
return baseUiBindable.untilDestroy(observable, onNextAction, onErrorAction, onCompletedAction);
return baseLifecycleBindable.untilDestroy(observable, onNextAction, onErrorAction, onCompletedAction);
}
@SuppressWarnings("CPD-END")
//CPD: it is same as in other implementation based on BaseUiBindable
//CPD: it is same as in other implementation based on BaseLifecycleBindable
/**
* Helper class to simplify constructor override.
*/

View File

@ -29,8 +29,8 @@ import android.view.inputmethod.InputMethodManager;
import java.util.ArrayList;
import ru.touchin.roboswag.components.observables.ui.BaseUiBindable;
import ru.touchin.roboswag.components.observables.ui.UiBindable;
import ru.touchin.roboswag.components.utils.BaseLifecycleBindable;
import ru.touchin.roboswag.components.utils.LifecycleBindable;
import rx.Observable;
import rx.Subscription;
import rx.functions.Action0;
@ -42,12 +42,12 @@ import rx.functions.Action1;
*/
@SuppressWarnings("PMD.TooManyMethods")
public abstract class BaseActivity extends AppCompatActivity
implements UiBindable {
implements LifecycleBindable {
@NonNull
private final ArrayList<OnBackPressedListener> onBackPressedListeners = new ArrayList<>();
@NonNull
private final BaseUiBindable baseUiBindable = new BaseUiBindable();
private final BaseLifecycleBindable baseLifecycleBindable = new BaseLifecycleBindable();
private boolean resumed;
/**
@ -62,13 +62,13 @@ public abstract class BaseActivity extends AppCompatActivity
@Override
protected void onCreate(@Nullable final Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
baseUiBindable.onCreate();
baseLifecycleBindable.onCreate();
}
@Override
protected void onStart() {
super.onStart();
baseUiBindable.onStart();
baseLifecycleBindable.onStart();
}
@Override
@ -85,13 +85,13 @@ public abstract class BaseActivity extends AppCompatActivity
@Override
protected void onStop() {
baseUiBindable.onStop();
baseLifecycleBindable.onStop();
super.onStop();
}
@Override
protected void onDestroy() {
baseUiBindable.onDestroy();
baseLifecycleBindable.onDestroy();
super.onDestroy();
}
@ -146,11 +146,11 @@ public abstract class BaseActivity extends AppCompatActivity
}
@SuppressWarnings("CPD-START")
//CPD: it is same as in other implementation based on BaseUiBindable
//CPD: it is same as in other implementation based on BaseLifecycleBindable
@NonNull
@Override
public <T> Subscription bind(@NonNull final Observable<T> observable, @NonNull final Action1<T> onNextAction) {
return baseUiBindable.bind(observable, onNextAction);
return baseLifecycleBindable.bind(observable, onNextAction);
}
@NonNull
@ -158,7 +158,7 @@ public abstract class BaseActivity extends AppCompatActivity
public <T> Subscription untilStop(@NonNull final Observable<T> observable,
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction) {
return baseUiBindable.untilStop(observable, onNextAction, onErrorAction);
return baseLifecycleBindable.untilStop(observable, onNextAction, onErrorAction);
}
@NonNull
@ -167,31 +167,31 @@ public abstract class BaseActivity extends AppCompatActivity
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction,
@NonNull final Action0 onCompletedAction) {
return baseUiBindable.untilStop(observable, onNextAction, onErrorAction, onCompletedAction);
return baseLifecycleBindable.untilStop(observable, onNextAction, onErrorAction, onCompletedAction);
}
@NonNull
@Override
public <T> Subscription untilStop(@NonNull final Observable<T> observable) {
return baseUiBindable.untilStop(observable);
return baseLifecycleBindable.untilStop(observable);
}
@NonNull
@Override
public <T> Subscription untilStop(@NonNull final Observable<T> observable, @NonNull final Action1<T> onNextAction) {
return baseUiBindable.untilStop(observable, onNextAction);
return baseLifecycleBindable.untilStop(observable, onNextAction);
}
@NonNull
@Override
public <T> Subscription untilDestroy(@NonNull final Observable<T> observable) {
return baseUiBindable.untilDestroy(observable);
return baseLifecycleBindable.untilDestroy(observable);
}
@NonNull
@Override
public <T> Subscription untilDestroy(@NonNull final Observable<T> observable, @NonNull final Action1<T> onNextAction) {
return baseUiBindable.untilDestroy(observable, onNextAction);
return baseLifecycleBindable.untilDestroy(observable, onNextAction);
}
@NonNull
@ -199,7 +199,7 @@ public abstract class BaseActivity extends AppCompatActivity
public <T> Subscription untilDestroy(@NonNull final Observable<T> observable,
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction) {
return baseUiBindable.untilDestroy(observable, onNextAction, onErrorAction);
return baseLifecycleBindable.untilDestroy(observable, onNextAction, onErrorAction);
}
@NonNull
@ -208,11 +208,11 @@ public abstract class BaseActivity extends AppCompatActivity
@NonNull final Action1<T> onNextAction,
@NonNull final Action1<Throwable> onErrorAction,
@NonNull final Action0 onCompletedAction) {
return baseUiBindable.untilDestroy(observable, onNextAction, onErrorAction, onCompletedAction);
return baseLifecycleBindable.untilDestroy(observable, onNextAction, onErrorAction, onCompletedAction);
}
@SuppressWarnings("CPD-END")
//CPD: it is same as in other implementation based on BaseUiBindable
//CPD: it is same as in other implementation based on BaseLifecycleBindable
/**
* Interface to be implemented for someone who want to intercept device back button pressing event.
*/

View File

@ -17,7 +17,7 @@
*
*/
package ru.touchin.roboswag.components.observables.ui;
package ru.touchin.roboswag.components.utils;
import android.support.annotation.NonNull;
@ -32,9 +32,9 @@ import rx.subjects.BehaviorSubject;
/**
* Created by Gavriil Sitnikov on 18/04/16.
* Simple implementation of {@link UiBindable}. Could be used to not implement interface but use such object inside.
* Simple implementation of {@link LifecycleBindable}. Could be used to not implement interface but use such object inside.
*/
public class BaseUiBindable implements UiBindable {
public class BaseLifecycleBindable implements LifecycleBindable {
@NonNull
private final BehaviorSubject<Boolean> isCreatedSubject = BehaviorSubject.create();
@ -78,7 +78,7 @@ public class BaseUiBindable implements UiBindable {
return Observable.never();
})
.observeOn(AndroidSchedulers.mainThread());
return isStartedSubject.switchMap(isStarted -> isStarted ? safeObservable : Observable.never())
return isStartedSubject.switchMap(started -> started ? safeObservable : Observable.never())
.takeUntil(isCreatedSubject.filter(created -> !created))
.subscribe(onNextAction);
}
@ -148,7 +148,7 @@ public class BaseUiBindable implements UiBindable {
@NonNull final Action1<Throwable> onErrorAction,
@NonNull final Action0 onCompletedAction) {
return isCreatedSubject.first()
.switchMap(isCreated -> isCreated ? observable.observeOn(AndroidSchedulers.mainThread()) : Observable.empty())
.switchMap(created -> created ? observable.observeOn(AndroidSchedulers.mainThread()) : Observable.empty())
.takeUntil(conditionSubject.filter(condition -> condition))
.subscribe(onNextAction, onErrorAction, onCompletedAction);
}

View File

@ -17,7 +17,7 @@
*
*/
package ru.touchin.roboswag.components.observables.ui;
package ru.touchin.roboswag.components.utils;
import android.support.annotation.NonNull;
@ -36,7 +36,7 @@ import rx.functions.Func1;
* Use {@link #untilStop(Observable)} method to subscribe to observable where you want and unsubscribe onStop.
* Use {@link #untilDestroy(Observable)} method to subscribe to observable where you want and unsubscribe onDestroy.
*/
public interface UiBindable {
public interface LifecycleBindable {
/**
* Method should be used to subscribe to observable while this element is in started state.