forked from github/szkolny
545 lines
19 KiB
Java
545 lines
19 KiB
Java
package com.mikepenz.materialdrawer;
|
|
|
|
import android.content.Context;
|
|
import android.content.res.Configuration;
|
|
import androidx.annotation.NonNull;
|
|
import androidx.recyclerview.widget.DefaultItemAnimator;
|
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
|
import androidx.recyclerview.widget.RecyclerView;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.widget.LinearLayout;
|
|
|
|
import com.mikepenz.fastadapter.FastAdapter;
|
|
import com.mikepenz.fastadapter.IAdapter;
|
|
import com.mikepenz.fastadapter.adapters.ItemAdapter;
|
|
import com.mikepenz.fastadapter.listeners.OnClickListener;
|
|
import com.mikepenz.fastadapter.listeners.OnLongClickListener;
|
|
import com.mikepenz.materialdrawer.interfaces.ICrossfader;
|
|
import com.mikepenz.materialdrawer.model.MiniDrawerItem;
|
|
import com.mikepenz.materialdrawer.model.MiniProfileDrawerItem;
|
|
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
|
|
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
|
|
import com.mikepenz.materialdrawer.model.SecondaryDrawerItem;
|
|
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
|
|
import com.mikepenz.materialdrawer.model.interfaces.IProfile;
|
|
import com.mikepenz.materialize.util.UIUtils;
|
|
|
|
import java.util.List;
|
|
|
|
/**
|
|
* Created by mikepenz on 15.07.15.
|
|
* Don't count this for real yet. it's just a quick try on creating a Gmail like panel
|
|
*/
|
|
public class MiniDrawer {
|
|
public static final int PROFILE = 1;
|
|
public static final int ITEM = 2;
|
|
|
|
private LinearLayout mContainer;
|
|
private RecyclerView mRecyclerView;
|
|
protected FastAdapter<IDrawerItem> mAdapter;
|
|
protected ItemAdapter<IDrawerItem> mItemAdapter;
|
|
|
|
private Drawer mDrawer;
|
|
|
|
/**
|
|
* Provide the Drawer which will be used as dataSource for the drawerItems
|
|
*
|
|
* @param drawer
|
|
* @return
|
|
*/
|
|
public MiniDrawer withDrawer(@NonNull Drawer drawer) {
|
|
this.mDrawer = drawer;
|
|
return this;
|
|
}
|
|
|
|
private AccountHeader mAccountHeader;
|
|
|
|
/**
|
|
* Provide the AccountHeader which will be used as the dataSource for the profiles
|
|
*
|
|
* @param accountHeader
|
|
* @return
|
|
*/
|
|
public MiniDrawer withAccountHeader(@NonNull AccountHeader accountHeader) {
|
|
this.mAccountHeader = accountHeader;
|
|
return this;
|
|
}
|
|
|
|
private ICrossfader mCrossFader;
|
|
|
|
/**
|
|
* Provide the Crossfader implementation which is used with this MiniDrawer
|
|
*
|
|
* @param crossFader
|
|
* @return
|
|
*/
|
|
public MiniDrawer withCrossFader(@NonNull ICrossfader crossFader) {
|
|
this.mCrossFader = crossFader;
|
|
return this;
|
|
}
|
|
|
|
private boolean mInnerShadow = false;
|
|
|
|
/**
|
|
* set to true if you want to show the innerShadow on the MiniDrawer
|
|
*
|
|
* @param innerShadow
|
|
* @return
|
|
*/
|
|
public MiniDrawer withInnerShadow(boolean innerShadow) {
|
|
this.mInnerShadow = innerShadow;
|
|
return this;
|
|
}
|
|
|
|
private boolean mInRTL = false;
|
|
|
|
/**
|
|
* set to true if you want the MiniDrawer in RTL mode
|
|
*
|
|
* @param inRTL
|
|
* @return
|
|
*/
|
|
public MiniDrawer withInRTL(boolean inRTL) {
|
|
this.mInRTL = inRTL;
|
|
return this;
|
|
}
|
|
|
|
private boolean mIncludeSecondaryDrawerItems = false;
|
|
|
|
/**
|
|
* set to true if you also want to display secondaryDrawerItems
|
|
*
|
|
* @param includeSecondaryDrawerItems
|
|
* @return
|
|
*/
|
|
public MiniDrawer withIncludeSecondaryDrawerItems(boolean includeSecondaryDrawerItems) {
|
|
this.mIncludeSecondaryDrawerItems = includeSecondaryDrawerItems;
|
|
return this;
|
|
}
|
|
|
|
private boolean mEnableSelectedMiniDrawerItemBackground = false;
|
|
|
|
/**
|
|
* set to true if you want to display the background for the miniDrawerItem
|
|
*
|
|
* @param enableSelectedMiniDrawerItemBackground
|
|
* @return
|
|
*/
|
|
public MiniDrawer withEnableSelectedMiniDrawerItemBackground(boolean enableSelectedMiniDrawerItemBackground) {
|
|
this.mEnableSelectedMiniDrawerItemBackground = enableSelectedMiniDrawerItemBackground;
|
|
return this;
|
|
}
|
|
|
|
private boolean mEnableProfileClick = true;
|
|
|
|
/**
|
|
* set to false if you do not want the profile image to toggle to the normal drawers profile selection
|
|
*
|
|
* @param enableProfileClick
|
|
* @return this
|
|
*/
|
|
public MiniDrawer withEnableProfileClick(boolean enableProfileClick) {
|
|
this.mEnableProfileClick = enableProfileClick;
|
|
return this;
|
|
}
|
|
|
|
private OnMiniDrawerItemClickListener mOnMiniDrawerItemClickListener;
|
|
|
|
/**
|
|
* Define the onMiniDrawerItemClickListener called before any logic in the MiniDrawer is run, allows you to intercept the default behavior
|
|
*
|
|
* @param onMiniDrawerItemClickListener
|
|
* @return this
|
|
*/
|
|
public MiniDrawer withOnMiniDrawerItemClickListener(OnMiniDrawerItemClickListener onMiniDrawerItemClickListener) {
|
|
this.mOnMiniDrawerItemClickListener = onMiniDrawerItemClickListener;
|
|
return this;
|
|
}
|
|
|
|
|
|
private OnClickListener<IDrawerItem> mOnMiniDrawerItemOnClickListener;
|
|
|
|
/**
|
|
* Define an onClickListener for the MiniDrawer item adapter. WARNING: this will completely overwrite the default behavior
|
|
* You may want to check the `OnMiniDrawerItemClickListener` (withOnMiniDrawerItemClickListener) which just hooks into the default behavior
|
|
*
|
|
* @param onMiniDrawerItemOnClickListener
|
|
* @return this
|
|
*/
|
|
public MiniDrawer withOnMiniDrawerItemOnClickListener(OnClickListener<IDrawerItem> onMiniDrawerItemOnClickListener) {
|
|
this.mOnMiniDrawerItemOnClickListener = onMiniDrawerItemOnClickListener;
|
|
return this;
|
|
}
|
|
|
|
|
|
private OnLongClickListener<IDrawerItem> mOnMiniDrawerItemLongClickListener;
|
|
|
|
/**
|
|
* Define an onLongClickListener for the MiniDrawer item adapter
|
|
*
|
|
* @param onMiniDrawerItemLongClickListener
|
|
* @return
|
|
*/
|
|
public MiniDrawer withOnMiniDrawerItemLongClickListener(OnLongClickListener<IDrawerItem> onMiniDrawerItemLongClickListener) {
|
|
this.mOnMiniDrawerItemLongClickListener = onMiniDrawerItemLongClickListener;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* get the RecyclerView of this MiniDrawer
|
|
*
|
|
* @return
|
|
*/
|
|
public RecyclerView getRecyclerView() {
|
|
return mRecyclerView;
|
|
}
|
|
|
|
/**
|
|
* get the FastAdapter of this MiniDrawer
|
|
*
|
|
* @return
|
|
*/
|
|
public FastAdapter<IDrawerItem> getAdapter() {
|
|
return mAdapter;
|
|
}
|
|
|
|
/**
|
|
* get the ItemAdapter of this MiniDrawer
|
|
*
|
|
* @return
|
|
*/
|
|
public ItemAdapter<IDrawerItem> getItemAdapter() {
|
|
return mItemAdapter;
|
|
}
|
|
|
|
/**
|
|
* get the Drawer used to fill this MiniDrawer
|
|
*
|
|
* @return
|
|
*/
|
|
public Drawer getDrawer() {
|
|
return mDrawer;
|
|
}
|
|
|
|
/**
|
|
* get the AccountHeader used to fill the this MiniDrawer
|
|
*
|
|
* @return
|
|
*/
|
|
public AccountHeader getAccountHeader() {
|
|
return mAccountHeader;
|
|
}
|
|
|
|
/**
|
|
* get the Crossfader used for this MiniDrawer
|
|
*
|
|
* @return
|
|
*/
|
|
public ICrossfader getCrossFader() {
|
|
return mCrossFader;
|
|
}
|
|
|
|
|
|
/**
|
|
* the defined FastAdapter.OnClickListener which completely replaces the original behavior
|
|
*
|
|
* @return
|
|
*/
|
|
public OnClickListener getOnMiniDrawerItemOnClickListener() {
|
|
return mOnMiniDrawerItemOnClickListener;
|
|
}
|
|
|
|
/**
|
|
* @return
|
|
*/
|
|
public OnLongClickListener getOnMiniDrawerItemLongClickListener() {
|
|
return mOnMiniDrawerItemLongClickListener;
|
|
}
|
|
|
|
|
|
/**
|
|
* generates a MiniDrawerItem from a IDrawerItem
|
|
*
|
|
* @param drawerItem
|
|
* @return
|
|
*/
|
|
public IDrawerItem generateMiniDrawerItem(IDrawerItem drawerItem) {
|
|
if (drawerItem instanceof SecondaryDrawerItem) {
|
|
if (drawerItem.isExcludeFromMiniDrawer()) {
|
|
return null;
|
|
}
|
|
return mIncludeSecondaryDrawerItems ? new MiniDrawerItem((SecondaryDrawerItem) drawerItem).withEnableSelectedBackground(mEnableSelectedMiniDrawerItemBackground).withSelectedBackgroundAnimated(false) : null;
|
|
} else if (drawerItem instanceof PrimaryDrawerItem) {
|
|
if (drawerItem.isExcludeFromMiniDrawer()) {
|
|
return null;
|
|
}
|
|
return new MiniDrawerItem((PrimaryDrawerItem) drawerItem).withEnableSelectedBackground(mEnableSelectedMiniDrawerItemBackground).withSelectedBackgroundAnimated(false);
|
|
} else if (drawerItem instanceof ProfileDrawerItem) {
|
|
if (drawerItem.isExcludeFromMiniDrawer()) {
|
|
return null;
|
|
}
|
|
MiniProfileDrawerItem mpdi = new MiniProfileDrawerItem((ProfileDrawerItem) drawerItem);
|
|
mpdi.withEnabled(mEnableProfileClick);
|
|
return mpdi;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* gets the type of a IDrawerItem
|
|
*
|
|
* @param drawerItem
|
|
* @return
|
|
*/
|
|
public int getMiniDrawerType(IDrawerItem drawerItem) {
|
|
if (drawerItem instanceof MiniProfileDrawerItem) {
|
|
return PROFILE;
|
|
} else if (drawerItem instanceof MiniDrawerItem) {
|
|
return ITEM;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
/**
|
|
* build the MiniDrawer
|
|
*
|
|
* @param ctx
|
|
* @return
|
|
*/
|
|
public View build(Context ctx) {
|
|
mContainer = new LinearLayout(ctx);
|
|
if (mInnerShadow) {
|
|
if (!mInRTL) {
|
|
mContainer.setBackgroundResource(R.drawable.material_drawer_shadow_left);
|
|
} else {
|
|
mContainer.setBackgroundResource(R.drawable.material_drawer_shadow_right);
|
|
}
|
|
}
|
|
|
|
//create and append recyclerView
|
|
mRecyclerView = new RecyclerView(ctx);
|
|
mContainer.addView(mRecyclerView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
|
|
|
|
//set the itemAnimator
|
|
mRecyclerView.setItemAnimator(new DefaultItemAnimator());
|
|
//some style improvements on older devices
|
|
mRecyclerView.setFadingEdgeLength(0);
|
|
//set the drawing cache background to the same color as the slider to improve performance
|
|
//mRecyclerView.setDrawingCacheBackgroundColor(UIUtils.getThemeColorFromAttrOrRes(mActivity, R.attr.material_drawer_background, R.color.material_drawer_background));
|
|
mRecyclerView.setClipToPadding(false);
|
|
//additional stuff
|
|
mRecyclerView.setLayoutManager(new LinearLayoutManager(ctx));
|
|
//adapter
|
|
mItemAdapter = new ItemAdapter<>();
|
|
mAdapter = FastAdapter.with(mItemAdapter);
|
|
mAdapter.withSelectable(true);
|
|
mAdapter.withAllowDeselection(false);
|
|
mRecyclerView.setAdapter(mAdapter);
|
|
|
|
//if the activity with the drawer should be fullscreen add the padding for the statusbar
|
|
if (mDrawer != null && mDrawer.mDrawerBuilder != null && (mDrawer.mDrawerBuilder.mFullscreen || mDrawer.mDrawerBuilder.mTranslucentStatusBar)) {
|
|
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), UIUtils.getStatusBarHeight(ctx), mRecyclerView.getPaddingRight(), mRecyclerView.getPaddingBottom());
|
|
}
|
|
|
|
//if the activity with the drawer should be fullscreen add the padding for the navigationBar
|
|
if (mDrawer != null && mDrawer.mDrawerBuilder != null && (mDrawer.mDrawerBuilder.mFullscreen || mDrawer.mDrawerBuilder.mTranslucentNavigationBar) && ctx.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
|
|
mRecyclerView.setPadding(mRecyclerView.getPaddingLeft(), mRecyclerView.getPaddingTop(), mRecyclerView.getPaddingRight(), UIUtils.getNavigationBarHeight(ctx));
|
|
}
|
|
|
|
//set the adapter with the items
|
|
createItems();
|
|
|
|
return mContainer;
|
|
}
|
|
|
|
/**
|
|
* call this method to trigger the onProfileClick on the MiniDrawer
|
|
*/
|
|
public void onProfileClick() {
|
|
//crossfade if we are cross faded
|
|
if (mCrossFader != null) {
|
|
if (mCrossFader.isCrossfaded()) {
|
|
mCrossFader.crossfade();
|
|
}
|
|
}
|
|
|
|
//update the current profile
|
|
if (mAccountHeader != null) {
|
|
IProfile profile = mAccountHeader.getActiveProfile();
|
|
if (profile instanceof IDrawerItem) {
|
|
mItemAdapter.set(0, generateMiniDrawerItem((IDrawerItem) profile));
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* call this method to trigger the onItemClick on the MiniDrawer
|
|
*
|
|
* @param selectedDrawerItem
|
|
* @return
|
|
*/
|
|
public boolean onItemClick(IDrawerItem selectedDrawerItem) {
|
|
//We only need to clear if the new item is selectable
|
|
if (selectedDrawerItem.isSelectable()) {
|
|
//crossfade if we are cross faded
|
|
if (mCrossFader != null) {
|
|
if (mCrossFader.isCrossfaded()) {
|
|
mCrossFader.crossfade();
|
|
}
|
|
}
|
|
//update everything
|
|
setSelection(selectedDrawerItem.getIdentifier());
|
|
|
|
return false;
|
|
} else {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* set the selection of the MiniDrawer
|
|
*
|
|
* @param identifier the identifier of the item which should be selected (-1 for none)
|
|
*/
|
|
public void setSelection(long identifier) {
|
|
if (identifier == -1) {
|
|
mAdapter.deselect();
|
|
}
|
|
int count = mAdapter.getItemCount();
|
|
for (int i = 0; i < count; i++) {
|
|
IDrawerItem item = mAdapter.getItem(i);
|
|
if (item.getIdentifier() == identifier && !item.isSelected()) {
|
|
mAdapter.deselect();
|
|
mAdapter.select(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* update a MiniDrawerItem (after updating the main Drawer) via its identifier
|
|
*
|
|
* @param identifier the identifier of the item which was updated
|
|
*/
|
|
public void updateItem(long identifier) {
|
|
if (mDrawer != null && mAdapter != null && mItemAdapter.getAdapterItems() != null && identifier != -1) {
|
|
IDrawerItem drawerItem = DrawerUtils.getDrawerItem(getDrawerItems(), identifier);
|
|
for (int i = 0; i < mItemAdapter.getAdapterItems().size(); i++) {
|
|
if (mItemAdapter.getAdapterItems().get(i).getIdentifier() == drawerItem.getIdentifier()) {
|
|
IDrawerItem miniDrawerItem = generateMiniDrawerItem(drawerItem);
|
|
if (miniDrawerItem != null) {
|
|
mItemAdapter.set(i, miniDrawerItem);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* creates the items for the MiniDrawer
|
|
*/
|
|
public void createItems() {
|
|
mItemAdapter.clear();
|
|
|
|
int profileOffset = 0;
|
|
if (mAccountHeader != null && mAccountHeader.getAccountHeaderBuilder().mProfileImagesVisible) {
|
|
IProfile profile = mAccountHeader.getActiveProfile();
|
|
if (profile instanceof IDrawerItem) {
|
|
mItemAdapter.add(generateMiniDrawerItem((IDrawerItem) profile));
|
|
profileOffset = 1;
|
|
}
|
|
}
|
|
|
|
int select = -1;
|
|
if (mDrawer != null) {
|
|
if (getDrawerItems() != null) {
|
|
//migrate to miniDrawerItems
|
|
int length = getDrawerItems().size();
|
|
|
|
int position = 0;
|
|
for (int i = 0; i < length; i++) {
|
|
IDrawerItem miniDrawerItem = generateMiniDrawerItem(getDrawerItems().get(i));
|
|
if (miniDrawerItem != null) {
|
|
if (miniDrawerItem.isSelected()) {
|
|
select = position;
|
|
}
|
|
mItemAdapter.add(miniDrawerItem);
|
|
position = position + 1;
|
|
}
|
|
}
|
|
|
|
if (select >= 0) {
|
|
//+1 because of the profile
|
|
mAdapter.select(select + profileOffset);
|
|
}
|
|
}
|
|
}
|
|
|
|
//listener
|
|
if (mOnMiniDrawerItemOnClickListener != null) {
|
|
mAdapter.withOnClickListener(mOnMiniDrawerItemOnClickListener);
|
|
} else {
|
|
mAdapter.withOnClickListener(new OnClickListener<IDrawerItem>() {
|
|
@Override
|
|
public boolean onClick(View v, IAdapter<IDrawerItem> adapter, final IDrawerItem item, final int position) {
|
|
int type = getMiniDrawerType(item);
|
|
|
|
//if a listener is defined and we consume the event return
|
|
if (mOnMiniDrawerItemClickListener != null && mOnMiniDrawerItemClickListener.onItemClick(v, position, item, type)) {
|
|
return false;
|
|
}
|
|
|
|
if (type == ITEM) {
|
|
//fire the onClickListener also if the specific drawerItem is not Selectable
|
|
if (item.isSelectable()) {
|
|
//make sure we are on the original drawerItemList
|
|
if (mAccountHeader != null && mAccountHeader.isSelectionListShown()) {
|
|
mAccountHeader.toggleSelectionList(v.getContext());
|
|
}
|
|
IDrawerItem drawerItem = mDrawer.getDrawerItem(item.getIdentifier());
|
|
if (drawerItem != null && !drawerItem.isSelected()) {
|
|
//set the selection
|
|
mDrawer.setSelection(item, true);
|
|
}
|
|
} else if (mDrawer.getOnDrawerItemClickListener() != null) {
|
|
//get the original `DrawerItem` from the Drawer as this one will contain all information
|
|
mDrawer.getOnDrawerItemClickListener().onItemClick(v, position, DrawerUtils.getDrawerItem(getDrawerItems(), item.getIdentifier()));
|
|
}
|
|
} else if (type == PROFILE) {
|
|
if (mAccountHeader != null && !mAccountHeader.isSelectionListShown()) {
|
|
mAccountHeader.toggleSelectionList(v.getContext());
|
|
}
|
|
if (mCrossFader != null) {
|
|
mCrossFader.crossfade();
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
});
|
|
}
|
|
mAdapter.withOnLongClickListener(mOnMiniDrawerItemLongClickListener);
|
|
mRecyclerView.scrollToPosition(0);
|
|
}
|
|
|
|
/**
|
|
* returns always the original drawerItems and not the switched content
|
|
*
|
|
* @return
|
|
*/
|
|
private List<IDrawerItem> getDrawerItems() {
|
|
return mDrawer.getOriginalDrawerItems() != null ? mDrawer.getOriginalDrawerItems() : mDrawer.getDrawerItems();
|
|
}
|
|
|
|
|
|
public interface OnMiniDrawerItemClickListener {
|
|
/**
|
|
* @param view
|
|
* @param position
|
|
* @param drawerItem
|
|
* @param type either MiniDrawer.PROFILE or MiniDrawer.ITEM
|
|
* @return true if the event was consumed
|
|
*/
|
|
boolean onItemClick(View view, int position, IDrawerItem drawerItem, int type);
|
|
}
|
|
}
|