New folder view when clicking on an expandable drawer item

This commit is contained in:
Shinokuni 2021-07-11 19:26:11 +02:00
parent 38bd3e3ae5
commit 725c20a78e
5 changed files with 370 additions and 5 deletions

View File

@ -90,10 +90,12 @@ dependencies {
implementation 'com.afollestad.material-dialogs:core:0.9.6.0'
implementation 'com.mikepenz:fastadapter:3.3.1'
implementation 'com.mikepenz:fastadapter:3.2.9'
implementation 'com.mikepenz:fastadapter-commons:3.3.0'
implementation 'com.mikepenz:materialdrawer:6.1.2'
implementation "com.mikepenz:aboutlibraries:6.2.3"
implementation "com.mikepenz:iconics-views:3.2.5"
implementation "com.mikepenz:iconics-core:3.2.5"
debugImplementation 'com.facebook.flipper:flipper:0.96.1'
debugImplementation 'com.facebook.soloader:soloader:0.10.1'

View File

@ -2,23 +2,28 @@ package com.readrops.app.itemslist;
import android.app.Activity;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.widget.Toolbar;
import androidx.recyclerview.widget.RecyclerView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.load.engine.DiskCacheStrategy;
import com.bumptech.glide.request.target.CustomTarget;
import com.bumptech.glide.request.transition.Transition;
import com.mikepenz.fastadapter.FastAdapter;
import com.mikepenz.fastadapter.expandable.ExpandableExtension;
import com.mikepenz.fastadapter.listeners.ClickEventHook;
import com.mikepenz.fastadapter.select.SelectExtension;
import com.mikepenz.materialdrawer.AccountHeader;
import com.mikepenz.materialdrawer.AccountHeaderBuilder;
import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.DrawerBuilder;
import com.mikepenz.materialdrawer.holder.ImageHolder;
import com.mikepenz.materialdrawer.model.DividerDrawerItem;
import com.mikepenz.materialdrawer.model.ExpandableBadgeDrawerItem;
import com.mikepenz.materialdrawer.model.PrimaryDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileDrawerItem;
import com.mikepenz.materialdrawer.model.ProfileSettingDrawerItem;
@ -26,11 +31,14 @@ import com.mikepenz.materialdrawer.model.SecondaryDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IDrawerItem;
import com.mikepenz.materialdrawer.model.interfaces.IProfile;
import com.readrops.app.R;
import com.readrops.app.utils.customviews.CustomExpandableBadgeDrawerItem;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
import com.readrops.db.entities.account.Account;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -50,6 +58,7 @@ public class DrawerManager {
private Activity activity;
private Toolbar toolbar;
private Drawer drawer;
private FastAdapter<IDrawerItem> adapter;
private AccountHeader header;
private Drawer.OnDrawerItemClickListener listener;
@ -76,11 +85,76 @@ public class DrawerManager {
.withOnDrawerItemClickListener(listener)
.build();
adapter = drawer.getAdapter();
buildFastAdapter();
addDefaultPlaces();
return drawer;
}
public void buildFastAdapter() {
// Folder click
adapter.withEventHook(new ClickEventHook<IDrawerItem>() {
@Override
public void onClick(@NonNull View v, int position, @NonNull FastAdapter<IDrawerItem> fastAdapter, @NonNull IDrawerItem item) {
SelectExtension selectExtension = adapter.getExtension(SelectExtension.class);
selectExtension.deselect(selectExtension.getSelections());
if (!item.isSelected()) {
selectExtension.select(position);
}
listener.onItemClick(v, position, item);
}
@Override
public List<View> onBindMany(@NonNull RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof CustomExpandableBadgeDrawerItem.ViewHolder) {
CustomExpandableBadgeDrawerItem.ViewHolder expandableViewHolder = (CustomExpandableBadgeDrawerItem.ViewHolder) viewHolder;
return Arrays.asList(new View[]{
expandableViewHolder.itemView.findViewById(R.id.expandable_item_container),
expandableViewHolder.itemView.findViewById(R.id.material_drawer_icon),
expandableViewHolder.itemView.findViewById(R.id.material_drawer_name),
expandableViewHolder.itemView.findViewById(R.id.material_drawer_description)
}.clone());
} else {
return Collections.emptyList();
}
}
});
// Expandable click
adapter.withEventHook(new ClickEventHook<IDrawerItem>() {
@Override
public void onClick(@NonNull View v, int position, @NonNull FastAdapter<IDrawerItem> fastAdapter, @NonNull IDrawerItem item) {
ExpandableExtension expandableExtension = adapter.getExtension(ExpandableExtension.class);
expandableExtension.toggleExpandable(position);
}
@Override
public List<View> onBindMany(@NonNull RecyclerView.ViewHolder viewHolder) {
if (viewHolder instanceof CustomExpandableBadgeDrawerItem.ViewHolder) {
CustomExpandableBadgeDrawerItem.ViewHolder expandableViewHolder = (CustomExpandableBadgeDrawerItem.ViewHolder) viewHolder;
return Arrays.asList(new View[]{
expandableViewHolder.badge,
expandableViewHolder.badgeContainer,
expandableViewHolder.arrow,
expandableViewHolder.itemView.findViewById(R.id.material_drawer_arrow_container)
}.clone());
} else {
return Collections.emptyList();
}
}
});
}
public void updateDrawer(Map<Folder, List<Feed>> folderListMap) {
drawer.removeAllItems();
drawer.removeAllStickyFooterItems();
@ -92,9 +166,8 @@ public class DrawerManager {
for (Map.Entry<Folder, List<Feed>> entry : folderListMap.entrySet()) {
Folder folder = entry.getKey();
if (folder != null) {
// no identifier for badge items, but if needed, be aware of not getting conflicts
// with secondary item identifiers (folder and feed ids can be the same)
ExpandableBadgeDrawerItem badgeDrawerItem = new ExpandableBadgeDrawerItem()
CustomExpandableBadgeDrawerItem badgeDrawerItem = new CustomExpandableBadgeDrawerItem()
.withIdentifier(folder.getId() * 1000L) // to avoid any id conflict with other items
.withName(folder.getName())
.withIcon(R.drawable.ic_folder_grey);

View File

@ -42,6 +42,7 @@ import com.readrops.app.settings.SettingsActivity;
import com.readrops.app.utils.GlideRequests;
import com.readrops.app.utils.SharedPreferencesManager;
import com.readrops.app.utils.Utils;
import com.readrops.app.utils.customviews.CustomExpandableBadgeDrawerItem;
import com.readrops.app.utils.customviews.ReadropsItemTouchCallback;
import com.readrops.db.entities.Feed;
import com.readrops.db.entities.Folder;
@ -280,6 +281,12 @@ public class MainActivity extends AppCompatActivity implements SwipeRefreshLayou
viewModel.setFilterFeedId((int) drawerItem.getIdentifier());
viewModel.setFilterType(FilterType.FEED_FILTER);
viewModel.invalidate();
} else if (drawerItem instanceof CustomExpandableBadgeDrawerItem) {
drawer.closeDrawer();
viewModel.setFilerFolderId((int) (drawerItem.getIdentifier() / 1000));
viewModel.setFilterType(FilterType.FOLDER_FILER);
viewModel.invalidate();
}
}

View File

@ -0,0 +1,174 @@
package com.readrops.app.utils.customviews;
import android.content.Context;
import android.graphics.Color;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.LayoutRes;
import androidx.annotation.StringRes;
import com.mikepenz.fastadapter.IClickable;
import com.mikepenz.fastadapter.IItem;
import com.mikepenz.fastadapter.listeners.OnClickListener;
import com.mikepenz.iconics.IconicsDrawable;
import com.mikepenz.materialdrawer.Drawer;
import com.mikepenz.materialdrawer.holder.BadgeStyle;
import com.mikepenz.materialdrawer.holder.ColorHolder;
import com.mikepenz.materialdrawer.holder.StringHolder;
import com.mikepenz.materialdrawer.icons.MaterialDrawerFont;
import com.mikepenz.materialdrawer.model.BaseDescribeableDrawerItem;
import com.mikepenz.materialdrawer.model.BaseViewHolder;
import com.mikepenz.materialdrawer.model.interfaces.ColorfulBadgeable;
import com.readrops.app.R;
import java.util.List;
/**
* This a simple modification of original ExpandableBadgeDrawerItem from MaterialDrawer lib to get two click events from an expandable drawer item
*/
public class CustomExpandableBadgeDrawerItem extends BaseDescribeableDrawerItem<CustomExpandableBadgeDrawerItem,
CustomExpandableBadgeDrawerItem.ViewHolder>
implements ColorfulBadgeable<CustomExpandableBadgeDrawerItem>, IClickable {
protected ColorHolder arrowColor;
protected int arrowRotationAngleStart = 0;
protected int arrowRotationAngleEnd = 180;
protected StringHolder mBadge;
protected BadgeStyle mBadgeStyle = new BadgeStyle();
@Override
public int getType() {
return R.id.material_drawer_item_expandable_badge;
}
@Override
@LayoutRes
public int getLayoutRes() {
return R.layout.custom_expandable_drawer_item;
}
@Override
public void bindView(CustomExpandableBadgeDrawerItem.ViewHolder viewHolder, List payloads) {
super.bindView(viewHolder, payloads);
Context ctx = viewHolder.itemView.getContext();
//bind the basic view parts
bindViewHelper(viewHolder);
//set the text for the badge or hide
boolean badgeVisible = StringHolder.applyToOrHide(mBadge, viewHolder.badge);
//style the badge if it is visible
if (true) {
mBadgeStyle.style(viewHolder.badge, getTextColorStateList(getColor(ctx), getSelectedTextColor(ctx)));
viewHolder.badgeContainer.setVisibility(View.VISIBLE);
} else {
viewHolder.badgeContainer.setVisibility(View.GONE);
}
//define the typeface for our textViews
if (getTypeface() != null) {
viewHolder.badge.setTypeface(getTypeface());
}
//make sure all animations are stopped
if (viewHolder.arrow.getDrawable() instanceof IconicsDrawable) {
((IconicsDrawable) viewHolder.arrow.getDrawable()).color(this.arrowColor != null ? this.arrowColor.color(ctx) : getIconColor(ctx));
}
viewHolder.arrow.clearAnimation();
if (!isExpanded()) {
viewHolder.arrow.setRotation(this.arrowRotationAngleStart);
} else {
viewHolder.arrow.setRotation(this.arrowRotationAngleEnd);
}
//call the onPostBindView method to trigger post bind view actions (like the listener to modify the item if required)
onPostBindView(this, viewHolder.itemView);
}
@Override
public CustomExpandableBadgeDrawerItem withOnDrawerItemClickListener(Drawer.OnDrawerItemClickListener onDrawerItemClickListener) {
mOnDrawerItemClickListener = null;
return this;
}
@Override
public Drawer.OnDrawerItemClickListener getOnDrawerItemClickListener() {
return null;
}
@Override
public CustomExpandableBadgeDrawerItem withBadge(StringHolder badge) {
this.mBadge = badge;
return this;
}
@Override
public CustomExpandableBadgeDrawerItem withBadge(String badge) {
this.mBadge = new StringHolder(badge);
return this;
}
@Override
public CustomExpandableBadgeDrawerItem withBadge(@StringRes int badgeRes) {
this.mBadge = new StringHolder(badgeRes);
return this;
}
@Override
public CustomExpandableBadgeDrawerItem withBadgeStyle(BadgeStyle badgeStyle) {
this.mBadgeStyle = badgeStyle;
return this;
}
public StringHolder getBadge() {
return mBadge;
}
public BadgeStyle getBadgeStyle() {
return mBadgeStyle;
}
@Override
public ViewHolder getViewHolder(View v) {
return new ViewHolder(v);
}
@Override
public IItem withOnItemPreClickListener(OnClickListener onItemPreClickListener) {
return null;
}
@Override
public OnClickListener getOnPreItemClickListener() {
return null;
}
@Override
public IItem withOnItemClickListener(OnClickListener onItemClickListener) {
return null;
}
@Override
public OnClickListener getOnItemClickListener() {
return null;
}
public static class ViewHolder extends BaseViewHolder {
public ImageView arrow;
public View badgeContainer;
public TextView badge;
public ViewHolder(View view) {
super(view);
badgeContainer = view.findViewById(R.id.material_drawer_badge_container);
badge = view.findViewById(R.id.material_drawer_badge);
arrow = view.findViewById(R.id.material_drawer_arrow);
arrow.setImageDrawable(new IconicsDrawable(view.getContext(), MaterialDrawerFont.Icon.mdf_expand_more).sizeDp(16).paddingDp(2).color(Color.BLACK));
}
}
}

View File

@ -0,0 +1,109 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/expandable_item_container"
android:layout_width="match_parent"
android:layout_height="@dimen/material_drawer_item_primary"
android:clickable="true"
android:orientation="horizontal"
android:paddingStart="@dimen/material_drawer_vertical_padding"
android:paddingLeft="@dimen/material_drawer_vertical_padding"
android:paddingEnd="@dimen/material_drawer_vertical_padding"
android:paddingRight="@dimen/material_drawer_vertical_padding">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/material_drawer_icon"
android:layout_width="@dimen/material_drawer_item_primary_icon"
android:layout_height="@dimen/material_drawer_item_primary"
android:layout_gravity="center_vertical"
android:paddingStart="0dp"
android:paddingLeft="0dp"
android:paddingTop="@dimen/material_drawer_item_primary_icon_padding"
android:paddingEnd="@dimen/material_drawer_item_primary_icon_padding_right"
android:paddingRight="@dimen/material_drawer_item_primary_icon_padding_right"
android:paddingBottom="@dimen/material_drawer_item_primary_icon_padding"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/material_drawer_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif-medium"
android:gravity="center_vertical|start"
android:lines="1"
android:singleLine="true"
android:textDirection="anyRtl"
android:textSize="@dimen/material_drawer_item_primary_text"
app:layout_constraintBottom_toTopOf="@id/material_drawer_description"
app:layout_constraintEnd_toStartOf="@+id/material_drawer_badge_container"
app:layout_constraintStart_toEndOf="@id/material_drawer_icon"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_chainStyle="packed"
tools:text="Some drawer text" />
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/material_drawer_description"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:gravity="center_vertical|start"
android:lines="1"
android:singleLine="true"
android:textDirection="anyRtl"
android:textSize="@dimen/material_drawer_item_primary_description"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/material_drawer_badge_container"
app:layout_constraintStart_toEndOf="@id/material_drawer_icon"
app:layout_constraintTop_toBottomOf="@id/material_drawer_name"
tools:text="Some drawer text" />
<LinearLayout
android:id="@+id/material_drawer_badge_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:paddingStart="@dimen/material_drawer_padding"
android:paddingLeft="@dimen/material_drawer_padding"
android:paddingEnd="0dp"
android:paddingRight="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/material_drawer_arrow_container"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatTextView
android:id="@+id/material_drawer_badge"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:fontFamily="sans-serif"
android:gravity="center"
android:lines="1"
android:minWidth="20dp"
android:paddingLeft="1dp"
android:paddingRight="1dp"
android:singleLine="true"
android:textSize="@dimen/material_drawer_item_primary_text"
tools:text="99" />
</LinearLayout>
<LinearLayout
android:id="@+id/material_drawer_arrow_container"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center"
android:paddingStart="@dimen/material_drawer_padding"
android:paddingLeft="@dimen/material_drawer_padding"
android:paddingEnd="0dp"
android:paddingRight="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.appcompat.widget.AppCompatImageView
android:id="@+id/material_drawer_arrow"
android:layout_width="16dp"
android:layout_height="16dp" />
</LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>