package it.neokree.materialnavigationdrawer;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.annotation.SuppressLint;
import android.app.FragmentTransaction;
import android.content.Intent;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.os.Bundle;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBar;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.widget.Toolbar;
import android.util.TypedValue;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewParent;
import android.view.ViewTreeObserver;
import android.view.Window;
import android.view.WindowManager;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import it.neokree.materialnavigationdrawer.elements.Element;
import it.neokree.materialnavigationdrawer.elements.MaterialAccount;
import it.neokree.materialnavigationdrawer.elements.MaterialSection;
import it.neokree.materialnavigationdrawer.elements.MaterialSubheader;
import it.neokree.materialnavigationdrawer.elements.listeners.MaterialAccountListener;
import it.neokree.materialnavigationdrawer.elements.listeners.MaterialSectionListener;
import it.neokree.materialnavigationdrawer.util.MaterialActionBarDrawerToggle;
import it.neokree.materialnavigationdrawer.util.MaterialDrawerLayout;
import it.neokree.materialnavigationdrawer.util.TypefaceManager;
import it.neokree.materialnavigationdrawer.util.Utils;
/**
* Activity that extends ActionBarActivity with a Navigation Drawer with Material Design style
*
* @author created by neokree
*/
@SuppressWarnings("unused")
@SuppressLint("InflateParams")
public abstract class MaterialNavigationDrawer<Fragment> extends ActionBarActivity implements MaterialSectionListener,MaterialAccount.OnAccountDataLoaded {
// public static final int BOTTOM_SECTION_START = 10000;
private static final int USER_CHANGE_TRANSITION = 500;
public static final int BACKPATTERN_BACK_ANYWHERE = 0;
public static final int BACKPATTERN_BACK_TO_FIRST = 1;
public static final int BACKPATTERN_CUSTOM = 2;
private static final int DRAWERHEADER_ACCOUNTS = 0;
private static final int DRAWERHEADER_IMAGE = 1;
private static final int DRAWERHEADER_CUSTOM = 2;
private static final int DRAWERHEADER_NO_HEADER = 3;
private static final String STATE_SECTION = "MaterialNavigationDrawer_section";
private static final String STATE_LIST = "MaterialNavigationDrawer_list";
private static final String STATE_ACCOUNT = "MaterialNavigationDrawer_account";
private MaterialDrawerLayout layout;
private ActionBar actionBar;
private MaterialActionBarDrawerToggle pulsante;
private ImageView statusBar;
private Toolbar toolbar;
private RelativeLayout content;
private RelativeLayout drawer;
private ImageView userphoto;
private ImageView userSecondPhoto;
private ImageView userThirdPhoto;
private ImageView usercover;
private ImageView usercoverSwitcher;
private TextView username;
private TextView usermail;
private ImageButton userButtonSwitcher;
private LinearLayout customDrawerHeader;
private LinearLayout sections;
private LinearLayout bottomSections;
// Lists
private List<MaterialSection> sectionList;
private List<MaterialSection> bottomSectionList;
private List<MaterialAccount> accountManager;
private List<MaterialSection> accountSectionList;
private List<MaterialSubheader> subheaderList;
private List<Element> elementsList;
private List<Fragment> childFragmentStack;
private List<String> childTitleStack;
// current pointers
private MaterialSection currentSection;
private MaterialAccount currentAccount;
private CharSequence title;
private float density;
private int primaryColor;
private int primaryDarkColor;
private int drawerColor;
private boolean drawerTouchLocked = false;
private boolean slidingDrawerEffect = false;
private boolean multiPaneSupport;
private boolean rippleSupport;
private boolean uniqueToolbarColor;
private boolean singleAccount;
private boolean accountSwitcher = false;
private boolean isCurrentFragmentChild = false;
private boolean kitkatTraslucentStatusbar = false;
private static boolean learningPattern = true;
private int backPattern = BACKPATTERN_BACK_ANYWHERE;
private int drawerHeaderType;
private int defaultSectionLoaded = 0;
private boolean toolbarElevation;
// resources
private Resources resources;
private TypefaceManager fontManager;
// listeners
private View.OnClickListener currentAccountListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!drawerTouchLocked) {
// enter into account properties
if (accountListener != null) {
accountListener.onAccountOpening(currentAccount);
}
// close drawer
if (!deviceSupportMultiPane())
layout.closeDrawer(drawer);
}
}
};
private View.OnClickListener secondAccountListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!drawerTouchLocked) {
// account change
MaterialAccount account = findAccountNumber(MaterialAccount.SECOND_ACCOUNT);
if (account != null) {
if (accountListener != null)
accountListener.onChangeAccount(account);
switchAccounts(account);
} else {// if there is no second account user clicked for open it
if(accountSwitcherListener != null && !singleAccount)
accountSwitcherListener.onClick(null);
}
}
}
};
private View.OnClickListener thirdAccountListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!drawerTouchLocked) {
// account change
MaterialAccount account = findAccountNumber(MaterialAccount.THIRD_ACCOUNT);
if (account != null) {
if (accountListener != null)
accountListener.onChangeAccount(account);
switchAccounts(account);
} else {// if there is no second account user clicked for open it
if(accountSwitcherListener != null && !singleAccount)
accountSwitcherListener.onClick(null);
}
}
}
};
private View.OnClickListener accountSwitcherListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(!drawerTouchLocked) {
// si rimuovono le viste || Views are removed
sections.removeAllViews();
bottomSections.removeAllViews();
if (!accountSwitcher) {
// si cambia l'icona del pulsante || Change the icon of the button
userButtonSwitcher.setImageResource(R.drawable.ic_arrow_drop_up_white_24dp);
for (MaterialAccount account : accountManager) {
// si inseriscono tutti gli account ma non quello attualmente in uso || Add all account without the current one
if(account.getAccountNumber() != MaterialAccount.FIRST_ACCOUNT) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (56 * density));
sections.addView(account.getSectionView(MaterialNavigationDrawer.this, fontManager.getRobotoMedium(),accountSectionListener,rippleSupport,account.getAccountNumber()),params);
}
}
for (MaterialSection section : accountSectionList) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (48 * density));
sections.addView(section.getView(), params);
}
// si attiva l'account switcher per annotare che si visualizzano gli account. || accountSwitcher is enabled for checking the account list is showed.
accountSwitcher = true;
} else {
userButtonSwitcher.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp);
int indexSection = 0 ,indexSubheader = 0;
for(Element element : elementsList) {
switch(element.getType()) {
case Element.TYPE_SECTION:
MaterialSection section = sectionList.get(indexSection);
indexSection++;
LinearLayout.LayoutParams paramSection = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (48 * density));
sections.addView(section.getView(), paramSection);
break;
case Element.TYPE_DIVISOR:
View view = new View(MaterialNavigationDrawer.this);
view.setBackgroundColor(Color.parseColor("#8f8f8f"));
// height 1 px
LinearLayout.LayoutParams paramDivisor = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,1);
paramDivisor.setMargins(0,(int) (8 * density), 0 , (int) (8 * density));
sections.addView(view,paramDivisor);
break;
case Element.TYPE_SUBHEADER:
MaterialSubheader subheader = subheaderList.get(indexSubheader);
indexSubheader++;
sections.addView(subheader.getView());
break;
case Element.TYPE_BOTTOM_SECTION:
break; // le bottom section vengono gestite dopo l'inserimento degli altri elementi
}
}
int width = drawer.getWidth();
int heightCover = 0;
switch(drawerHeaderType) {
default:
case DRAWERHEADER_ACCOUNTS:
case DRAWERHEADER_IMAGE:
case DRAWERHEADER_CUSTOM:
// si fa il rapporto in 16 : 9 || 16:9 rate
heightCover = (9 * width) / 16;
break;
case DRAWERHEADER_NO_HEADER:
break;
}
// adding status bar height
if(Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP) {
heightCover += (int) (24 * density); // on lollipop status bar is only 24 dp height
}
else {
heightCover += (int) (25 * density);
}
int heightDrawer = (int) (( ( 8 + 8 ) * density ) + 1 + heightCover + sections.getHeight() + ((density * 48) * bottomSectionList.size()) + (subheaderList.size() * (35 * density)));
View divisor = new View(MaterialNavigationDrawer.this);
divisor.setBackgroundColor(Color.parseColor("#8f8f8f"));
// si aggiungono le bottom sections
if (heightDrawer >= Utils.getScreenHeight(MaterialNavigationDrawer.this)) {
LinearLayout.LayoutParams paramDivisor = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,1);
paramDivisor.setMargins(0,(int) (8 * density), 0 , (int) (8 * density));
sections.addView(divisor,paramDivisor);
for (MaterialSection section : bottomSectionList) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (48 * density));
sections.addView(section.getView(), params);
}
} else {
LinearLayout.LayoutParams paramDivisor = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,1);
bottomSections.addView(divisor,paramDivisor);
for (MaterialSection section : bottomSectionList) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (48 * density));
bottomSections.addView(section.getView(), params);
}
}
accountSwitcher = false;
}
}
}
};
private MaterialSectionListener accountSectionListener = new MaterialSectionListener() {
@Override
public void onClick(MaterialSection section) {
section.unSelect(); // remove the selected color
if(!drawerTouchLocked) {
int accountPosition = section.getAccountPosition();
MaterialAccount account = findAccountNumber(accountPosition);
// switch accounts position
currentAccount.setAccountNumber(accountPosition);
account.setAccountNumber(MaterialAccount.FIRST_ACCOUNT);
currentAccount = account;
notifyAccountDataChanged();
// call change account method
if (accountListener != null)
accountListener.onChangeAccount(account);
// change account list
accountSwitcherListener.onClick(null);
// close drawer
if (!deviceSupportMultiPane())
layout.closeDrawer(drawer);
}
}
};
private View.OnClickListener toolbarToggleListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
if(isCurrentFragmentChild) {
onHomeAsUpSelected();
onBackPressed();
}
}
};
private MaterialAccountListener accountListener;
private DrawerLayout.DrawerListener drawerListener;
@SuppressWarnings("unchecked")
@Override
/**
* Do not Override this method!!! <br>
* Use init() instead
*/
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Resources.Theme theme = this.getTheme();
TypedValue typedValue = new TypedValue();
theme.resolveAttribute(R.attr.drawerType,typedValue,true);
drawerHeaderType = typedValue.data;
theme.resolveAttribute(R.attr.rippleBackport,typedValue,false);
rippleSupport = typedValue.data != 0;
theme.resolveAttribute(R.attr.uniqueToolbarColor,typedValue,false);
uniqueToolbarColor = typedValue.data != 0;
theme.resolveAttribute(R.attr.singleAccount,typedValue,false);
singleAccount = typedValue.data != 0;
theme.resolveAttribute(R.attr.multipaneSupport,typedValue,false);
multiPaneSupport = typedValue.data != 0;
theme.resolveAttribute(R.attr.learningPattern,typedValue,false);
learningPattern = typedValue.data != 0;
theme.resolveAttribute(R.attr.drawerColor,typedValue,true);
drawerColor = typedValue.data;
theme.resolveAttribute(R.attr.defaultSectionLoaded,typedValue,true);
defaultSectionLoaded = typedValue.data;
theme.resolveAttribute(R.attr.toolbarElevation, typedValue, false);
toolbarElevation = typedValue.data != 0;
if(drawerHeaderType == DRAWERHEADER_ACCOUNTS)
super.setContentView(R.layout.activity_material_navigation_drawer);
else
super.setContentView(R.layout.activity_material_navigation_drawer_customheader);
// init Typeface
fontManager = new TypefaceManager(this.getAssets());
// init toolbar & status bar
statusBar = (ImageView) findViewById(R.id.statusBar);
toolbar = (Toolbar) findViewById(R.id.toolbar);
// init drawer components
layout = (MaterialDrawerLayout) this.findViewById(R.id.drawer_layout);
content = (RelativeLayout) this.findViewById(R.id.content);
drawer = (RelativeLayout) this.findViewById(R.id.drawer);
if(drawerHeaderType == DRAWERHEADER_ACCOUNTS) {
username = (TextView) this.findViewById(R.id.user_nome);
usermail = (TextView) this.findViewById(R.id.user_email);
userphoto = (ImageView) this.findViewById(R.id.user_photo);
userSecondPhoto = (ImageView) this.findViewById(R.id.user_photo_2);
userThirdPhoto = (ImageView) this.findViewById(R.id.user_photo_3);
usercover = (ImageView) this.findViewById(R.id.user_cover);
usercoverSwitcher = (ImageView) this.findViewById(R.id.user_cover_switcher);
userButtonSwitcher = (ImageButton) this.findViewById(R.id.user_switcher);
// set Roboto Fonts
username.setTypeface(fontManager.getRobotoMedium());
usermail.setTypeface(fontManager.getRobotoRegular());
// get and set username and mail text colors
theme.resolveAttribute(R.attr.accountStyle,typedValue,true);
TypedArray attributes = theme.obtainStyledAttributes(typedValue.resourceId,R.styleable.MaterialAccount);
try {
username.setTextColor(attributes.getColor(R.styleable.MaterialAccount_titleColor,0xFFF));
usermail.setTextColor(attributes.getColor(R.styleable.MaterialAccount_subtitleColor,0xFFF));
}
finally {
attributes.recycle();
}
// set the button image
if(!singleAccount) {
userButtonSwitcher.setImageResource(R.drawable.ic_arrow_drop_down_white_24dp);
userButtonSwitcher.setOnClickListener(accountSwitcherListener);
}
}
else
customDrawerHeader = (LinearLayout) this.findViewById(R.id.drawer_header);
sections = (LinearLayout) this.findViewById(R.id.sections);
bottomSections = (LinearLayout) this.findViewById(R.id.bottom_sections);
// init lists
sectionList = new LinkedList<>();
bottomSectionList = new LinkedList<>();
accountManager = new LinkedList<>();
accountSectionList = new LinkedList<>();
subheaderList = new LinkedList<>();
elementsList = new LinkedList<>();
childFragmentStack = new LinkedList<>();
childTitleStack = new LinkedList<>();
// init listeners
if(drawerHeaderType == DRAWERHEADER_ACCOUNTS) {
userphoto.setOnClickListener(currentAccountListener);
if(singleAccount)
usercover.setOnClickListener(currentAccountListener);
else
usercover.setOnClickListener(accountSwitcherListener);
userSecondPhoto.setOnClickListener(secondAccountListener);
userThirdPhoto.setOnClickListener(thirdAccountListener);
}
// set drawer backgrond color
drawer.setBackgroundColor(drawerColor);
//get resources and density
resources = this.getResources();
density = resources.getDisplayMetrics().density;
// set the right drawer width
DrawerLayout.LayoutParams drawerParams = (android.support.v4.widget.DrawerLayout.LayoutParams) drawer.getLayoutParams();
drawerParams.width = Utils.getDrawerWidth(resources);
drawer.setLayoutParams(drawerParams);
// get primary color
theme.resolveAttribute(R.attr.colorPrimary, typedValue, true);
primaryColor = typedValue.data;
theme.resolveAttribute(R.attr.colorPrimaryDark, typedValue, true);
primaryDarkColor = typedValue.data;
// if device is kitkat
if(Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT) {
TypedArray windowTraslucentAttribute = theme.obtainStyledAttributes(new int[]{android.R.attr.windowTranslucentStatus});
kitkatTraslucentStatusbar = windowTraslucentAttribute.getBoolean(0, false);
if(kitkatTraslucentStatusbar) {
Window window = this.getWindow();
window.setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS,
WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
RelativeLayout.LayoutParams statusParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, resources.getDimensionPixelSize(R.dimen.traslucentStatusMargin));
statusBar.setLayoutParams(statusParams);
statusBar.setImageDrawable(new ColorDrawable(darkenColor(primaryColor)));
if(drawerHeaderType == DRAWERHEADER_ACCOUNTS) {
RelativeLayout.LayoutParams photoParams = (RelativeLayout.LayoutParams) userphoto.getLayoutParams();
photoParams.setMargins((int) (16 * density), resources.getDimensionPixelSize(R.dimen.traslucentPhotoMarginTop), 0, 0);
userphoto.setLayoutParams(photoParams);
}
}
}
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
getWindow().getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN);
}
// INIT TOOLBAR ELEVATION
if (toolbarElevation) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 4 dp elevation
toolbar.setElevation(4 * density);
}
else {
View elevation = LayoutInflater.from(this).inflate(R.layout.layout_toolbar_elevation,content, false);
content.addView(elevation);
}
}
// INIT ACTION BAR
this.setSupportActionBar(toolbar);
actionBar = getSupportActionBar();
// DEVELOPER CALL TO INIT
init(savedInstanceState);
if(sectionList.size() == 0) {
throw new RuntimeException("You must add at least one Section to top list.");
}
if(deviceSupportMultiPane()) {
// se il multipane e' attivo, si e' in landscape e si e' un tablet allora si passa in multipane mode
layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN,drawer);
DrawerLayout.LayoutParams params = new DrawerLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
params.setMargins((int) (320 * density),0,0,0);
content.setLayoutParams(params);
layout.setScrimColor(Color.TRANSPARENT);
layout.openDrawer(drawer);
layout.setMultipaneSupport(true);
}
else {
// se non si sta lavorando in multiPane allora si inserisce il pulsante per aprire/chiudere
actionBar.setDisplayHomeAsUpEnabled(true);
actionBar.setHomeButtonEnabled(true);
pulsante = new MaterialActionBarDrawerToggle<Fragment>(this,layout,toolbar,R.string.nothing,R.string.nothing) {
@Override
public void onDrawerClosed(View view) {
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
// abilita il touch del drawer
setDrawerTouchable(true);
if(drawerListener != null)
drawerListener.onDrawerClosed(view);
if(hasRequest()) {
MaterialSection section = getRequestedSection();
changeToolbarColor(section);
setFragment((Fragment) section.getTargetFragment(), section.getTitle(), (Fragment) currentSection.getTargetFragment());
afterFragmentSetted((Fragment) section.getTargetFragment(),section.getTitle());
this.removeRequest();
}
}
@Override
public void onDrawerOpened(View drawerView) {
invalidateOptionsMenu(); // creates call to onPrepareOptionsMenu()
if(drawerListener != null)
drawerListener.onDrawerOpened(drawerView);
}
@Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// if user wants the sliding arrow it compare
if (slidingDrawerEffect)
super.onDrawerSlide(drawerView, slideOffset);
else
super.onDrawerSlide(drawerView, 0);
if(drawerListener != null)
drawerListener.onDrawerSlide(drawerView,slideOffset);
}
@Override
public void onDrawerStateChanged(int newState) {
super.onDrawerStateChanged(newState);
if(drawerListener != null)
drawerListener.onDrawerStateChanged(newState);
}
};
pulsante.setToolbarNavigationClickListener(toolbarToggleListener);
layout.setDrawerListener(pulsante);
layout.setMultipaneSupport(false);
}
// si procede con gli altri elementi dopo la creazione delle viste
ViewTreeObserver vto = drawer.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
// quando l'immagine e' stata caricata
// change user space to 16:9
int width = drawer.getWidth();
int heightCover = 0;
switch(drawerHeaderType) {
default:
case DRAWERHEADER_ACCOUNTS:
case DRAWERHEADER_IMAGE:
case DRAWERHEADER_CUSTOM:
// si fa il rapporto in 16 : 9
heightCover = (9 * width) / 16;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
heightCover += (int) (24 * density);
if(Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT && kitkatTraslucentStatusbar)
heightCover += (int) (25 * density);
break;
case DRAWERHEADER_NO_HEADER:
break;
}
// set user space
if(drawerHeaderType == DRAWERHEADER_ACCOUNTS) {
usercover.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, heightCover));
usercoverSwitcher.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, heightCover));
}
else {
customDrawerHeader.setLayoutParams(new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.MATCH_PARENT, heightCover));
}
// adding status bar height for other version of android that not have traslucent status bar
if((Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT && !kitkatTraslucentStatusbar) || Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT ) {
heightCover += (int) (25 * density);
}
// heightCover (DRAWER HEADER) + 8 (PADDING) + sections + 8 (PADDING) + 1 (DIVISOR) + bottomSections + subheaders
int heightDrawer = (int) (( ( 8 + 8 ) * density ) + 1 + heightCover + sections.getHeight() + ((density * 48) * bottomSectionList.size()) + (subheaderList.size() * (35 * density)));
// create the divisor
View divisor = new View(MaterialNavigationDrawer.this);
divisor.setBackgroundColor(Color.parseColor("#8f8f8f"));
// si aggiungono le bottom sections
if(heightDrawer >= Utils.getScreenHeight(MaterialNavigationDrawer.this)) {
// add the divisor to the section view
LinearLayout.LayoutParams paramDivisor = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,1);
paramDivisor.setMargins(0,(int) (8 * density), 0 , (int) (8 * density));
sections.addView(divisor,paramDivisor);
for (MaterialSection section : bottomSectionList) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (48 * density));
sections.addView(section.getView(), params);
}
}
else {
// add the divisor to the bottom section listview
LinearLayout.LayoutParams paramDivisor = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,1);
bottomSections.addView(divisor,paramDivisor);
for (MaterialSection section : bottomSectionList) {
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, (int) (48 * density));
bottomSections.addView(section.getView(), params);
}
}
ViewTreeObserver obs = drawer.getViewTreeObserver();
// si rimuove il listener
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
obs.removeOnGlobalLayoutListener(this);
} else {
obs.removeGlobalOnLayoutListener(this);
}
}
});
MaterialSection section;
if (savedInstanceState == null) {
// init account views
if(accountManager.size() > 0) {
currentAccount = accountManager.get(0);
notifyAccountDataChanged();
}
// init section
if(defaultSectionLoaded < 0 || defaultSectionLoaded >= sectionList.size()) {
throw new RuntimeException("You are trying to open at startup a section that does not exist");
}
section = sectionList.get(defaultSectionLoaded);
if(section.getTarget() != MaterialSection.TARGET_FRAGMENT)
throw new RuntimeException("The first section added must have a fragment as target");
}
else {
ArrayList<Integer> accountNumbers = savedInstanceState.getIntegerArrayList(STATE_ACCOUNT);
// ripristina gli account | restore accounts
for(int i = 0; i< accountNumbers.size(); i++) {
MaterialAccount account = accountManager.get(i);
account.setAccountNumber(accountNumbers.get(i));
if(account.getAccountNumber() == MaterialAccount.FIRST_ACCOUNT) {
currentAccount = account;
}
}
notifyAccountDataChanged();
int sectionSelected = savedInstanceState.getInt(STATE_SECTION);
int sectionListType = savedInstanceState.getInt(STATE_LIST);
if(sectionListType == Element.TYPE_SECTION) {
section = sectionList.get(sectionSelected);
}
else
section = bottomSectionList.get(sectionSelected);
if(section.getTarget() != MaterialSection.TARGET_FRAGMENT) {
section = sectionList.get(0);
}
}
title = section.getTitle();
currentSection = section;
section.select();
setFragment((Fragment) section.getTargetFragment(), section.getTitle(), null,savedInstanceState != null);
// change the toolbar color for the first section
changeToolbarColor(section);
// add the first section to the child stack
childFragmentStack.add((Fragment) section.getTargetFragment());
childTitleStack.add(section.getTitle());
// learning pattern
if(learningPattern) {
layout.openDrawer(drawer);
disableLearningPattern();
}
}
@Override
protected void onResume() {
super.onResume();
if(!deviceSupportMultiPane())
layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED, drawer);
else
layout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_OPEN, drawer);
}
@Override
public void setContentView(View view) {
throw new RuntimeException("The library have it's own content, please move all content inside section's fragments");
//super.setContentView(view);
}
@Override
public void setContentView(int layoutResID) {
throw new RuntimeException("The library have it's own content, please move all content inside section's fragments");
//super.setContentView(layoutResID);
}
@Override
public void setContentView(View view, ViewGroup.LayoutParams params) {
throw new RuntimeException("The library have it's own content, please move all content inside section's fragments");
//super.setContentView(view, params);
}
// Gestione dei Menu -----------------------------------------------------------------------------------------------------------------------------
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
return super.onCreateOptionsMenu(menu);
}
/* Chiamata dopo l'invalidateOptionsMenu() */
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if(layout.isDrawerOpen(drawer) && !deviceSupportMultiPane()) {
menu.clear();
}
return super.onPrepareOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Se dal drawer si seleziona un oggetto
if(!deviceSupportMultiPane()) {
if (pulsante.onOptionsItemSelected(item)) {
return true;
}
}
else {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
toolbarToggleListener.onClick(null);
return true;
}
}
return super.onOptionsItemSelected(item);
}
//------------------------------------------------------------------------------------------------------------------------------------------------
@Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
if(pulsante != null )
pulsante.syncState();
}
@Override
public void onConfigurationChanged(Configuration newConfig) {// al cambio di orientamento dello schermo
super.onConfigurationChanged(newConfig);
// Passa tutte le configurazioni al drawer
if(pulsante != null ) {
pulsante.onConfigurationChanged(newConfig);
}
}
@Override
public void setTitle(CharSequence title) {
this.title = title;
this.getSupportActionBar().setTitle(title);
}
@Override
public void onBackPressed() {
if(!isCurrentFragmentChild) {
switch (backPattern) {
default:
case BACKPATTERN_BACK_ANYWHERE:
super.onBackPressed();
break;
case BACKPATTERN_BACK_TO_FIRST:
MaterialSection section = sectionList.get(0);
if (currentSection == section)
super.onBackPressed();
else {
section.select();
//onClick(section);
changeToolbarColor(section);
setFragment((Fragment) section.getTargetFragment(), section.getTitle(), (Fragment) currentSection.getTargetFragment());
afterFragmentSetted((Fragment) section.getTargetFragment(),section.getTitle());
syncSectionsState(section);
}
break;
case BACKPATTERN_CUSTOM:
MaterialSection backedSection = backToSection(getCurrentSection());
if (currentSection == backedSection)
super.onBackPressed();
else {
if (backedSection.getTarget() != MaterialSection.TARGET_FRAGMENT) {
throw new RuntimeException("The restored section must have a fragment as target");
}
backedSection.select();
changeToolbarColor(backedSection);
setFragment((Fragment) backedSection.getTargetFragment(), backedSection.getTitle(), (Fragment) currentSection.getTargetFragment());
afterFragmentSetted((Fragment) backedSection.getTargetFragment(),backedSection.getTitle());
syncSectionsState(backedSection);
}
break;
}
}
else {
if(childFragmentStack.size() <= 1) {
isCurrentFragmentChild = false;
onBackPressed();
}
else {
// reload the child before
Fragment newFragment = childFragmentStack.get(childFragmentStack.size() - 2);
String newTitle = childTitleStack.get(childTitleStack.size() - 2);
// get and remove the last child
Fragment currentFragment = childFragmentStack.remove(childFragmentStack.size() - 1);
childTitleStack.remove(childTitleStack.size() - 1);
setFragment(newFragment,newTitle,currentFragment);
if(childFragmentStack.size() == 1) {
// user comed back to master section
isCurrentFragmentChild = false;
if(!deviceSupportMultiPane())
pulsante.setDrawerIndicatorEnabled(true);
else
actionBar.setDisplayHomeAsUpEnabled(false);
}
}
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
int position = 0;
int type = 0;
Element e = findElementBySection(currentSection);
switch (e.getType()) {
default:
case Element.TYPE_SECTION:
position = sectionList.indexOf(currentSection);
break;
case Element.TYPE_BOTTOM_SECTION:
position = bottomSectionList.indexOf(currentSection);
break;
}
type = e.getType();
outState.putInt(STATE_LIST,type);
outState.putInt(STATE_SECTION,position);
ArrayList<Integer> list = new ArrayList<>();
for(MaterialAccount account : accountManager)
list.add(account.getAccountNumber());
outState.putIntegerArrayList(STATE_ACCOUNT,list);
super.onSaveInstanceState(outState);
}
@Override
protected void onDestroy() {
super.onDestroy();
// recycle bitmaps
recycleAccounts();
}
/**
* Method used with BACKPATTERN_CUSTOM to retrieve the section which is restored
* @param currentSection the section used at this time
* @return the Section to restore that has Fragment as target (or currentSection for exit from activity)
*/
protected MaterialSection backToSection(MaterialSection currentSection) {
return currentSection;
}
/**
* Set the section informations.<br />
* In short:
* <ul>
* <li>set the section title into the toolbar</li>
* <li>set the section color to the toolbar</li>
* <li>open/call the target</li>
* </ul>
*
* This method is equal to a user tap on a drawer section.
* @param section the section which is replaced
*/
public void setSection(MaterialSection section) {
section.select();
syncSectionsState(section);
switch (section.getTarget()) {
case MaterialSection.TARGET_FRAGMENT:
// se l'utente clicca sulla stessa schermata in cui si trova si chiude il drawer e basta
if(section == currentSection) {
if(!deviceSupportMultiPane())
layout.closeDrawer(drawer);
return;
}
changeToolbarColor(section);
setFragment((Fragment) section.getTargetFragment(), section.getTitle(), (Fragment) currentSection.getTargetFragment());
afterFragmentSetted((Fragment) section.getTargetFragment(),section.getTitle());
break;
case MaterialSection.TARGET_ACTIVITY:
this.startActivity(section.getTargetIntent());
if (!deviceSupportMultiPane())
layout.closeDrawer(drawer);
break;
case MaterialSection.TARGET_LISTENER:
// call the section listener
section.getTargetListener().onClick(section);
if (!deviceSupportMultiPane())
layout.closeDrawer(drawer);
default:
break;
}
// se il target e' un activity la sezione corrente rimane quella precedente
if(section.getTarget() != MaterialSection.TARGET_ACTIVITY ) {
syncSectionsState(section);
}
}
/**
* Set the fragment to the activity content.<br />
* N.B. If you want to support the master/child flow, please consider to use setFragmentChild instead
*
* @param fragment to replace into the main content
* @param title to set into Toolbar
*/
public void setFragment(Fragment fragment,String title) {
setFragment(fragment,title,null);
if(!isCurrentFragmentChild) {// remove the last child from the stack
childFragmentStack.remove(childFragmentStack.size() - 1);
childTitleStack.remove(childTitleStack.size() - 1);
}
else for(int i = childFragmentStack.size()-1; i >= 0;i--) { // if a section is clicked when user is into a child remove all childs from stack
childFragmentStack.remove(i);
childTitleStack.remove(i);
}
// add to the childStack the Fragment and title
childFragmentStack.add(fragment);
childTitleStack.add(title);
isCurrentFragmentChild = false;
}
private void setFragment(Fragment fragment,String title, Fragment oldFragment) {
setFragment(fragment,title,oldFragment,false);
}
private void setFragment(Fragment fragment,String title,Fragment oldFragment,boolean hasSavedInstanceState) {
// si setta il titolo
setTitle(title);
if(Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
// before honeycomb there is not android.app.Fragment
if(!hasSavedInstanceState) {
android.support.v4.app.FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if (oldFragment != null && oldFragment != fragment)
ft.remove((android.support.v4.app.Fragment) oldFragment);
ft.replace(R.id.frame_container, (android.support.v4.app.Fragment) fragment).commit();
}
}
else if (fragment instanceof android.app.Fragment) {
if (oldFragment instanceof android.support.v4.app.Fragment)
throw new RuntimeException("You should use only one type of Fragment");
if(!hasSavedInstanceState) {// se non e' avvenuta una rotazione
FragmentTransaction ft = getFragmentManager().beginTransaction();
if (oldFragment != null && fragment != oldFragment)
ft.remove((android.app.Fragment) oldFragment);
ft.replace(R.id.frame_container, (android.app.Fragment) fragment).commit();
}
}
else if(fragment instanceof android.support.v4.app.Fragment) {
if(oldFragment instanceof android.app.Fragment)
throw new RuntimeException("You should use only one type of Fragment");
android.support.v4.app.FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
if(oldFragment != null && oldFragment != fragment)
ft.remove((android.support.v4.app.Fragment) oldFragment);
if(!hasSavedInstanceState) // se non e' avvenuta una rotazione
ft.replace(R.id.frame_container, (android.support.v4.app.Fragment) fragment).commit();
}
else
throw new RuntimeException("Fragment must be android.app.Fragment or android.support.v4.app.Fragment");
}
private void afterFragmentSetted(Fragment fragment,String title) {
// remove the last child from the stack
if(!isCurrentFragmentChild) {
childFragmentStack.remove(childFragmentStack.size() - 1);
childTitleStack.remove(childTitleStack.size() - 1);
}
else for(int i = childFragmentStack.size()-1;i >= 0;i--) { // if a section is clicked when user is into a child remove all childs from stack
childFragmentStack.remove(i);
childTitleStack.remove(i);
}
// add to the childStack the Fragment and title
childFragmentStack.add(fragment);
childTitleStack.add(title);
isCurrentFragmentChild = false;
if(!deviceSupportMultiPane())
pulsante.setDrawerIndicatorEnabled(true);
else {
actionBar.setDisplayHomeAsUpEnabled(false);
}
}
public void setFragmentChild(Fragment fragment,String title) {
isCurrentFragmentChild = true;
// replace the fragment
setFragment(fragment,title,childFragmentStack.get(childFragmentStack.size() - 1));
// add to the stack the child
childFragmentStack.add(fragment);
childTitleStack.add(title);
// sync the toolbar toggle state
if(!deviceSupportMultiPane())
pulsante.setDrawerIndicatorEnabled(false);
else {
actionBar.setDisplayHomeAsUpEnabled(true);
}
}
// private methods
private MaterialAccount findAccountNumber(int number) {
for(MaterialAccount account : accountManager)
if(account.getAccountNumber() == number)
return account;
return null;
}
private Element findElementBySection(MaterialSection section) {
for(Element element : elementsList)
if (element.getElement() == section)
return element;
return null;
}
private void switchAccounts(final MaterialAccount newAccount) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
final ImageView floatingImage = new ImageView(this);
// si calcolano i rettangoli di inizio e fine
Rect startingRect = new Rect();
Rect finalRect = new Rect();
Point offsetHover = new Point();
// 64dp primary user image / 40dp other user image = 1.6 scale
float finalScale = 1.6f;
final int statusBarHeight;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT || (Build.VERSION.SDK_INT == Build.VERSION_CODES.KITKAT && !kitkatTraslucentStatusbar)) {
statusBarHeight = (int) (25 * density);
} else {
statusBarHeight = 0;
}
// si tiene traccia della foto cliccata
ImageView photoClicked;
if (newAccount.getAccountNumber() == MaterialAccount.SECOND_ACCOUNT) {
photoClicked = userSecondPhoto;
} else {
photoClicked = userThirdPhoto;
}
photoClicked.getGlobalVisibleRect(startingRect, offsetHover);
floatingImage.setImageDrawable(photoClicked.getDrawable());
// si aggiunge una view nell'esatta posizione dell'altra
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(photoClicked.getWidth(), photoClicked.getHeight());
params.setMargins(offsetHover.x, offsetHover.y - statusBarHeight, 0, 0);
drawer.addView(floatingImage, params);
// si setta la nuova foto di profilo sopra alla vecchia
photoClicked.setImageDrawable(currentAccount.getCircularPhoto());
// si setta la nuova immagine di background da visualizzare sotto la vecchia
usercoverSwitcher.setImageDrawable(newAccount.getBackground());
userphoto.getGlobalVisibleRect(finalRect);
// Si calcola l'offset finale (LARGHEZZA DEL CONTAINER GRANDE - LARGHEZZA DEL CONTAINER PICCOLO / 2) e lo si applica
int offset = (((finalRect.bottom - finalRect.top) - (startingRect.bottom - finalRect.top)) / 2);
finalRect.offset(offset, offset - statusBarHeight);
startingRect.offset(0, -statusBarHeight);
// Se il dispositivo usa un linguaggio RTL si rimuove l'offset della parte a sinistra dello schermo
if(Utils.isRTL()) {
// si rimuove dal conteggio la parte a sinistra del drawer.
int leftOffset = resources.getDisplayMetrics().widthPixels - Utils.getDrawerWidth(resources);
startingRect.left -= leftOffset;
finalRect.left -= leftOffset;
}
// si animano le viste
AnimatorSet set = new AnimatorSet();
set
// si ingrandisce l'immagine e la si sposta a sinistra.
.play(ObjectAnimator.ofFloat(floatingImage, View.X, startingRect.left, finalRect.left))
.with(ObjectAnimator.ofFloat(floatingImage, View.Y, startingRect.top, finalRect.top))
.with(ObjectAnimator.ofFloat(floatingImage, View.SCALE_X, 1f, finalScale))
.with(ObjectAnimator.ofFloat(floatingImage, View.SCALE_Y, 1f, finalScale))
.with(ObjectAnimator.ofFloat(userphoto, View.ALPHA, 1f, 0f))
.with(ObjectAnimator.ofFloat(usercover, View.ALPHA, 1f, 0f))
.with(ObjectAnimator.ofFloat(photoClicked, View.SCALE_X, 0f, 1f))
.with(ObjectAnimator.ofFloat(photoClicked, View.SCALE_Y, 0f, 1f));
set.setDuration(USER_CHANGE_TRANSITION);
set.setInterpolator(new DecelerateInterpolator());
set.addListener(new AnimatorListenerAdapter() {
@SuppressLint("NewApi")
@Override
public void onAnimationEnd(Animator animation) {
// si carica la nuova immagine
((View) userphoto).setAlpha(1);
setFirstAccountPhoto(newAccount.getCircularPhoto());
// si cancella l'imageview per l'effetto
drawer.removeView(floatingImage);
// si cambiano i dati utente
setUserEmail(newAccount.getSubTitle());
setUsername(newAccount.getTitle());
// si cambia l'immagine soprastante
setDrawerHeaderImage(newAccount.getBackground());
// si fa tornare il contenuto della cover visibile (ma l'utente non nota nulla)
((View) usercover).setAlpha(1);
// switch numbers
currentAccount.setAccountNumber(newAccount.getAccountNumber());
newAccount.setAccountNumber(MaterialAccount.FIRST_ACCOUNT);
// change pointer to newAccount
currentAccount = newAccount;
// si chiude il drawer
if (!deviceSupportMultiPane())
layout.closeDrawer(drawer);
}
@Override
public void onAnimationCancel(Animator animation) {
// se si annulla l'animazione si conclude e basta.
onAnimationEnd(animation);
}
});
set.start();
}
else {
// for minor version no animation is used.
// switch numbers
currentAccount.setAccountNumber(newAccount.getAccountNumber());
newAccount.setAccountNumber(MaterialAccount.FIRST_ACCOUNT);
// change pointer to newAccount
currentAccount = newAccount;
// refresh views
notifyAccountDataChanged();
if (!deviceSupportMultiPane())
layout.closeDrawer(drawer);
}
}
private boolean deviceSupportMultiPane() {
if(multiPaneSupport && resources.getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE && Utils.isTablet(resources))
return true;
else
return false;
}
private void setDrawerTouchable(boolean isTouchable) {
drawerTouchLocked = !isTouchable;
for(MaterialSection section : sectionList) {
section.setTouchable(isTouchable);
}
for(MaterialSection section : bottomSectionList) {
section.setTouchable(isTouchable);
}
}
private void recycleAccounts() {
for(MaterialAccount account : accountManager) {
account.recycle();
}
}
private void syncSectionsState(MaterialSection section) {
currentSection = section;
// search in first list
int position = sectionList.indexOf(section);
if(position != -1) {
for (int i = 0;i < sectionList.size();i++)
if(i != position)
sectionList.get(i).unSelect();
}
else {
// section is a bottom section
position = bottomSectionList.indexOf(section);
for (int i = 0;i < bottomSectionList.size();i++)
if(i != position)
bottomSectionList.get(i).unSelect();
}
}
protected int darkenColor(int color) {
if(color == primaryColor)
return primaryDarkColor;
float[] hsv = new float[3];
Color.colorToHSV(color, hsv);
hsv[2] *= 0.8f; // value component
return Color.HSVToColor(hsv);
}
@Override
public void onClick(MaterialSection section) {
switch (section.getTarget()) {
case MaterialSection.TARGET_FRAGMENT:
// se l'utente clicca sulla stessa schermata in cui si trova si chiude il drawer e basta
if(section == currentSection) {
layout.closeDrawer(drawer);
return;
}
if(deviceSupportMultiPane()) {
changeToolbarColor(section);
setFragment((Fragment) section.getTargetFragment(), section.getTitle(), (Fragment) currentSection.getTargetFragment());
afterFragmentSetted((Fragment) section.getTargetFragment(),section.getTitle());
}
else {
// si disattiva il touch sul drawer
setDrawerTouchable(false);
// la chiamata al fragment viene spostata dopo la chiusura del drawer
pulsante.addRequest(section);
layout.closeDrawer(drawer);
}
break;
case MaterialSection.TARGET_ACTIVITY:
this.startActivity(section.getTargetIntent());
if (!deviceSupportMultiPane())
layout.closeDrawer(drawer);
break;
// TARGET_LISTENER viene gestito internamente
case MaterialSection.TARGET_LISTENER:
if (!deviceSupportMultiPane())
layout.closeDrawer(drawer);
if (!deviceSupportMultiPane()) {
setDrawerTouchable(false);
}
default:
break;
}
// se il target e' un activity la sezione corrente rimane quella precedente
if(section.getTarget() != MaterialSection.TARGET_ACTIVITY ) {
syncSectionsState(section);
}
}
@Override
public void onUserPhotoLoaded(MaterialAccount account) {
if(account.getAccountNumber() <= MaterialAccount.THIRD_ACCOUNT)
notifyAccountDataChanged();
}
@Override
public void onBackgroundLoaded(MaterialAccount account) {
if(account.getAccountNumber() <= MaterialAccount.THIRD_ACCOUNT)
notifyAccountDataChanged();
}
// method used for change supports
public void setAccountListener(MaterialAccountListener listener) {
this.accountListener = listener;
}
public void setDrawerListener(DrawerLayout.DrawerListener listener) {
this.drawerListener = listener;
}
public void addMultiPaneSupport() {
this.multiPaneSupport = true;
}
public void allowArrowAnimation() {
slidingDrawerEffect = true;
}
public void disableLearningPattern() {
learningPattern = false;
}
public void enableToolbarElevation() {
if (!toolbarElevation) {
toolbarElevation = true;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 4 dp elevation
toolbar.setElevation(4 * density);
}
else {
View elevation = LayoutInflater.from(this).inflate(R.layout.layout_toolbar_elevation,content, false);
content.addView(elevation);
}
}
}
/**
* Set the HomeAsUpIndicator that is visible when user navigate to a fragment child
*
* N.B. call this method AFTER the init() to leave the time to instantiate the ActionBarDrawerToggle
* @param resId the id to resource drawable to use as indicator
*/
public void setHomeAsUpIndicator(int resId) {
setHomeAsUpIndicator(resources.getDrawable(resId));
}
/**
* Set the HomeAsUpIndicator that is visible when user navigate to a fragment child
* @param indicator the resource drawable to use as indicator
*/
public void setHomeAsUpIndicator(Drawable indicator) {
if(!deviceSupportMultiPane()) {
pulsante.setHomeAsUpIndicator(indicator);
}
else {
actionBar.setHomeAsUpIndicator(indicator);
}
}
public void changeToolbarColor(MaterialSection section) {
int sectionPrimaryColor;
int sectionPrimaryColorDark;
if (section.hasSectionColor() && !uniqueToolbarColor) {
if (!section.hasSectionColorDark())
sectionPrimaryColorDark = darkenColor(section.getSectionColor());
else
sectionPrimaryColorDark = section.getSectionColorDark();
sectionPrimaryColor = section.getSectionColor();
} else {
sectionPrimaryColorDark = primaryDarkColor;
sectionPrimaryColor = primaryColor;
}
this.getToolbar().setBackgroundColor(sectionPrimaryColor);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
statusBar.setImageDrawable(new ColorDrawable(sectionPrimaryColorDark));
}
public void changeToolbarColor(int primaryColor, int primaryDarkColor) {
if(statusBar != null)
statusBar.setImageDrawable(new ColorDrawable(primaryDarkColor));
if(getToolbar() != null)
this.getToolbar().setBackgroundColor(primaryColor);
}
public void setBackPattern(int backPattern) {
this.backPattern = backPattern;
}
/**
* Set the section that will be opened when the activity starts.
* NOTE: 0 is for the first section
* @param sectionNumber is the number of section that you have added in the init() method.
*/
public void setDefaultSectionLoaded(int sectionNumber) {
defaultSectionLoaded = sectionNumber;
}
public void setDrawerHeaderCustom(View view) {
if(drawerHeaderType != DRAWERHEADER_CUSTOM)
throw new RuntimeException("Your header is not setted to Custom, check in your styles.xml");
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
customDrawerHeader.addView(view,params);
}
public void setDrawerHeaderImage(Bitmap background) {
switch(drawerHeaderType) {
case DRAWERHEADER_ACCOUNTS:
usercover.setImageBitmap(background);
break;
case DRAWERHEADER_IMAGE:
ImageView image = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
image.setScaleType(ImageView.ScaleType.FIT_XY);
image.setImageBitmap(background);
customDrawerHeader.addView(image,params);
break;
default:
throw new RuntimeException("Your drawer configuration don't support a background image, check in your styles.xml");
}
}
public void setDrawerHeaderImage(int backgroundId) {
setDrawerHeaderImage(resources.getDrawable(backgroundId));
}
public void setDrawerHeaderImage(Drawable background) {
switch(drawerHeaderType) {
case DRAWERHEADER_IMAGE:
ImageView image = new ImageView(this);
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
image.setScaleType(ImageView.ScaleType.FIT_XY);
image.setImageDrawable(background);
customDrawerHeader.addView(image, params);
break;
case DRAWERHEADER_ACCOUNTS:
usercover.setImageDrawable(background);
break;
default:
throw new RuntimeException("Your drawer configuration don't support a background image, check in your styles.xml");
}
}
// Method used for customize layout
public void setUserEmail(String email) {
if(DRAWERHEADER_ACCOUNTS != drawerHeaderType) {
throw new RuntimeException("Your header is not setted to Accounts, check in your styles.xml");
}
usermail.setText(email);
}
public void setUserEmailTextColor(int color) {
if(DRAWERHEADER_ACCOUNTS != drawerHeaderType) {
throw new RuntimeException("Your header is not setted to Accounts, check in your styles.xml");
}
usermail.setTextColor(color);
}
public void setUsername(String username) {
if(DRAWERHEADER_ACCOUNTS != drawerHeaderType) {
throw new RuntimeException("Your header is not setted to Accounts, check in your styles.xml");
}
this.username.setText(username);
}
public void setUsernameTextColor(int color) {
if(DRAWERHEADER_ACCOUNTS != drawerHeaderType) {
throw new RuntimeException("Your header is not setted to Accounts, check in your styles.xml");
}
this.username.setTextColor(color);
}
public void setFirstAccountPhoto(Drawable photo) {
if(DRAWERHEADER_ACCOUNTS != drawerHeaderType) {
throw new RuntimeException("Your header is not setted to Accounts, check in your styles.xml");
}
userphoto.setImageDrawable(photo);
}
public void setSecondAccountPhoto(Drawable photo) {
if(DRAWERHEADER_ACCOUNTS != drawerHeaderType) {
throw new RuntimeException("Your header is not setted to Accounts, check in your styles.xml");
}
userSecondPhoto.setImageDrawable(photo);
}
public void setThirdAccountPhoto(Drawable photo) {
if(DRAWERHEADER_ACCOUNTS != drawerHeaderType) {
throw new RuntimeException("Your header is not setted to Accounts, check in your styles.xml");
}
userThirdPhoto.setImageDrawable(photo);
}
public void setDrawerBackgroundColor(int color) {
drawer.setBackgroundColor(color);
}
public void addSection(MaterialSection section) {
// section.setPosition(sectionList.size());
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,(int)(48 * density));
section.setTypeface(fontManager.getRobotoMedium());
sectionList.add(section);
ViewParent parent = section.getView().getParent();
sections.addView(section.getView(),params);
// add the element to the list
elementsList.add(new Element(Element.TYPE_SECTION,section));
}
public void removeSection(MaterialSection section) {
// remove section from section list and recalculate positions
sectionList.remove(section);
// removes section view from the drawer
sections.removeView(section.getView());
}
public void addBottomSection(MaterialSection section) {
// section.setPosition(BOTTOM_SECTION_START + bottomSectionList.size());
section.setTypeface(fontManager.getRobotoRegular());
bottomSectionList.add(section);
// add the element to the list
elementsList.add(new Element(Element.TYPE_BOTTOM_SECTION,section));
}
public void addAccountSection(MaterialSection section) {
// section.setPosition(accountSectionList.size());
section.setTypeface(fontManager.getRobotoMedium());
accountSectionList.add(section);
}
public void addDivisor() {
View view = new View(this);
view.setBackgroundColor(Color.parseColor("#8f8f8f"));
// height 1 px
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT,1);
params.setMargins(0,(int) (8 * density), 0 , (int) (8 * density));
sections.addView(view, params);
// add the element to the list
elementsList.add(new Element(Element.TYPE_DIVISOR,view));
}
public void addSubheader(CharSequence title) {
MaterialSubheader subheader = new MaterialSubheader(this);
subheader.setTitle(title);
subheader.setTitleFont(fontManager.getRobotoRegular());
subheaderList.add(subheader);
sections.addView(subheader.getView());
// add the element to the list
elementsList.add(new Element(Element.TYPE_SUBHEADER,subheader));
}
public void addAccount(MaterialAccount account) {
if(DRAWERHEADER_ACCOUNTS != drawerHeaderType) {
throw new RuntimeException("Your header is not setted to Accounts, check in your styles.xml");
}
account.setAccountListener(this);
account.setAccountNumber(accountManager.size());
accountManager.add(account);
}
public void removeAccount(MaterialAccount account) {
int size = accountManager.size();
// si rimuovono le viste gia inserite che stanno per essere cambiate
if(size <= 3 && size > 0) {
this.setThirdAccountPhoto(null);
this.setSecondAccountPhoto(null);
this.setFirstAccountPhoto(null);
}
// si ricalcolano gli indici degli account
for(int i = 0; i < size; i++ ) {
MaterialAccount a = accountManager.get(i);
if(a.getAccountNumber() > account.getAccountNumber()) {
a.setAccountNumber(a.getAccountNumber() - 1);
}
}
// si rimuove dalla lista degli account e si esegue il recycle sulle sue view
accountManager.remove(account);
account.recycle();
if(account.getAccountNumber() == 0)
currentAccount = findAccountNumber(0);
}
/**
* Reload Application data from Account Information
*/
public void notifyAccountDataChanged() {
switch(accountManager.size()) {
default:
case 3:
this.setThirdAccountPhoto(findAccountNumber(MaterialAccount.THIRD_ACCOUNT).getCircularPhoto());
case 2:
this.setSecondAccountPhoto(findAccountNumber(MaterialAccount.SECOND_ACCOUNT).getCircularPhoto());
case 1:
this.setFirstAccountPhoto(currentAccount.getCircularPhoto());
this.setDrawerHeaderImage(currentAccount.getBackground());
this.setUsername(currentAccount.getTitle());
this.setUserEmail(currentAccount.getSubTitle());
case 0:
}
}
public void openDrawer() {
layout.openDrawer(drawer);
}
public void closeDrawer() {
layout.closeDrawer(drawer);
}
public boolean isDrawerOpen() {
return layout.isDrawerOpen(drawer);
}
// create sections
public MaterialSection newSection(String title, Drawable icon, Fragment target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_FRAGMENT);
section.setOnClickListener(this);
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSectionWithRealColor(String title,Drawable icon,Fragment target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_FRAGMENT);
section.setOnClickListener(this);
section.useRealColor();
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSection(String title, Drawable icon, Intent target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_ACTIVITY);
section.setOnClickListener(this);
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSectionWithRealColor(String title, Drawable icon, Intent target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_ACTIVITY);
section.setOnClickListener(this);
section.useRealColor();
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSection(String title, Drawable icon, MaterialSectionListener target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_LISTENER);
section.setOnClickListener(this);
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSectionWithRealColor(String title, Drawable icon, MaterialSectionListener target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_LISTENER);
section.setOnClickListener(this);
section.useRealColor();
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSection(String title, Bitmap icon,Fragment target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_FRAGMENT);
section.setOnClickListener(this);
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSectionWithRealColor(String title, Bitmap icon,Fragment target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_FRAGMENT);
section.setOnClickListener(this);
section.useRealColor();
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSection(String title, Bitmap icon,Intent target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_ACTIVITY);
section.setOnClickListener(this);
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSectionWithRealColor(String title, Bitmap icon,Intent target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_ACTIVITY);
section.setOnClickListener(this);
section.useRealColor();
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSection(String title, Bitmap icon,MaterialSectionListener target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_LISTENER);
section.setOnClickListener(this);
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSectionWithRealColor(String title, Bitmap icon,MaterialSectionListener target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_24DP,rippleSupport,MaterialSection.TARGET_LISTENER);
section.setOnClickListener(this);
section.useRealColor();
section.setIcon(icon);
section.setTitle(title);
section.setTarget(target);
return section;
}
public MaterialSection newSection(String title, int icon,Fragment target) {
return newSection(title,resources.getDrawable(icon),target);
}
public MaterialSection newSectionWithRealColor(String title, int icon,Fragment target) {
return newSectionWithRealColor(title,resources.getDrawable(icon),target);
}
public MaterialSection newSection(String title, int icon,Intent target) {
return newSection(title,resources.getDrawable(icon),target);
}
public MaterialSection newSectionWithRealColor(String title, int icon,Intent target) {
return newSectionWithRealColor(title,resources.getDrawable(icon),target);
}
public MaterialSection newSection(String title, int icon,MaterialSectionListener target) {
return newSection(title,resources.getDrawable(icon),target);
}
public MaterialSection newSectionWithRealColor(String title, int icon,MaterialSectionListener target) {
return newSectionWithRealColor(title,resources.getDrawable(icon),target);
}
@SuppressWarnings("unchecked")
public MaterialSection newSection(String title,Fragment target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_NO_ICON,rippleSupport,MaterialSection.TARGET_FRAGMENT);
section.setOnClickListener(this);
section.setTitle(title);
section.setTarget(target);
return section;
}
@SuppressWarnings("unchecked")
public MaterialSection newSection(String title,Intent target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_NO_ICON,rippleSupport,MaterialSection.TARGET_ACTIVITY);
section.setOnClickListener(this);
section.setTitle(title);
section.setTarget(target);
return section;
}
@SuppressWarnings("unchecked")
public MaterialSection newSection(String title,MaterialSectionListener target) {
MaterialSection section = new MaterialSection<Fragment>(this,MaterialSection.ICON_NO_ICON,rippleSupport,MaterialSection.TARGET_LISTENER);
section.setOnClickListener(this);
section.setTitle(title);
section.setTarget(target);
return section;
}
// abstract methods
public abstract void init(Bundle savedInstanceState);
public void onHomeAsUpSelected() {}
// get methods
public Toolbar getToolbar() {
return toolbar;
}
/**
* Get the section which the user see
* @return the current section
*/
public MaterialSection getCurrentSection() {
return currentSection;
}
// /**
// * Get a setted section knowing his position
// *
// * N.B. this search only into section list and bottom section list.
// * @param position is the position of the section
// * @return the section at position or null if the section is not found
// */
// public MaterialSection getSectionAtCurrentPosition(int position) {
//
//
// for(MaterialSection section : bottomSectionList) {
// if(section.getPosition() == position)
// return section;
// }
//
// return null;
// }
/**
* Get a setted section knowing his title
*
* N.B. this search only into section list and bottom section list.
* @param title is the title of the section
* @return the section with title or null if the section is not founded
*/
public MaterialSection getSectionByTitle(String title) {
for(MaterialSection section : sectionList) {
if(section.getTitle().equals(title)) {
return section;
}
}
for(MaterialSection section : bottomSectionList) {
if(section.getTitle().equals(title))
return section;
}
return null;
}
/**
* Get the section list
*
* N.B. The section list contains the bottom sections
* @return the list of sections setted
*/
public List<MaterialSection> getSectionList() {
List<MaterialSection> list = new LinkedList<>();
for(MaterialSection section : sectionList)
list.add(section);
for(MaterialSection section : bottomSectionList)
list.add(section);
return list;
}
/**
* Get current account
* @return the account at first position
*/
public MaterialAccount getCurrentAccount() {
return currentAccount;
}
/**
* Get the account list
* @return the account lists
*/
public List<MaterialAccount> getAccountList() {
return accountManager;
}
/**
* Get the account knowing his position
* @param position the position of the account (it can change at runtime!)
* @return the account
*/
public MaterialAccount getAccountAtCurrentPosition(int position) {
if (position < 0 || position >= accountManager.size())
throw new RuntimeException("Account Index Overflow");
return findAccountNumber(position);
}
/**
* Get the account knowing his title
* @param title the title of the account (it can change at runtime!)
* @return the account founded or null if the account not exists
*/
public MaterialAccount getAccountByTitle(String title) {
for(MaterialAccount account : accountManager)
if(currentAccount.getTitle().equals(title))
return account;
return null;
}
}