Convert navigation drawer to recycler view

pull/848/head
Alex Baker 5 years ago
parent ead60643be
commit 54278e49e0

@ -20,47 +20,37 @@ import androidx.annotation.Nullable;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.FilterListItem;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.R;
import org.tasks.filters.NavigationDrawerSubheader; import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.locale.Locale; import org.tasks.locale.Locale;
import org.tasks.themes.Theme; import org.tasks.themes.Theme;
import org.tasks.themes.ThemeAccent;
import org.tasks.themes.ThemeCache; import org.tasks.themes.ThemeCache;
public class FilterAdapter extends BaseAdapter { public class FilterAdapter extends BaseAdapter {
public static final int REQUEST_SETTINGS = 10123;
public static final int REQUEST_PURCHASE = 10124;
private static final String TOKEN_FILTERS = "token_filters"; private static final String TOKEN_FILTERS = "token_filters";
private static final String TOKEN_SELECTED = "token_selected"; private static final String TOKEN_SELECTED = "token_selected";
private static final int VIEW_TYPE_COUNT = FilterListItem.Type.values().length; private static final int VIEW_TYPE_COUNT = FilterListItem.Type.values().length;
private final Activity activity; private final Activity activity;
private final Theme theme; private final ThemeAccent accent;
private final Locale locale; private final Locale locale;
private final LayoutInflater inflater; private final LayoutInflater inflater;
private final ThemeCache themeCache; private final ThemeCache themeCache;
private boolean navigationDrawer;
private Filter selected = null; private Filter selected = null;
private List<FilterListItem> items = new ArrayList<>(); private List<FilterListItem> items = new ArrayList<>();
private Map<Filter, Integer> counts = new HashMap<>();
@Inject @Inject
public FilterAdapter(Activity activity, Theme theme, ThemeCache themeCache, Locale locale) { public FilterAdapter(
Activity activity, Theme theme, ThemeCache themeCache, Locale locale) {
this.activity = activity; this.activity = activity;
this.theme = theme; this.accent = theme.getThemeAccent();
this.locale = locale; this.locale = locale;
this.inflater = theme.getLayoutInflater(activity); this.inflater = theme.getLayoutInflater(activity);
this.themeCache = themeCache; this.themeCache = themeCache;
} }
public void setNavigationDrawer() {
navigationDrawer = true;
}
public void save(Bundle outState) { public void save(Bundle outState) {
outState.putParcelableArrayList(TOKEN_FILTERS, getItems()); outState.putParcelableArrayList(TOKEN_FILTERS, getItems());
outState.putParcelable(TOKEN_SELECTED, selected); outState.putParcelable(TOKEN_SELECTED, selected);
@ -71,10 +61,6 @@ public class FilterAdapter extends BaseAdapter {
selected = savedInstanceState.getParcelable(TOKEN_SELECTED); selected = savedInstanceState.getParcelable(TOKEN_SELECTED);
} }
public void setData(List<FilterListItem> items) {
setData(items, selected);
}
public void setData(List<FilterListItem> items, @Nullable Filter selected) { public void setData(List<FilterListItem> items, @Nullable Filter selected) {
setData(items, selected, -1); setData(items, selected, -1);
} }
@ -86,12 +72,6 @@ public class FilterAdapter extends BaseAdapter {
notifyDataSetChanged(); notifyDataSetChanged();
} }
public void setCounts(Map<Filter, Integer> counts) {
assertMainThread();
this.counts = counts;
notifyDataSetChanged();
}
@Override @Override
public int getCount() { public int getCount() {
assertMainThread(); assertMainThread();
@ -121,11 +101,12 @@ public class FilterAdapter extends BaseAdapter {
FilterViewHolder viewHolder; FilterViewHolder viewHolder;
switch (viewType) { switch (viewType) {
case ITEM: case ITEM:
viewHolder = new FilterViewHolder( viewHolder =
convertView, theme.getThemeAccent(), themeCache, navigationDrawer, locale, activity); new FilterViewHolder(
convertView, accent, themeCache, false, locale, activity, null);
break; break;
case SEPARATOR: case SEPARATOR:
viewHolder = new FilterViewHolder(); viewHolder = new FilterViewHolder(convertView);
break; break;
case SUBHEADER: case SUBHEADER:
viewHolder = new FilterViewHolder(convertView, activity); viewHolder = new FilterViewHolder(convertView, activity);
@ -138,15 +119,6 @@ public class FilterAdapter extends BaseAdapter {
return convertView; return convertView;
} }
public Filter getSelected() {
return selected;
}
public void setSelected(Filter selected) {
this.selected = selected;
notifyDataSetChanged();
}
public ArrayList<FilterListItem> getItems() { public ArrayList<FilterListItem> getItems() {
assertMainThread(); assertMainThread();
return newArrayList(items); return newArrayList(items);
@ -166,7 +138,7 @@ public class FilterAdapter extends BaseAdapter {
FilterViewHolder viewHolder = (FilterViewHolder) convertView.getTag(); FilterViewHolder viewHolder = (FilterViewHolder) convertView.getTag();
switch (item.getItemType()) { switch (item.getItemType()) {
case ITEM: case ITEM:
viewHolder.bind(item, item.equals(selected), counts.get(item)); viewHolder.bind(item, item.equals(selected), 0);
break; break;
case SUBHEADER: case SUBHEADER:
viewHolder.bind((NavigationDrawerSubheader) item); viewHolder.bind((NavigationDrawerSubheader) item);
@ -192,9 +164,4 @@ public class FilterAdapter extends BaseAdapter {
public int getItemViewType(int position) { public int getItemViewType(int position) {
return getItem(position).getItemType().ordinal(); return getItem(position).getItemType().ordinal();
} }
@Override
public View getDropDownView(int position, View convertView, @NonNull ViewGroup parent) {
return getView(position, convertView, parent);
}
} }

@ -16,20 +16,18 @@ import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat; import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.drawable.DrawableCompat; import androidx.core.graphics.drawable.DrawableCompat;
import androidx.recyclerview.widget.RecyclerView;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.FilterListItem;
import org.tasks.R; import org.tasks.R;
import org.tasks.filters.NavigationDrawerAction;
import org.tasks.filters.NavigationDrawerSubheader; import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.intents.TaskIntents;
import org.tasks.locale.Locale; import org.tasks.locale.Locale;
import org.tasks.sync.SynchronizationPreferences; import org.tasks.sync.SynchronizationPreferences;
import org.tasks.themes.ThemeAccent; import org.tasks.themes.ThemeAccent;
import org.tasks.themes.ThemeCache; import org.tasks.themes.ThemeCache;
public class FilterViewHolder { public class FilterViewHolder extends RecyclerView.ViewHolder {
@Nullable @Nullable
@BindView(R.id.row) @BindView(R.id.row)
@ -45,6 +43,7 @@ public class FilterViewHolder {
@BindView(R.id.size) @BindView(R.id.size)
TextView size; TextView size;
private OnClick onClick;
private ThemeCache themeCache; private ThemeCache themeCache;
private boolean navigationDrawer; private boolean navigationDrawer;
private Locale locale; private Locale locale;
@ -57,7 +56,10 @@ public class FilterViewHolder {
ThemeCache themeCache, ThemeCache themeCache,
boolean navigationDrawer, boolean navigationDrawer,
Locale locale, Locale locale,
Activity activity) { Activity activity,
OnClick onClick) {
super(itemView);
ButterKnife.bind(this, itemView); ButterKnife.bind(this, itemView);
this.itemView = itemView; this.itemView = itemView;
@ -65,6 +67,7 @@ public class FilterViewHolder {
this.navigationDrawer = navigationDrawer; this.navigationDrawer = navigationDrawer;
this.locale = locale; this.locale = locale;
this.activity = activity; this.activity = activity;
this.onClick = onClick;
if (navigationDrawer) { if (navigationDrawer) {
text.setCheckMarkDrawable(null); text.setCheckMarkDrawable(null);
@ -87,25 +90,23 @@ public class FilterViewHolder {
} }
FilterViewHolder(@NonNull View itemView, Activity activity) { FilterViewHolder(@NonNull View itemView, Activity activity) {
super(itemView);
ButterKnife.bind(this, itemView); ButterKnife.bind(this, itemView);
icon.setOnClickListener( icon.setOnClickListener(
v -> activity.startActivity(new Intent(activity, SynchronizationPreferences.class))); v -> activity.startActivity(new Intent(activity, SynchronizationPreferences.class)));
} }
FilterViewHolder() { FilterViewHolder(@NonNull View itemView) {
super(itemView);
} }
public void bind(FilterListItem filter, boolean selected, Integer count) { public void bind(FilterListItem filter, boolean selected, Integer count) {
if (selected) { if (navigationDrawer) {
if (navigationDrawer) { itemView.setSelected(selected);
itemView.setBackgroundColor(getColor(activity, R.color.drawer_color_selected));
} else {
text.setChecked(true);
}
} else { } else {
itemView.setBackgroundResource(0); text.setChecked(selected);
text.setChecked(false);
} }
icon.setImageResource(filter.icon); icon.setImageResource(filter.icon);
@ -123,25 +124,17 @@ public class FilterViewHolder {
size.setVisibility(View.VISIBLE); size.setVisibility(View.VISIBLE);
} }
row.setOnClickListener( if (onClick != null) {
v -> { row.setOnClickListener(v -> onClick.onClick(filter));
if (filter instanceof Filter) { }
if (!selected) {
activity.startActivity(TaskIntents.getTaskListIntent(activity, (Filter) filter));
}
} else if (filter instanceof NavigationDrawerAction) {
NavigationDrawerAction action = (NavigationDrawerAction) filter;
if (action.requestCode > 0) {
activity.startActivityForResult(action.intent, action.requestCode);
} else {
activity.startActivity(action.intent);
}
}
});
} }
public void bind(NavigationDrawerSubheader filter) { public void bind(NavigationDrawerSubheader filter) {
text.setText(filter.listingTitle); text.setText(filter.listingTitle);
icon.setVisibility(filter.error ? View.VISIBLE : View.GONE); icon.setVisibility(filter.error ? View.VISIBLE : View.GONE);
} }
public interface OnClick {
void onClick(FilterListItem item);
}
} }

@ -0,0 +1,174 @@
/*
* Copyright (c) 2012 Todoroo Inc
*
* See the file "LICENSE" for the full license governing this code.
*/
package com.todoroo.astrid.adapter;
import static com.google.common.collect.Lists.newArrayList;
import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread;
import static com.todoroo.astrid.api.FilterListItem.Type.ITEM;
import static com.todoroo.astrid.api.FilterListItem.Type.SUBHEADER;
import android.app.Activity;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.DiffUtil.ItemCallback;
import androidx.recyclerview.widget.ListAdapter;
import com.todoroo.astrid.adapter.FilterViewHolder.OnClick;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.api.FilterListItem.Type;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.inject.Inject;
import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.locale.Locale;
import org.tasks.themes.Theme;
import org.tasks.themes.ThemeAccent;
import org.tasks.themes.ThemeCache;
public class NavigationDrawerAdapter extends ListAdapter<FilterListItem, FilterViewHolder> {
public static final int REQUEST_SETTINGS = 10123;
public static final int REQUEST_PURCHASE = 10124;
private static final String TOKEN_SELECTED = "token_selected";
private final Activity activity;
private final ThemeAccent accent;
private final Locale locale;
private final LayoutInflater inflater;
private final ThemeCache themeCache;
private OnClick onClick;
private Filter selected = null;
private Map<Filter, Integer> counts = new HashMap<>();
private List<FilterListItem> items;
@Inject
public NavigationDrawerAdapter(
Activity activity, Theme theme, ThemeCache themeCache, Locale locale) {
super(new DiffCallback());
this.activity = activity;
this.accent = theme.getThemeAccent();
this.locale = locale;
this.inflater = theme.getLayoutInflater(activity);
this.themeCache = themeCache;
}
public void setOnClick(OnClick onClick) {
this.onClick = onClick;
}
public void save(Bundle outState) {
outState.putParcelable(TOKEN_SELECTED, selected);
}
public void restore(Bundle savedInstanceState) {
selected = savedInstanceState.getParcelable(TOKEN_SELECTED);
}
public void setData(List<FilterListItem> items) {
setData(items, selected);
}
public void setData(List<FilterListItem> items, @Nullable Filter selected) {
setData(items, selected, -1);
}
public void setData(List<FilterListItem> items, @Nullable Filter selected, int defaultIndex) {
this.items = items;
submitList(items);
if (selected != null) {
this.selected = selected;
} else if (defaultIndex >= 0) {
this.selected = getFilter(defaultIndex);
}
}
public void setCounts(Map<Filter, Integer> counts) {
assertMainThread();
this.counts = counts;
notifyDataSetChanged();
}
private Filter getFilter(int position) {
FilterListItem item = getItem(position);
return item instanceof Filter ? (Filter) item : null;
}
@Override
public long getItemId(int position) {
return position;
}
public Filter getSelected() {
return selected;
}
public void setSelected(Filter selected) {
this.selected = selected;
notifyDataSetChanged();
}
public List<FilterListItem> getItems() {
assertMainThread();
return newArrayList(items);
}
@NonNull
@Override
public FilterViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
Type type = Type.values()[viewType];
View view = inflater.inflate(type.layout, parent, false);
if (type == ITEM) {
return new FilterViewHolder(
view, accent, themeCache, true, locale, activity, onClick);
} else if (type == SUBHEADER) {
return new FilterViewHolder(view, activity);
} else {
return new FilterViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull FilterViewHolder holder, int position) {
FilterListItem item = getItem(position);
Type type = item.getItemType();
if (type == ITEM) {
holder.bind(item, item.equals(selected), counts.get(item));
} else if (type == SUBHEADER) {
holder.bind((NavigationDrawerSubheader) item);
}
}
@Override
public int getItemViewType(int position) {
return getItem(position).getItemType().ordinal();
}
@Override
public FilterListItem getItem(int position) {
return super.getItem(position);
}
private static class DiffCallback extends ItemCallback<FilterListItem> {
@Override
public boolean areItemsTheSame(
@NonNull FilterListItem oldItem, @NonNull FilterListItem newItem) {
return oldItem.areItemsTheSame(newItem);
}
@Override
public boolean areContentsTheSame(
@NonNull FilterListItem oldItem, @NonNull FilterListItem newItem) {
return oldItem.areContentsTheSame(newItem);
}
}
}

@ -1,6 +1,7 @@
package com.todoroo.astrid.api; package com.todoroo.astrid.api;
import android.os.Parcel; import android.os.Parcel;
import androidx.annotation.NonNull;
import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Field; import com.todoroo.andlib.sql.Field;
import com.todoroo.andlib.sql.Join; import com.todoroo.andlib.sql.Join;
@ -94,4 +95,15 @@ public class CaldavFilter extends Filter {
public int getMenu() { public int getMenu() {
return R.menu.menu_caldav_list_fragment; return R.menu.menu_caldav_list_fragment;
} }
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof CaldavFilter
&& calendar.getUuid().equals(((CaldavFilter) other).getUuid());
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return calendar.equals(((CaldavFilter) other).calendar);
}
} }

@ -4,7 +4,9 @@ import static com.todoroo.andlib.utility.AndroidUtilities.mapToSerializedString;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.NonNull;
import java.util.Map; import java.util.Map;
import org.tasks.Objects;
import org.tasks.R; import org.tasks.R;
public class CustomFilter extends Filter { public class CustomFilter extends Filter {
@ -75,4 +77,14 @@ public class CustomFilter extends Filter {
public int getMenu() { public int getMenu() {
return getId() > 0 ? R.menu.menu_custom_filter : 0; return getId() > 0 ? R.menu.menu_custom_filter : 0;
} }
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof CustomFilter && id == ((CustomFilter) other).id;
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return super.areContentsTheSame(other) && Objects.equals(criterion, ((CustomFilter) other).criterion);
}
} }

@ -9,10 +9,12 @@ package com.todoroo.astrid.api;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.MenuRes; import androidx.annotation.MenuRes;
import androidx.annotation.NonNull;
import com.todoroo.andlib.sql.QueryTemplate; import com.todoroo.andlib.sql.QueryTemplate;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.tasks.Objects;
/** /**
* A <code>FilterListFilter</code> allows users to display tasks that have something in common. * A <code>FilterListFilter</code> allows users to display tasks that have something in common.
@ -100,10 +102,7 @@ public class Filter extends FilterListItem {
} }
} }
/** Utility constructor */ Filter() {}
Filter() {
// do nothing
}
public String getOriginalSqlQuery() { public String getOriginalSqlQuery() {
return sqlQuery; return sqlQuery;
@ -207,4 +206,15 @@ public class Filter extends FilterListItem {
+ valuesForNewTasks + valuesForNewTasks
+ '}'; + '}';
} }
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof Filter && Objects.equals(sqlQuery, ((Filter) other).sqlQuery);
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return super.areContentsTheSame(other)
&& Objects.equals(sqlQuery, ((Filter) other).sqlQuery);
}
} }

@ -10,6 +10,8 @@ import android.content.Intent;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.LayoutRes; import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import org.tasks.Objects;
import org.tasks.R; import org.tasks.R;
/** /**
@ -53,6 +55,14 @@ public abstract class FilterListItem implements Parcelable {
source.createTypedArray(Intent.CREATOR); // old context menu intents source.createTypedArray(Intent.CREATOR); // old context menu intents
} }
public abstract boolean areItemsTheSame(@NonNull FilterListItem other);
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return Objects.equals(listingTitle, other.listingTitle)
&& icon == other.icon
&& tint == other.tint;
}
@Override @Override
public String toString() { public String toString() {
return "FilterListItem{" + "listingTitle='" + listingTitle + '\'' + '}'; return "FilterListItem{" + "listingTitle='" + listingTitle + '\'' + '}';

@ -2,6 +2,7 @@ package com.todoroo.astrid.api;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Field; import com.todoroo.andlib.sql.Field;
import com.todoroo.andlib.sql.Join; import com.todoroo.andlib.sql.Join;
@ -109,4 +110,15 @@ public class GtasksFilter extends Filter {
public int getMenu() { public int getMenu() {
return R.menu.menu_gtasks_list_fragment; return R.menu.menu_gtasks_list_fragment;
} }
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof GtasksFilter
&& list.getRemoteId().equals(((GtasksFilter) other).list.getRemoteId());
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return list.equals(((GtasksFilter) other).list);
}
} }

@ -2,6 +2,7 @@ package com.todoroo.astrid.api;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.andlib.sql.Criterion; import com.todoroo.andlib.sql.Criterion;
import com.todoroo.andlib.sql.Field; import com.todoroo.andlib.sql.Field;
import com.todoroo.andlib.sql.Join; import com.todoroo.andlib.sql.Join;
@ -93,4 +94,15 @@ public class TagFilter extends Filter {
public int getMenu() { public int getMenu() {
return R.menu.menu_tag_view_fragment; return R.menu.menu_tag_view_fragment;
} }
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof TagFilter
&& tagData.getRemoteId().equals(((TagFilter) other).getUuid());
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return tagData.equals(((TagFilter) other).tagData);
}
} }

@ -0,0 +1,9 @@
package org.tasks;
public class Objects {
private Objects() {}
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
}

@ -4,8 +4,8 @@ import static com.google.common.base.Strings.isNullOrEmpty;
import static com.google.common.collect.Iterables.concat; import static com.google.common.collect.Iterables.concat;
import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.newArrayList;
import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread; import static com.todoroo.andlib.utility.AndroidUtilities.assertNotMainThread;
import static com.todoroo.astrid.adapter.FilterAdapter.REQUEST_PURCHASE; import static com.todoroo.astrid.adapter.NavigationDrawerAdapter.REQUEST_PURCHASE;
import static com.todoroo.astrid.adapter.FilterAdapter.REQUEST_SETTINGS; import static com.todoroo.astrid.adapter.NavigationDrawerAdapter.REQUEST_SETTINGS;
import static org.tasks.caldav.CaldavCalendarSettingsActivity.EXTRA_CALDAV_ACCOUNT; import static org.tasks.caldav.CaldavCalendarSettingsActivity.EXTRA_CALDAV_ACCOUNT;
import android.content.Context; import android.content.Context;

@ -3,6 +3,7 @@ package org.tasks.filters;
import android.content.Intent; import android.content.Intent;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.FilterListItem;
public class NavigationDrawerAction extends FilterListItem { public class NavigationDrawerAction extends FilterListItem {
@ -57,4 +58,10 @@ public class NavigationDrawerAction extends FilterListItem {
intent = source.readParcelable(Intent.class.getClassLoader()); intent = source.readParcelable(Intent.class.getClassLoader());
requestCode = source.readInt(); requestCode = source.readInt();
} }
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof NavigationDrawerAction
&& requestCode == ((NavigationDrawerAction) other).requestCode;
}
} }

@ -2,6 +2,7 @@ package org.tasks.filters;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.FilterListItem;
public class NavigationDrawerSeparator extends FilterListItem { public class NavigationDrawerSeparator extends FilterListItem {
@ -28,4 +29,14 @@ public class NavigationDrawerSeparator extends FilterListItem {
public Type getItemType() { public Type getItemType() {
return Type.SEPARATOR; return Type.SEPARATOR;
} }
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof NavigationDrawerSeparator;
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return true;
}
} }

@ -2,6 +2,7 @@ package org.tasks.filters;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.NonNull;
import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.FilterListItem;
public class NavigationDrawerSubheader extends FilterListItem { public class NavigationDrawerSubheader extends FilterListItem {
@ -39,6 +40,16 @@ public class NavigationDrawerSubheader extends FilterListItem {
error = source.readInt() == 1; error = source.readInt() == 1;
} }
@Override
public boolean areItemsTheSame(@NonNull FilterListItem other) {
return other instanceof NavigationDrawerSubheader && listingTitle.equals(other.listingTitle);
}
@Override
public boolean areContentsTheSame(@NonNull FilterListItem other) {
return super.areContentsTheSame(other) && error == ((NavigationDrawerSubheader) other).error;
}
@Override @Override
public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) {
super.writeToParcel(dest, flags); super.writeToParcel(dest, flags);

@ -13,13 +13,14 @@ import android.os.Bundle;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.widget.ListView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.core.view.GravityCompat; import androidx.core.view.GravityCompat;
import androidx.drawerlayout.widget.DrawerLayout; import androidx.drawerlayout.widget.DrawerLayout;
import androidx.fragment.app.FragmentActivity; import androidx.fragment.app.FragmentActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.todoroo.astrid.activity.MainActivity; import com.todoroo.astrid.activity.MainActivity;
import com.todoroo.astrid.adapter.FilterAdapter; import com.todoroo.astrid.adapter.NavigationDrawerAdapter;
import com.todoroo.astrid.api.Filter; import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.FilterListItem;
import com.todoroo.astrid.dao.TaskDao; import com.todoroo.astrid.dao.TaskDao;
@ -50,13 +51,13 @@ public class NavigationDrawerFragment extends InjectingFragment {
public static final int REQUEST_NEW_CALDAV_COLLECTION = 7; public static final int REQUEST_NEW_CALDAV_COLLECTION = 7;
private final RefreshReceiver refreshReceiver = new RefreshReceiver(); private final RefreshReceiver refreshReceiver = new RefreshReceiver();
@Inject LocalBroadcastManager localBroadcastManager; @Inject LocalBroadcastManager localBroadcastManager;
@Inject FilterAdapter adapter; @Inject NavigationDrawerAdapter adapter;
@Inject FilterProvider filterProvider; @Inject FilterProvider filterProvider;
@Inject TaskDao taskDao; @Inject TaskDao taskDao;
/** A pointer to the current callbacks instance (the Activity). */ /** A pointer to the current callbacks instance (the Activity). */
private DrawerLayout mDrawerLayout; private DrawerLayout mDrawerLayout;
private ListView mDrawerListView;
private RecyclerView recyclerView;
private View mFragmentContainerView; private View mFragmentContainerView;
private CompositeDisposable disposables; private CompositeDisposable disposables;
@ -80,13 +81,13 @@ public class NavigationDrawerFragment extends InjectingFragment {
@Override @Override
public void onActivityResult(int requestCode, int resultCode, Intent data) { public void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == FilterAdapter.REQUEST_SETTINGS) { if (requestCode == NavigationDrawerAdapter.REQUEST_SETTINGS) {
if (resultCode == Activity.RESULT_OK && data != null) { if (resultCode == Activity.RESULT_OK && data != null) {
if (data.getBooleanExtra(AppearancePreferences.EXTRA_RESTART, false)) { if (data.getBooleanExtra(AppearancePreferences.EXTRA_RESTART, false)) {
((MainActivity) getActivity()).restart(); ((MainActivity) getActivity()).restart();
} }
} }
} else if (requestCode == FilterAdapter.REQUEST_PURCHASE) { } else if (requestCode == NavigationDrawerAdapter.REQUEST_PURCHASE) {
if (resultCode == Activity.RESULT_OK) { if (resultCode == Activity.RESULT_OK) {
((MainActivity) getActivity()).restart(); ((MainActivity) getActivity()).restart();
} }
@ -114,33 +115,41 @@ public class NavigationDrawerFragment extends InjectingFragment {
@Override @Override
public View onCreateView( public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { @NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false); View layout = inflater.inflate(R.layout.fragment_navigation_drawer, container, false);
recyclerView = layout.findViewById(R.id.recycler_view);
if (atLeastLollipop()) { if (atLeastLollipop()) {
((ScrimInsetsFrameLayout) layout.findViewById(R.id.scrim_layout)) ((ScrimInsetsFrameLayout) layout.findViewById(R.id.scrim_layout))
.setOnInsetsCallback(insets -> mDrawerListView.setPadding(0, insets.top, 0, 0)); .setOnInsetsCallback(insets -> recyclerView.setPadding(0, insets.top, 0, 0));
} }
mDrawerListView = layout.findViewById(android.R.id.list);
mDrawerListView.setOnItemClickListener(
(parent, view, position, id) -> {
mDrawerLayout.addDrawerListener(
new DrawerLayout.SimpleDrawerListener() {
@Override
public void onDrawerClosed(View drawerView) {
mDrawerLayout.removeDrawerListener(this);
selectItem(position);
}
});
close();
});
return layout; return layout;
} }
private void setUpList() { private void setUpList() {
adapter.setNavigationDrawer(); adapter.setOnClick(this::onFilterItemSelected);
mDrawerListView.setAdapter(adapter); recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
registerForContextMenu(mDrawerListView); recyclerView.setAdapter(adapter);
}
private void onFilterItemSelected(FilterListItem item) {
if (item instanceof Filter) {
mDrawerLayout.addDrawerListener(
new DrawerLayout.SimpleDrawerListener() {
@Override
public void onDrawerClosed(View drawerView) {
mDrawerLayout.removeDrawerListener(this);
openFilter((Filter) item);
}
});
close();
} else if (item instanceof NavigationDrawerAction) {
NavigationDrawerAction action = (NavigationDrawerAction) item;
if (action.requestCode > 0) {
startActivityForResult(action.intent, action.requestCode);
} else {
startActivity(action.intent);
}
}
} }
public boolean isDrawerOpen() { public boolean isDrawerOpen() {
@ -173,22 +182,6 @@ public class NavigationDrawerFragment extends InjectingFragment {
disposables.dispose(); disposables.dispose();
} }
private void selectItem(int position) {
FilterListItem item = adapter.getItem(position);
if (item instanceof Filter) {
if (!item.equals(adapter.getSelected())) {
openFilter((Filter) item);
}
} else if (item instanceof NavigationDrawerAction) {
NavigationDrawerAction action = (NavigationDrawerAction) item;
if (action.requestCode > 0) {
startActivityForResult(action.intent, action.requestCode);
} else {
startActivity(action.intent);
}
}
}
@Override @Override
protected void inject(FragmentComponent component) { protected void inject(FragmentComponent component) {
component.inject(this); component.inject(this);

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/drawer_color"/>
<item android:drawable="?attr/selectableItemBackground"/>
</layer-list>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@color/drawer_color_selected"/>
<item android:drawable="?attr/selectableItemBackground"/>
</layer-list>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@drawable/drawer_background_selected" android:state_selected="true"/>
<item android:drawable="@drawable/drawer_background"/>
</selector>

@ -2,6 +2,7 @@
<com.todoroo.astrid.adapter.CheckableRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" <com.todoroo.astrid.adapter.CheckableRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/row" android:id="@+id/row"
android:background="@drawable/drawer_background_selector"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="12dp" android:paddingTop="12dp"

@ -4,6 +4,7 @@
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:paddingTop="8dp" android:paddingTop="8dp"
android:paddingBottom="8dp" android:paddingBottom="8dp"
android:background="@drawable/drawer_background_selector"
android:focusable="false" android:focusable="false"
android:orientation="vertical"> android:orientation="vertical">

@ -4,6 +4,7 @@
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="48dp" android:layout_height="48dp"
android:paddingTop="8dp" android:paddingTop="8dp"
android:background="@drawable/drawer_background_selector"
android:orientation="vertical"> android:orientation="vertical">
<View <View
@ -24,8 +25,8 @@
android:paddingLeft="0dp" android:paddingLeft="0dp"
android:paddingRight="@dimen/keyline_first" android:paddingRight="@dimen/keyline_first"
android:alpha="?attr/alpha_secondary" android:alpha="?attr/alpha_secondary"
android:focusable="true"
android:clickable="true" android:clickable="true"
android:focusable="true"
android:scaleType="center" android:scaleType="center"
android:src="@drawable/ic_outline_sync_problem_24px" android:src="@drawable/ic_outline_sync_problem_24px"
android:tint="?attr/icon_tint" android:tint="?attr/icon_tint"

@ -8,20 +8,13 @@
android:fitsSystemWindows="true" android:fitsSystemWindows="true"
app:insetForeground="#4000"> app:insetForeground="#4000">
<ListView <androidx.recyclerview.widget.RecyclerView
android:id="@android:id/list" android:id="@+id/recycler_view"
android:scrollbarStyle="outsideOverlay" android:scrollbarStyle="outsideOverlay"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="1"
android:cacheColorHint="@android:color/transparent"
android:choiceMode="singleChoice"
android:clipToPadding="false" android:clipToPadding="false"
android:divider="@android:color/transparent"
android:drawSelectorOnTop="true"
android:listSelector="?attr/selectableItemBackground"
android:scrollbars="vertical" android:scrollbars="vertical"
android:scrollingCache="false"
tools:context=".NavigationDrawerFragment"/> tools:context=".NavigationDrawerFragment"/>
</org.tasks.ui.ScrimInsetsFrameLayout> </org.tasks.ui.ScrimInsetsFrameLayout>

Loading…
Cancel
Save