package com.kickstarter.ui.viewholders;
import android.content.Context;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import com.kickstarter.KSApplication;
import com.kickstarter.libs.ActivityLifecycleType;
import com.kickstarter.libs.Environment;
import com.trello.rxlifecycle.ActivityEvent;
import com.trello.rxlifecycle.RxLifecycle;
import rx.Observable;
import rx.subjects.PublishSubject;
import timber.log.Timber;
public abstract class KSViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener,
ActivityLifecycleType {
private final View view;
private final @NonNull PublishSubject<ActivityEvent> lifecycle = PublishSubject.create();
public KSViewHolder(final @NonNull View view) {
super(view);
this.view = view;
view.setOnClickListener(this);
}
/**
* No-op click implementation. Subclasses should override this method to implement click handling.
*/
@Override
public void onClick(final @NonNull View view) {
Timber.d("Default KSViewHolder projectClicked event");
}
/**
* Populate a view with data that was bound in `bindData`.
*
* @deprecated Prefer creating subscriptions to a viewmodel in the constructor, then using #{link #bindData} to
* send new data to the viewmodel.
*/
@Deprecated
public void onBind() {}
/**
* Implementations of this should inspect `data` to set instance variables in the view holder that
* `onBind` can then use without worrying about type safety.
*
* @throws Exception Raised when binding is unsuccessful.
*/
abstract public void bindData(final @Nullable Object data) throws Exception;
@Override
public @NonNull Observable<ActivityEvent> lifecycle() {
return lifecycle;
}
/**
* This method is intended to be called only from `KSAdapter` in order for it to inform the view holder
* of its lifecycle.
*/
public void lifecycleEvent(final @NonNull ActivityEvent event) {
lifecycle.onNext(event);
if (ActivityEvent.DESTROY.equals(event)) {
destroy();
}
}
/**
* Completes an observable when an {@link ActivityEvent} occurs in the activity's lifecycle.
*/
public final @NonNull <T> Observable.Transformer<T, T> bindUntilEvent(final @NonNull ActivityEvent event) {
return RxLifecycle.bindUntilActivityEvent(lifecycle, event);
}
/**
* Completes an observable when the lifecycle event opposing the current lifecyle event is emitted.
* For example, if a subscription is made during {@link ActivityEvent#CREATE}, the observable will be completed
* in {@link ActivityEvent#DESTROY}.
*/
public final @NonNull <T> Observable.Transformer<T, T> bindToLifecycle() {
return RxLifecycle.bindActivity(lifecycle);
}
/**
* Called when the ViewHolder is being detached. Subclasses should override if they need to do any work
* when the ViewHolder is being de-allocated.
*/
protected void destroy() {}
protected @NonNull View view() {
return view;
}
protected @NonNull Context context() {
return view.getContext();
}
protected @NonNull Environment environment() {
return ((KSApplication) context().getApplicationContext()).component().environment();
}
}