1
0
forked from github/szkolny
2019-09-18 22:29:09 +02:00

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);
}
}