package com.afollestad.aesthetic;
import android.content.Context;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.StateListDrawable;
import android.support.design.widget.NavigationView;
import android.support.v4.content.ContextCompat;
import android.util.AttributeSet;
import io.reactivex.Observable;
import io.reactivex.annotations.NonNull;
import io.reactivex.disposables.Disposable;
import io.reactivex.functions.Consumer;
import static com.afollestad.aesthetic.Rx.onErrorLogAndRethrow;
/** @author Aidan Follestad (afollestad) */
@SuppressWarnings("RestrictedApi")
public class AestheticNavigationView extends NavigationView {
private Disposable modeSubscription;
private Disposable colorSubscription;
public AestheticNavigationView(Context context) {
super(context);
}
public AestheticNavigationView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public AestheticNavigationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void invalidateColors(ColorIsDarkState state) {
int selectedColor = state.color();
boolean isDark = state.isDark();
int baseColor = isDark ? Color.WHITE : Color.BLACK;
int unselectedIconColor = Util.adjustAlpha(baseColor, .54f);
int unselectedTextColor = Util.adjustAlpha(baseColor, .87f);
int selectedItemBgColor =
ContextCompat.getColor(
getContext(),
isDark
? R.color.ate_navigation_drawer_selected_dark
: R.color.ate_navigation_drawer_selected_light);
final ColorStateList iconSl =
new ColorStateList(
new int[][] {
new int[] {-android.R.attr.state_checked}, new int[] {android.R.attr.state_checked}
},
new int[] {unselectedIconColor, selectedColor});
final ColorStateList textSl =
new ColorStateList(
new int[][] {
new int[] {-android.R.attr.state_checked}, new int[] {android.R.attr.state_checked}
},
new int[] {unselectedTextColor, selectedColor});
setItemTextColor(textSl);
setItemIconTintList(iconSl);
StateListDrawable bgDrawable = new StateListDrawable();
bgDrawable.addState(
new int[] {android.R.attr.state_checked}, new ColorDrawable(selectedItemBgColor));
setItemBackground(bgDrawable);
}
@Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
modeSubscription =
Aesthetic.get()
.navigationViewMode()
.compose(Rx.<Integer>distinctToMainThread())
.subscribe(
new Consumer<Integer>() {
@Override
public void accept(@NonNull Integer mode) {
switch (mode) {
case NavigationViewMode.SELECTED_PRIMARY:
colorSubscription =
Observable.combineLatest(
Aesthetic.get().colorPrimary(),
Aesthetic.get().isDark(),
ColorIsDarkState.creator())
.compose(Rx.<ColorIsDarkState>distinctToMainThread())
.subscribe(
new Consumer<ColorIsDarkState>() {
@Override
public void accept(
@NonNull ColorIsDarkState colorIsDarkState) {
invalidateColors(colorIsDarkState);
}
},
onErrorLogAndRethrow());
break;
case NavigationViewMode.SELECTED_ACCENT:
colorSubscription =
Observable.combineLatest(
Aesthetic.get().colorAccent(),
Aesthetic.get().isDark(),
ColorIsDarkState.creator())
.compose(Rx.<ColorIsDarkState>distinctToMainThread())
.subscribe(
new Consumer<ColorIsDarkState>() {
@Override
public void accept(
@NonNull ColorIsDarkState colorIsDarkState) {
invalidateColors(colorIsDarkState);
}
},
onErrorLogAndRethrow());
break;
default:
throw new IllegalStateException("Unknown nav view mode: " + mode);
}
}
},
onErrorLogAndRethrow());
}
@Override
protected void onDetachedFromWindow() {
if (modeSubscription != null) {
modeSubscription.dispose();
}
if (colorSubscription != null) {
colorSubscription.dispose();
}
super.onDetachedFromWindow();
}
}