Add FilterViewHolder

pull/848/head
Alex Baker 5 years ago
parent f0813e4934
commit 07c2b10b6b

@ -9,24 +9,35 @@
</component>
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myDefaultNotNull" value="androidx.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<list size="10">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="4" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.Nullable" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableDecl" />
<item index="9" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NullableType" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<list size="9">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
<item index="6" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.qual.NonNull" />
<item index="7" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullDecl" />
<item index="8" class="java.lang.String" itemvalue="org.checkerframework.checker.nullness.compatqual.NonNullType" />
</list>
</value>
</option>

@ -6,28 +6,17 @@
package com.todoroo.astrid.adapter;
import static androidx.core.content.ContextCompat.getColor;
import static com.google.common.collect.Lists.newArrayList;
import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread;
import static com.todoroo.andlib.utility.AndroidUtilities.preLollipop;
import android.app.Activity;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import java.util.ArrayList;
@ -38,7 +27,6 @@ import javax.inject.Inject;
import org.tasks.R;
import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.locale.Locale;
import org.tasks.sync.SynchronizationPreferences;
import org.tasks.themes.Theme;
import org.tasks.themes.ThemeCache;
@ -129,46 +117,22 @@ public class FilterAdapter extends BaseAdapter {
/** Create or reuse a view */
private View newView(View convertView, ViewGroup parent, FilterListItem.Type viewType) {
if (convertView == null) {
ViewHolder viewHolder = new ViewHolder();
convertView = inflater.inflate(viewType.layout, parent, false);
FilterViewHolder viewHolder;
switch (viewType) {
case ITEM:
convertView = inflater.inflate(R.layout.filter_adapter_row, parent, false);
viewHolder.name = convertView.findViewById(R.id.name);
if (navigationDrawer) {
viewHolder.name.setCheckMarkDrawable(null);
} else if (preLollipop()) {
ColorStateList tintList =
new ColorStateList(
new int[][] {
new int[] {-android.R.attr.state_checked},
new int[] {android.R.attr.state_checked}
},
new int[] {
ResourcesCompat.getColor(
activity.getResources(), android.R.color.transparent, null),
theme.getThemeAccent().getAccentColor()
});
Drawable original =
ContextCompat.getDrawable(activity, R.drawable.ic_outline_done_24px);
Drawable wrapped = DrawableCompat.wrap(original.mutate());
DrawableCompat.setTintList(wrapped, tintList);
viewHolder.name.setCheckMarkDrawable(wrapped);
}
viewHolder.icon = convertView.findViewById(R.id.icon);
viewHolder.size = convertView.findViewById(R.id.size);
viewHolder = new FilterViewHolder(
convertView, theme.getThemeAccent(), themeCache, navigationDrawer, locale, activity);
break;
case SEPARATOR:
convertView = inflater.inflate(R.layout.filter_adapter_separator, parent, false);
viewHolder = new FilterViewHolder();
break;
case SUBHEADER:
convertView = inflater.inflate(R.layout.filter_adapter_subheader, parent, false);
viewHolder.name = convertView.findViewById(R.id.subheader_text);
viewHolder.icon = convertView.findViewById(R.id.subheader_icon);
viewHolder.icon.setOnClickListener(
v -> activity.startActivity(new Intent(activity, SynchronizationPreferences.class)));
viewHolder = new FilterViewHolder(convertView, activity);
break;
default:
throw new RuntimeException();
}
viewHolder.view = convertView;
convertView.setTag(viewHolder);
}
return convertView;
@ -198,16 +162,14 @@ public class FilterAdapter extends BaseAdapter {
@Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) {
FilterListItem item = getItem(position);
convertView = newView(convertView, parent, item.getItemType());
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
viewHolder.item = getItem(position);
FilterViewHolder viewHolder = (FilterViewHolder) convertView.getTag();
switch (item.getItemType()) {
case ITEM:
populateItem(viewHolder);
viewHolder.bind(item, item.equals(selected), counts.get(item));
break;
case SUBHEADER:
populateHeader(viewHolder);
viewHolder.bind((NavigationDrawerSubheader) item);
break;
case SEPARATOR:
break;
@ -235,56 +197,4 @@ public class FilterAdapter extends BaseAdapter {
public View getDropDownView(int position, View convertView, @NonNull ViewGroup parent) {
return getView(position, convertView, parent);
}
private void populateItem(ViewHolder viewHolder) {
FilterListItem filter = viewHolder.item;
if (filter == null) {
return;
}
if (selected != null && selected.equals(filter)) {
if (navigationDrawer) {
viewHolder.view.setBackgroundColor(getColor(activity, R.color.drawer_color_selected));
} else {
viewHolder.name.setChecked(true);
}
} else {
viewHolder.view.setBackgroundResource(0);
viewHolder.name.setChecked(false);
}
viewHolder.icon.setImageResource(filter.icon);
viewHolder.icon.setColorFilter(
filter.tint >= 0
? themeCache.getThemeColor(filter.tint).getPrimaryColor()
: getColor(activity, R.color.text_primary));
viewHolder.name.setText(filter.listingTitle);
Integer count = counts.get(filter);
if (count == null || count == 0) {
viewHolder.size.setVisibility(View.GONE);
} else {
viewHolder.size.setText(locale.formatNumber(count));
viewHolder.size.setVisibility(View.VISIBLE);
}
}
private void populateHeader(ViewHolder viewHolder) {
NavigationDrawerSubheader filter = (NavigationDrawerSubheader) viewHolder.item;
if (filter == null) {
return;
}
viewHolder.name.setText(filter.listingTitle);
viewHolder.icon.setVisibility(filter.error ? View.VISIBLE : View.GONE);
}
static class ViewHolder {
FilterListItem item;
CheckedTextView name;
ImageView icon;
TextView size;
View view;
}
}

@ -0,0 +1,147 @@
package com.todoroo.astrid.adapter;
import static androidx.core.content.ContextCompat.getColor;
import static com.todoroo.andlib.utility.AndroidUtilities.preLollipop;
import android.app.Activity;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.view.View;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.ContextCompat;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.drawable.DrawableCompat;
import butterknife.BindView;
import butterknife.ButterKnife;
import com.todoroo.astrid.api.Filter;
import com.todoroo.astrid.api.FilterListItem;
import org.tasks.R;
import org.tasks.filters.NavigationDrawerAction;
import org.tasks.filters.NavigationDrawerSubheader;
import org.tasks.intents.TaskIntents;
import org.tasks.locale.Locale;
import org.tasks.sync.SynchronizationPreferences;
import org.tasks.themes.ThemeAccent;
import org.tasks.themes.ThemeCache;
public class FilterViewHolder {
@Nullable
@BindView(R.id.row)
View row;
@BindView(R.id.text)
CheckedTextView text;
@BindView(R.id.icon)
ImageView icon;
@Nullable
@BindView(R.id.size)
TextView size;
private ThemeCache themeCache;
private boolean navigationDrawer;
private Locale locale;
private Activity activity;
private View itemView;
FilterViewHolder(
@NonNull View itemView,
ThemeAccent accent,
ThemeCache themeCache,
boolean navigationDrawer,
Locale locale,
Activity activity) {
ButterKnife.bind(this, itemView);
this.itemView = itemView;
this.themeCache = themeCache;
this.navigationDrawer = navigationDrawer;
this.locale = locale;
this.activity = activity;
if (navigationDrawer) {
text.setCheckMarkDrawable(null);
} else if (preLollipop()) {
ColorStateList tintList =
new ColorStateList(
new int[][] {
new int[] {-android.R.attr.state_checked}, new int[] {android.R.attr.state_checked}
},
new int[] {
ResourcesCompat.getColor(
activity.getResources(), android.R.color.transparent, null),
accent.getAccentColor()
});
Drawable original = ContextCompat.getDrawable(activity, R.drawable.ic_outline_done_24px);
Drawable wrapped = DrawableCompat.wrap(original.mutate());
DrawableCompat.setTintList(wrapped, tintList);
text.setCheckMarkDrawable(wrapped);
}
}
FilterViewHolder(@NonNull View itemView, Activity activity) {
ButterKnife.bind(this, itemView);
icon.setOnClickListener(
v -> activity.startActivity(new Intent(activity, SynchronizationPreferences.class)));
}
FilterViewHolder() {
}
public void bind(FilterListItem filter, boolean selected, Integer count) {
if (selected) {
if (navigationDrawer) {
itemView.setBackgroundColor(getColor(activity, R.color.drawer_color_selected));
} else {
text.setChecked(true);
}
} else {
itemView.setBackgroundResource(0);
text.setChecked(false);
}
icon.setImageResource(filter.icon);
icon.setColorFilter(
filter.tint >= 0
? themeCache.getThemeColor(filter.tint).getPrimaryColor()
: getColor(activity, R.color.text_primary));
text.setText(filter.listingTitle);
if (count == null || count == 0) {
size.setVisibility(View.GONE);
} else {
size.setText(locale.formatNumber(count));
size.setVisibility(View.VISIBLE);
}
row.setOnClickListener(
v -> {
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) {
text.setText(filter.listingTitle);
icon.setVisibility(filter.error ? View.VISIBLE : View.GONE);
}
}

@ -9,6 +9,8 @@ package com.todoroo.astrid.api;
import android.content.Intent;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.LayoutRes;
import org.tasks.R;
/**
* Represents an item displayed by Astrid's FilterListActivity
@ -57,8 +59,14 @@ public abstract class FilterListItem implements Parcelable {
}
public enum Type {
ITEM,
SUBHEADER,
SEPARATOR
ITEM(R.layout.filter_adapter_row),
SUBHEADER(R.layout.filter_adapter_subheader),
SEPARATOR(R.layout.filter_adapter_separator);
public final int layout;
Type(@LayoutRes int layout) {
this.layout = layout;
}
}
}

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<com.todoroo.astrid.adapter.CheckableRelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/row"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:paddingTop="12dp"
@ -39,7 +40,7 @@
android:tint="?attr/icon_tint"/>
<CheckedTextView
android:id="@+id/name"
android:id="@+id/text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"

@ -12,7 +12,7 @@
android:layout_gravity="top"/>
<ImageView
android:id="@+id/subheader_icon"
android:id="@+id/icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
@ -29,17 +29,17 @@
android:scaleType="center"
android:src="@drawable/ic_outline_sync_problem_24px"
android:tint="?attr/icon_tint"
android:visibility="visible"/>
android:visibility="gone"/>
<CheckedTextView
android:id="@+id/subheader_text"
android:id="@+id/text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_below="@id/divider"
android:layout_toLeftOf="@id/subheader_icon"
android:layout_toStartOf="@id/subheader_icon"
android:layout_toLeftOf="@id/icon"
android:layout_toStartOf="@id/icon"
android:paddingTop="12dp"
android:paddingStart="@dimen/keyline_first"
android:paddingEnd="@dimen/keyline_first"

Loading…
Cancel
Save