Add FilterViewHolder

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

@ -9,24 +9,35 @@
</component> </component>
<component name="NullableNotNullManager"> <component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" /> <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"> <option name="myNullables">
<value> <value>
<list size="4"> <list size="10">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" /> <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="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="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="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> </list>
</value> </value>
</option> </option>
<option name="myNotNulls"> <option name="myNotNulls">
<value> <value>
<list size="4"> <list size="9">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" /> <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="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="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="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> </list>
</value> </value>
</option> </option>

@ -6,28 +6,17 @@
package com.todoroo.astrid.adapter; package com.todoroo.astrid.adapter;
import static androidx.core.content.ContextCompat.getColor;
import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.newArrayList;
import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread; import static com.todoroo.andlib.utility.AndroidUtilities.assertMainThread;
import static com.todoroo.andlib.utility.AndroidUtilities.preLollipop;
import android.app.Activity; import android.app.Activity;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.drawable.Drawable;
import android.os.Bundle; 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.BaseAdapter; import android.widget.BaseAdapter;
import android.widget.CheckedTextView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.annotation.Nullable; 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.Filter;
import com.todoroo.astrid.api.FilterListItem; import com.todoroo.astrid.api.FilterListItem;
import java.util.ArrayList; import java.util.ArrayList;
@ -38,7 +27,6 @@ import javax.inject.Inject;
import org.tasks.R; 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.sync.SynchronizationPreferences;
import org.tasks.themes.Theme; import org.tasks.themes.Theme;
import org.tasks.themes.ThemeCache; import org.tasks.themes.ThemeCache;
@ -129,46 +117,22 @@ public class FilterAdapter extends BaseAdapter {
/** Create or reuse a view */ /** Create or reuse a view */
private View newView(View convertView, ViewGroup parent, FilterListItem.Type viewType) { private View newView(View convertView, ViewGroup parent, FilterListItem.Type viewType) {
if (convertView == null) { if (convertView == null) {
ViewHolder viewHolder = new ViewHolder(); convertView = inflater.inflate(viewType.layout, parent, false);
FilterViewHolder viewHolder;
switch (viewType) { switch (viewType) {
case ITEM: case ITEM:
convertView = inflater.inflate(R.layout.filter_adapter_row, parent, false); viewHolder = new FilterViewHolder(
viewHolder.name = convertView.findViewById(R.id.name); convertView, theme.getThemeAccent(), themeCache, navigationDrawer, locale, activity);
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);
break; break;
case SEPARATOR: case SEPARATOR:
convertView = inflater.inflate(R.layout.filter_adapter_separator, parent, false); viewHolder = new FilterViewHolder();
break; break;
case SUBHEADER: case SUBHEADER:
convertView = inflater.inflate(R.layout.filter_adapter_subheader, parent, false); viewHolder = new FilterViewHolder(convertView, activity);
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)));
break; break;
default:
throw new RuntimeException();
} }
viewHolder.view = convertView;
convertView.setTag(viewHolder); convertView.setTag(viewHolder);
} }
return convertView; return convertView;
@ -198,16 +162,14 @@ public class FilterAdapter extends BaseAdapter {
@Override @Override
public View getView(int position, View convertView, @NonNull ViewGroup parent) { public View getView(int position, View convertView, @NonNull ViewGroup parent) {
FilterListItem item = getItem(position); FilterListItem item = getItem(position);
convertView = newView(convertView, parent, item.getItemType()); convertView = newView(convertView, parent, item.getItemType());
ViewHolder viewHolder = (ViewHolder) convertView.getTag(); FilterViewHolder viewHolder = (FilterViewHolder) convertView.getTag();
viewHolder.item = getItem(position);
switch (item.getItemType()) { switch (item.getItemType()) {
case ITEM: case ITEM:
populateItem(viewHolder); viewHolder.bind(item, item.equals(selected), counts.get(item));
break; break;
case SUBHEADER: case SUBHEADER:
populateHeader(viewHolder); viewHolder.bind((NavigationDrawerSubheader) item);
break; break;
case SEPARATOR: case SEPARATOR:
break; break;
@ -235,56 +197,4 @@ public class FilterAdapter extends BaseAdapter {
public View getDropDownView(int position, View convertView, @NonNull ViewGroup parent) { public View getDropDownView(int position, View convertView, @NonNull ViewGroup parent) {
return getView(position, convertView, 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.content.Intent;
import android.os.Parcel; import android.os.Parcel;
import android.os.Parcelable; import android.os.Parcelable;
import androidx.annotation.LayoutRes;
import org.tasks.R;
/** /**
* Represents an item displayed by Astrid's FilterListActivity * Represents an item displayed by Astrid's FilterListActivity
@ -57,8 +59,14 @@ public abstract class FilterListItem implements Parcelable {
} }
public enum Type { public enum Type {
ITEM, ITEM(R.layout.filter_adapter_row),
SUBHEADER, SUBHEADER(R.layout.filter_adapter_subheader),
SEPARATOR 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"?> <?xml version="1.0" encoding="utf-8"?>
<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: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"
@ -39,7 +40,7 @@
android:tint="?attr/icon_tint"/> android:tint="?attr/icon_tint"/>
<CheckedTextView <CheckedTextView
android:id="@+id/name" android:id="@+id/text"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_centerVertical="true" android:layout_centerVertical="true"

@ -12,7 +12,7 @@
android:layout_gravity="top"/> android:layout_gravity="top"/>
<ImageView <ImageView
android:id="@+id/subheader_icon" android:id="@+id/icon"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentEnd="true" android:layout_alignParentEnd="true"
@ -29,17 +29,17 @@
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"
android:visibility="visible"/> android:visibility="gone"/>
<CheckedTextView <CheckedTextView
android:id="@+id/subheader_text" android:id="@+id/text"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentLeft="true" android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" android:layout_alignParentStart="true"
android:layout_below="@id/divider" android:layout_below="@id/divider"
android:layout_toLeftOf="@id/subheader_icon" android:layout_toLeftOf="@id/icon"
android:layout_toStartOf="@id/subheader_icon" android:layout_toStartOf="@id/icon"
android:paddingTop="12dp" android:paddingTop="12dp"
android:paddingStart="@dimen/keyline_first" android:paddingStart="@dimen/keyline_first"
android:paddingEnd="@dimen/keyline_first" android:paddingEnd="@dimen/keyline_first"

Loading…
Cancel
Save