package at.favre.lib.dali.builder.nav;
import android.app.Activity;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import at.favre.lib.dali.Dali;
import at.favre.lib.dali.util.BuilderUtil;
import at.favre.lib.dali.util.LegacySDKUtil;
/**
* This is a {@link android.support.v7.app.ActionBarDrawerToggle} that
* will blur the content behind when the nav drawer is opened. It uses
* a third layer over the content layer that alpha transitions in and out.
* <p/>
* It features 2 Cachemodes: {@link at.favre.lib.dali.builder.nav.DaliBlurDrawerToggle.CacheMode#AUTO} and {@link at.favre.lib.dali.builder.nav.DaliBlurDrawerToggle.CacheMode#MANUAL}
* The difference is, that in AUTO mode the blurview will be redrawn everytime
* the nav drawer opens. In manual you can decide for yourself when the cache
* will be invalidated.
*/
public class DaliBlurDrawerToggle extends ActionBarDrawerToggle {
private static String TAG = DaliBlurDrawerToggle.class.getSimpleName();
private DrawerLayout drawerLayout;
private Dali dali;
private ImageView blurView;
private int blurRadius = 16;
private int downSample = 4;
private CacheMode cacheMode = CacheMode.AUTO;
private boolean forceRedraw = false;
private boolean enableBlur = true;
private NavigationDrawerListener listener;
public DaliBlurDrawerToggle(Activity activity, DrawerLayout drawerLayout, Toolbar toolbar,
int openDrawerContentDescRes, int closeDrawerContentDescRes, NavigationDrawerListener listener) {
super(activity, drawerLayout, toolbar, openDrawerContentDescRes, closeDrawerContentDescRes);
dali = Dali.create(drawerLayout.getContext());
this.drawerLayout = drawerLayout;
this.listener = listener;
}
/**
* @param blurRadius
* @param downSample
* @param cacheMode AUTO = reblur occurs everytime the drawer gets opened,
* MANUAL = user has to call {@link DaliBlurDrawerToggle#setForceRedraw()} for a reblur (can be better optimized if the view hardly changes
*/
public void setConfig(int blurRadius, int downSample, CacheMode cacheMode) {
BuilderUtil.checkBlurRadiusPrecondition(blurRadius);
this.blurRadius = blurRadius;
this.downSample = downSample;
this.cacheMode = cacheMode;
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
super.onDrawerSlide(drawerView, slideOffset);
renderBlurLayer(slideOffset);
}
/**
* This will blur the view behind it and set it in
* a imageview over the content with a alpha value
* that corresponds to slideOffset.
*/
private void renderBlurLayer(float slideOffset) {
if (enableBlur) {
if (slideOffset == 0 || forceRedraw) {
clearBlurView();
}
if (slideOffset > 0f && blurView == null) {
if (drawerLayout.getChildCount() == 2) {
blurView = new ImageView(drawerLayout.getContext());
blurView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
blurView.setScaleType(ImageView.ScaleType.FIT_CENTER);
drawerLayout.addView(blurView, 1);
}
if (BuilderUtil.isOnUiThread()) {
if (cacheMode.equals(CacheMode.AUTO) || forceRedraw) {
dali.load(drawerLayout.getChildAt(0)).blurRadius(blurRadius).downScale(downSample).noFade().error(Dali.NO_RESID).concurrent().skipCache().into(blurView);
forceRedraw = false;
} else {
dali.load(drawerLayout.getChildAt(0)).blurRadius(blurRadius).downScale(downSample).noFade().error(Dali.NO_RESID).concurrent().into(blurView);
}
}
}
if (slideOffset > 0f && slideOffset < 1f) {
int alpha = (int) Math.ceil((double) slideOffset * 255d);
LegacySDKUtil.setImageAlpha(blurView, alpha);
}
}
}
private void clearBlurView() {
if (drawerLayout.getChildCount() == 3) {
drawerLayout.removeViewAt(1);
}
blurView = null;
}
/**
* Syncs state after e.g. orientation change
*/
@Override
public void syncState() {
super.syncState();
if (drawerLayout.isDrawerOpen(GravityCompat.START)) {
renderBlurLayer(255);
} else {
renderBlurLayer(0);
}
}
/**
* If this is set to false, it will basically behave like a normal
* {@link android.support.v4.app.ActionBarDrawerToggle}. Use this
* to deactivate the effect on slower devices.
*
* @param enableBlur
*/
public void setEnableBlur(boolean enableBlur) {
this.enableBlur = enableBlur;
}
/**
* This will invalidate any cache and force
* a re-blur on the next drawer slide event.
* This is used with {@link at.favre.lib.dali.builder.nav.DaliBlurDrawerToggle.CacheMode#MANUAL}
*/
public void setForceRedraw() {
forceRedraw = true;
}
public void onDrawerClosed(View view) {
super.onDrawerClosed(view);
if (listener != null) listener.onDrawerOpened(view);
}
/**
* Called when a drawer has settled in a completely open state.
*/
public void onDrawerOpened(View drawerView) {
super.onDrawerOpened(drawerView);
if (listener != null) listener.onDrawerClosed(drawerView);
}
public enum CacheMode {AUTO, MANUAL}
}