mirror of https://github.com/tasks/tasks
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
642 lines
24 KiB
Java
642 lines
24 KiB
Java
/**
|
|
* Copyright (c) 2012 Todoroo Inc
|
|
*
|
|
* See the file "LICENSE" for the full license governing this code.
|
|
*/
|
|
package com.todoroo.astrid.adapter;
|
|
|
|
import java.util.HashMap;
|
|
import java.util.List;
|
|
import java.util.concurrent.LinkedBlockingQueue;
|
|
import java.util.concurrent.ThreadPoolExecutor;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.regex.Matcher;
|
|
import java.util.regex.Pattern;
|
|
|
|
import android.app.Activity;
|
|
import android.app.PendingIntent;
|
|
import android.app.PendingIntent.CanceledException;
|
|
import android.content.BroadcastReceiver;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.content.IntentFilter;
|
|
import android.content.pm.PackageManager;
|
|
import android.content.pm.ResolveInfo;
|
|
import android.content.res.Resources;
|
|
import android.graphics.Color;
|
|
import android.os.Bundle;
|
|
import android.os.Parcelable;
|
|
import android.text.TextUtils;
|
|
import android.util.DisplayMetrics;
|
|
import android.util.Log;
|
|
import android.view.LayoutInflater;
|
|
import android.view.View;
|
|
import android.view.ViewGroup;
|
|
import android.view.ViewGroup.LayoutParams;
|
|
import android.widget.ArrayAdapter;
|
|
import android.widget.Button;
|
|
import android.widget.ImageView;
|
|
import android.widget.ListView;
|
|
import android.widget.RelativeLayout;
|
|
import android.widget.TextView;
|
|
|
|
import org.tasks.R;
|
|
import com.todoroo.andlib.service.Autowired;
|
|
import com.todoroo.andlib.service.ContextManager;
|
|
import com.todoroo.andlib.service.DependencyInjectionService;
|
|
import com.todoroo.astrid.actfm.TagViewFragment;
|
|
import com.todoroo.astrid.activity.AstridActivity;
|
|
import com.todoroo.astrid.activity.FilterListFragment;
|
|
import com.todoroo.astrid.activity.TaskListFragment;
|
|
import com.todoroo.astrid.api.AstridApiConstants;
|
|
import com.todoroo.astrid.api.AstridFilterExposer;
|
|
import com.todoroo.astrid.api.Filter;
|
|
import com.todoroo.astrid.api.FilterCategory;
|
|
import com.todoroo.astrid.api.FilterCategoryWithNewButton;
|
|
import com.todoroo.astrid.api.FilterListHeader;
|
|
import com.todoroo.astrid.api.FilterListItem;
|
|
import com.todoroo.astrid.api.FilterWithCustomIntent;
|
|
import com.todoroo.astrid.api.FilterWithUpdate;
|
|
import com.todoroo.astrid.data.RemoteModel;
|
|
import com.todoroo.astrid.helper.AsyncImageView;
|
|
import com.todoroo.astrid.service.MarketStrategy.NookMarketStrategy;
|
|
import com.todoroo.astrid.service.TaskService;
|
|
import com.todoroo.astrid.tags.TagService;
|
|
import com.todoroo.astrid.utility.Constants;
|
|
import com.todoroo.astrid.utility.ResourceDrawableCache;
|
|
|
|
public class FilterAdapter extends ArrayAdapter<Filter> {
|
|
|
|
public static interface FilterDataSourceChangedListener {
|
|
public void filterDataSourceChanged();
|
|
}
|
|
|
|
// --- style constants
|
|
|
|
public int filterStyle = R.style.TextAppearance_FLA_Filter;
|
|
public int headerStyle = R.style.TextAppearance_FLA_Header;
|
|
|
|
// --- instance variables
|
|
|
|
@Autowired
|
|
private TaskService taskService;
|
|
|
|
/** parent activity */
|
|
protected final Activity activity;
|
|
|
|
protected final Resources resources;
|
|
|
|
/** owner listview */
|
|
protected ListView listView;
|
|
|
|
/** display metrics for scaling icons */
|
|
protected final DisplayMetrics metrics = new DisplayMetrics();
|
|
|
|
/** receiver for new filters */
|
|
protected final FilterReceiver filterReceiver = new FilterReceiver();
|
|
|
|
/** row layout to inflate */
|
|
private final int layout;
|
|
|
|
/** layout inflater */
|
|
private final LayoutInflater inflater;
|
|
|
|
/** whether to skip Filters that launch intents instead of being real filters */
|
|
private final boolean skipIntentFilters;
|
|
|
|
/** whether rows are selectable */
|
|
private final boolean selectable;
|
|
|
|
/** Pattern for matching filter counts in listing titles */
|
|
private final Pattern countPattern = Pattern.compile(".* \\((\\d+)\\)$"); //$NON-NLS-1$
|
|
|
|
private final HashMap<Filter, Integer> filterCounts;
|
|
|
|
private FilterDataSourceChangedListener listener;
|
|
|
|
private final boolean nook;
|
|
|
|
|
|
// Previous solution involved a queue of filters and a filterSizeLoadingThread. The filterSizeLoadingThread had
|
|
// a few problems: how to make sure that the thread is resumed when the controlling activity is resumed, and
|
|
// how to make sure that the the filterQueue does not accumulate filters without being processed. I am replacing
|
|
// both the queue and a the thread with a thread pool, which will shut itself off after a second if it has
|
|
// nothing to do (corePoolSize == 0, which makes it available for garbage collection), and will wake itself up
|
|
// if new filters are queued (obviously it cannot be garbage collected if it is possible for new filters to
|
|
// be added).
|
|
private final ThreadPoolExecutor filterExecutor = new ThreadPoolExecutor(0, 1, 1, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
|
|
|
|
public FilterAdapter(Activity activity, ListView listView,
|
|
int rowLayout, boolean skipIntentFilters) {
|
|
this(activity, listView, rowLayout, skipIntentFilters, false);
|
|
}
|
|
|
|
public FilterAdapter(Activity activity, ListView listView,
|
|
int rowLayout, boolean skipIntentFilters, boolean selectable) {
|
|
super(activity, 0);
|
|
|
|
DependencyInjectionService.getInstance().inject(this);
|
|
|
|
this.activity = activity;
|
|
this.resources = activity.getResources();
|
|
this.listView = listView;
|
|
this.layout = rowLayout;
|
|
this.skipIntentFilters = skipIntentFilters;
|
|
this.selectable = selectable;
|
|
this.filterCounts = new HashMap<Filter, Integer>();
|
|
|
|
this.nook = (Constants.MARKET_STRATEGY instanceof NookMarketStrategy);
|
|
|
|
if (activity instanceof AstridActivity && ((AstridActivity) activity).getFragmentLayout() != AstridActivity.LAYOUT_SINGLE) {
|
|
filterStyle = R.style.TextAppearance_FLA_Filter_Tablet;
|
|
}
|
|
|
|
inflater = (LayoutInflater) activity.getSystemService(
|
|
Context.LAYOUT_INFLATER_SERVICE);
|
|
|
|
activity.getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
|
}
|
|
|
|
private void offerFilter(final Filter filter) {
|
|
if(selectable && selection == null) {
|
|
setSelection(filter);
|
|
}
|
|
filterExecutor.submit(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
try {
|
|
int size = -1;
|
|
Matcher m = countPattern.matcher(filter.listingTitle);
|
|
if(m.find()) {
|
|
String countString = m.group(1);
|
|
try {
|
|
size = Integer.parseInt(countString);
|
|
} catch (NumberFormatException e) {
|
|
// Count manually
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
if (size < 0) {
|
|
size = taskService.countTasks(filter);
|
|
filter.listingTitle = filter.listingTitle + (" (" + //$NON-NLS-1$
|
|
size + ")"); //$NON-NLS-1$
|
|
}
|
|
|
|
filterCounts.put(filter, size);
|
|
activity.runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
notifyDataSetChanged();
|
|
}
|
|
});
|
|
} catch (Exception e) {
|
|
Log.e("astrid-filter-adapter", "Error loading filter size", e); //$NON-NLS-1$ //$NON-NLS-2$
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
@Override
|
|
public boolean hasStableIds() {
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public void add(Filter item) {
|
|
super.add(item);
|
|
notifyDataSetChanged();
|
|
// load sizes
|
|
offerFilter(item);
|
|
}
|
|
|
|
public int addOrLookup(Filter filter) {
|
|
int index = getPosition(filter);
|
|
if (index >= 0) {
|
|
Filter existing = getItem(index);
|
|
transferImageReferences(filter, existing);
|
|
return index;
|
|
}
|
|
add(filter);
|
|
return getCount() - 1;
|
|
}
|
|
|
|
// Helper function: if a filter was created from serialized extras, it may not
|
|
// have the same image data we can get from the in-app broadcast
|
|
private void transferImageReferences(Filter from, Filter to) {
|
|
if (from instanceof FilterWithUpdate && to instanceof FilterWithUpdate) {
|
|
((FilterWithUpdate) to).imageUrl = ((FilterWithUpdate) from).imageUrl;
|
|
} else {
|
|
to.listingIcon = from.listingIcon;
|
|
}
|
|
}
|
|
|
|
public int adjustFilterCount(Filter filter, int delta) {
|
|
int filterCount = 0;
|
|
if (filterCounts.containsKey(filter)) {
|
|
filterCount = filterCounts.get(filter);
|
|
}
|
|
int newCount = Math.max(filterCount + delta, 0);
|
|
filterCounts.put(filter, newCount);
|
|
notifyDataSetChanged();
|
|
return newCount;
|
|
}
|
|
|
|
public int incrementFilterCount(Filter filter) {
|
|
return adjustFilterCount(filter, 1);
|
|
}
|
|
|
|
public int decrementFilterCount(Filter filter) {
|
|
return adjustFilterCount(filter, -1);
|
|
}
|
|
|
|
public void refreshFilterCount(final Filter filter) {
|
|
filterExecutor.submit(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
int size = taskService.countTasks(filter);
|
|
filterCounts.put(filter, size);
|
|
activity.runOnUiThread(new Runnable() {
|
|
|
|
@Override
|
|
public void run() {
|
|
notifyDataSetChanged();
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
|
|
public void setDataSourceChangedListener(FilterDataSourceChangedListener listener) {
|
|
this.listener = listener;
|
|
}
|
|
|
|
public void setListView(ListView listView) {
|
|
this.listView = listView;
|
|
}
|
|
|
|
/**
|
|
* Create or reuse a view
|
|
* @param convertView
|
|
* @param parent
|
|
* @return
|
|
*/
|
|
protected View newView(View convertView, ViewGroup parent) {
|
|
if(convertView == null) {
|
|
convertView = inflater.inflate(layout, parent, false);
|
|
ViewHolder viewHolder = new ViewHolder();
|
|
viewHolder.view = convertView;
|
|
viewHolder.icon = (ImageView)convertView.findViewById(R.id.icon);
|
|
viewHolder.urlImage = (AsyncImageView)convertView.findViewById(R.id.url_image);
|
|
viewHolder.name = (TextView)convertView.findViewById(R.id.name);
|
|
viewHolder.selected = (ImageView)convertView.findViewById(R.id.selected);
|
|
viewHolder.size = (TextView)convertView.findViewById(R.id.size);
|
|
viewHolder.decoration = null;
|
|
convertView.setTag(viewHolder);
|
|
}
|
|
return convertView;
|
|
}
|
|
|
|
public static class ViewHolder {
|
|
public FilterListItem item;
|
|
public ImageView icon;
|
|
public AsyncImageView urlImage;
|
|
public TextView name;
|
|
public TextView size;
|
|
public ImageView selected;
|
|
public View view;
|
|
public View decoration;
|
|
}
|
|
|
|
|
|
@Override
|
|
public View getView(int position, View convertView, ViewGroup parent) {
|
|
|
|
convertView = newView(convertView, parent);
|
|
ViewHolder viewHolder = (ViewHolder) convertView.getTag();
|
|
viewHolder.item = (FilterListItem) getItem(position);
|
|
populateView(viewHolder);
|
|
|
|
Filter selected = null;
|
|
if (activity instanceof AstridActivity) {
|
|
boolean shouldHighlightSelected = ((AstridActivity) activity).getFragmentLayout() != AstridActivity.LAYOUT_SINGLE;
|
|
if (shouldHighlightSelected) {
|
|
TaskListFragment tlf = ((AstridActivity) activity).getTaskListFragment();
|
|
selected = tlf.getFilter();
|
|
}
|
|
}
|
|
|
|
if (selected != null && selected.equals(viewHolder.item)) {
|
|
convertView.setBackgroundColor(activity.getResources().getColor(R.color.tablet_list_selected));
|
|
} else {
|
|
convertView.setBackgroundColor(activity.getResources().getColor(android.R.color.transparent));
|
|
}
|
|
|
|
return convertView;
|
|
}
|
|
|
|
@Override
|
|
public View getDropDownView(int position, View convertView, ViewGroup parent) {
|
|
return getView(position, convertView, parent);
|
|
}
|
|
/* ======================================================================
|
|
* ============================================================ selection
|
|
* ====================================================================== */
|
|
|
|
private FilterListItem selection = null;
|
|
|
|
/**
|
|
* Sets the selected item to this one
|
|
* @param picked
|
|
*/
|
|
public void setSelection(FilterListItem picked) {
|
|
selection = picked;
|
|
int scroll = listView.getScrollY();
|
|
notifyDataSetInvalidated();
|
|
listView.scrollTo(0, scroll);
|
|
}
|
|
|
|
/**
|
|
* Gets the currently selected item
|
|
* @return null if no item is to be selected
|
|
*/
|
|
public FilterListItem getSelection() {
|
|
return selection;
|
|
}
|
|
|
|
protected boolean shouldDirectlyPopulateFilters() {
|
|
return true;
|
|
}
|
|
|
|
/* ======================================================================
|
|
* ============================================================= receiver
|
|
* ====================================================================== */
|
|
|
|
/**
|
|
* Receiver which receives intents to add items to the filter list
|
|
*
|
|
* @author Tim Su <tim@todoroo.com>
|
|
*
|
|
*/
|
|
public class FilterReceiver extends BroadcastReceiver {
|
|
private final List<ResolveInfo> filterExposerList;
|
|
|
|
public FilterReceiver() {
|
|
// query astrids AndroidManifest.xml for all registered default-receivers to expose filters
|
|
PackageManager pm = ContextManager.getContext().getPackageManager();
|
|
filterExposerList = pm.queryBroadcastReceivers(
|
|
new Intent(AstridApiConstants.BROADCAST_REQUEST_FILTERS),
|
|
PackageManager.MATCH_DEFAULT_ONLY);
|
|
}
|
|
|
|
@Override
|
|
public void onReceive(Context context, Intent intent) {
|
|
try {
|
|
if (shouldDirectlyPopulateFilters()) {
|
|
for (ResolveInfo filterExposerInfo : filterExposerList) {
|
|
String className = filterExposerInfo.activityInfo.name;
|
|
AstridFilterExposer filterExposer = null;
|
|
filterExposer = (AstridFilterExposer) Class.forName(className, true, FilterAdapter.class.getClassLoader()).newInstance();
|
|
|
|
if (filterExposer != null) {
|
|
populateFiltersToAdapter(filterExposer.getFilters());
|
|
}
|
|
}
|
|
} else {
|
|
try {
|
|
Bundle extras = intent.getExtras();
|
|
extras.setClassLoader(FilterListHeader.class.getClassLoader());
|
|
final Parcelable[] filters = extras.getParcelableArray(AstridApiConstants.EXTRAS_RESPONSE);
|
|
populateFiltersToAdapter(filters);
|
|
} catch (Exception e) {
|
|
Log.e("receive-filter-" + //$NON-NLS-1$
|
|
intent.getStringExtra(AstridApiConstants.EXTRAS_ADDON),
|
|
e.toString(), e);
|
|
}
|
|
}
|
|
} catch (Exception e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
protected void populateFiltersToAdapter(final Parcelable[] filters) {
|
|
if (filters == null) {
|
|
return;
|
|
}
|
|
|
|
for (Parcelable item : filters) {
|
|
FilterListItem filter = (FilterListItem) item;
|
|
if(skipIntentFilters && !(filter instanceof Filter ||
|
|
filter instanceof FilterListHeader ||
|
|
filter instanceof FilterCategory)) {
|
|
continue;
|
|
}
|
|
onReceiveFilter((FilterListItem)item);
|
|
|
|
if (filter instanceof FilterCategory) {
|
|
Filter[] children = ((FilterCategory) filter).children;
|
|
for (Filter f : children) {
|
|
addOrLookup(f);
|
|
}
|
|
} else if (filter instanceof Filter){
|
|
addOrLookup((Filter) filter);
|
|
}
|
|
}
|
|
|
|
notifyDataSetChanged();
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void notifyDataSetChanged() {
|
|
super.notifyDataSetChanged();
|
|
if (listener != null) {
|
|
listener.filterDataSourceChanged();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Broadcast a request for lists. The request is sent to every
|
|
* application registered to listen for this broadcast. Each application
|
|
* can then add lists to this activity
|
|
*/
|
|
public void getLists() {
|
|
filterReceiver.onReceive(activity, null);
|
|
}
|
|
|
|
/**
|
|
* Call this method from your activity's onResume() method
|
|
*/
|
|
public void registerRecevier() {
|
|
IntentFilter regularFilter = new IntentFilter(AstridApiConstants.BROADCAST_SEND_FILTERS);
|
|
regularFilter.setPriority(2);
|
|
activity.registerReceiver(filterReceiver, regularFilter);
|
|
getLists();
|
|
}
|
|
|
|
/**
|
|
* Call this method from your activity's onResume() method
|
|
*/
|
|
public void unregisterRecevier() {
|
|
activity.unregisterReceiver(filterReceiver);
|
|
}
|
|
|
|
/**
|
|
* Called when an item comes through. Override if you like
|
|
* @param item
|
|
*/
|
|
public void onReceiveFilter(FilterListItem item) {
|
|
// do nothing
|
|
}
|
|
|
|
/* ======================================================================
|
|
* ================================================================ views
|
|
* ====================================================================== */
|
|
|
|
public void populateView(ViewHolder viewHolder) {
|
|
FilterListItem filter = viewHolder.item;
|
|
if(filter == null) {
|
|
return;
|
|
}
|
|
|
|
viewHolder.view.setBackgroundResource(0);
|
|
|
|
if(viewHolder.decoration != null) {
|
|
((ViewGroup)viewHolder.view).removeView(viewHolder.decoration);
|
|
viewHolder.decoration = null;
|
|
}
|
|
|
|
if(viewHolder.item instanceof FilterListHeader || viewHolder.item instanceof FilterCategory) {
|
|
viewHolder.name.setTextAppearance(activity, headerStyle);
|
|
viewHolder.name.setShadowLayer(1, 1, 1, Color.BLACK);
|
|
} else {
|
|
viewHolder.name.setTextAppearance(activity, filterStyle);
|
|
viewHolder.name.setShadowLayer(0, 0, 0, 0);
|
|
}
|
|
|
|
// update with filter attributes (listing icon, url, update text, size)
|
|
|
|
viewHolder.urlImage.setVisibility(View.GONE);
|
|
viewHolder.icon.setVisibility(View.GONE);
|
|
|
|
if(!nook && filter.listingIcon != null) {
|
|
viewHolder.icon.setVisibility(View.VISIBLE);
|
|
viewHolder.icon.setImageBitmap(filter.listingIcon);
|
|
}
|
|
|
|
// title / size
|
|
int countInt = -1;
|
|
if(filterCounts.containsKey(filter) || (!TextUtils.isEmpty(filter.listingTitle) && filter.listingTitle.matches(".* \\(\\d+\\)$"))) { //$NON-NLS-1$
|
|
viewHolder.size.setVisibility(View.VISIBLE);
|
|
String count;
|
|
if (filterCounts.containsKey(filter)) {
|
|
Integer c = filterCounts.get(filter);
|
|
countInt = c;
|
|
count = c.toString();
|
|
} else {
|
|
count = filter.listingTitle.substring(filter.listingTitle.lastIndexOf('(') + 1,
|
|
filter.listingTitle.length() - 1);
|
|
try {
|
|
countInt = Integer.parseInt(count);
|
|
} catch (NumberFormatException e) {
|
|
//
|
|
}
|
|
}
|
|
viewHolder.size.setText(count);
|
|
|
|
String title;
|
|
int listingTitleSplit = filter.listingTitle.lastIndexOf(' ');
|
|
if (listingTitleSplit > 0) {
|
|
title = filter.listingTitle.substring(0, listingTitleSplit);
|
|
} else {
|
|
title = filter.listingTitle;
|
|
}
|
|
viewHolder.name.setText(title);
|
|
} else {
|
|
viewHolder.name.setText(filter.listingTitle);
|
|
viewHolder.size.setVisibility(View.GONE);
|
|
countInt = -1;
|
|
}
|
|
|
|
if(countInt == 0 && filter instanceof FilterWithCustomIntent) {
|
|
viewHolder.name.setTextColor(Color.GRAY);
|
|
}
|
|
|
|
viewHolder.name.getLayoutParams().height = (int) (58 * metrics.density);
|
|
if(!nook && filter instanceof FilterWithUpdate) {
|
|
String defaultImageId = RemoteModel.NO_UUID;
|
|
FilterWithUpdate fwu = (FilterWithUpdate) filter;
|
|
Bundle customExtras = fwu.customExtras;
|
|
if (customExtras != null && customExtras.containsKey(TagViewFragment.EXTRA_TAG_UUID)) {
|
|
defaultImageId = customExtras.getString(TagViewFragment.EXTRA_TAG_UUID);
|
|
} else {
|
|
defaultImageId = viewHolder.name.getText().toString();
|
|
}
|
|
|
|
viewHolder.urlImage.setVisibility(View.VISIBLE);
|
|
viewHolder.urlImage.setDefaultImageDrawable(ResourceDrawableCache.getImageDrawableFromId(resources, TagService.getDefaultImageIDForTag(defaultImageId)));
|
|
viewHolder.urlImage.setUrl(((FilterWithUpdate)filter).imageUrl);
|
|
}
|
|
|
|
if (nook) {
|
|
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) viewHolder.name.getLayoutParams();
|
|
params.setMargins((int) (8 * metrics.density), 0, 0, 0);
|
|
}
|
|
|
|
if (filter.color != 0) {
|
|
viewHolder.name.setTextColor(filter.color);
|
|
}
|
|
|
|
// selection
|
|
if(selection == viewHolder.item) {
|
|
viewHolder.selected.setVisibility(View.VISIBLE);
|
|
viewHolder.view.setBackgroundColor(Color.rgb(128, 230, 0));
|
|
} else {
|
|
viewHolder.selected.setVisibility(View.GONE);
|
|
}
|
|
|
|
if(filter instanceof FilterCategoryWithNewButton) {
|
|
setupCustomHeader(viewHolder, (FilterCategoryWithNewButton) filter);
|
|
}
|
|
}
|
|
|
|
private void setupCustomHeader(ViewHolder viewHolder, final FilterCategoryWithNewButton filter) {
|
|
Button add = new Button(activity);
|
|
add.setBackgroundResource(R.drawable.filter_btn_background);
|
|
add.setCompoundDrawablesWithIntrinsicBounds(R.drawable.filter_new,0,0,0);
|
|
add.setTextColor(Color.WHITE);
|
|
add.setShadowLayer(1, 1, 1, Color.BLACK);
|
|
add.setText(filter.label);
|
|
add.setFocusable(false);
|
|
RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT,
|
|
(int)(32 * metrics.density));
|
|
lp.rightMargin = (int) (4 * metrics.density);
|
|
lp.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
|
add.setLayoutParams(lp);
|
|
((ViewGroup)viewHolder.view).addView(add);
|
|
viewHolder.decoration = add;
|
|
|
|
add.setOnClickListener(new View.OnClickListener() {
|
|
@Override
|
|
public void onClick(View v) {
|
|
try {
|
|
filter.intent.send(FilterListFragment.REQUEST_NEW_BUTTON, new PendingIntent.OnFinished() {
|
|
@Override
|
|
public void onSendFinished(PendingIntent pendingIntent, Intent intent,
|
|
int resultCode, String resultData, Bundle resultExtras) {
|
|
activity.runOnUiThread(new Runnable() {
|
|
@Override
|
|
public void run() {
|
|
clear();
|
|
}
|
|
});
|
|
}
|
|
}, null);
|
|
} catch (CanceledException e) {
|
|
// do nothing
|
|
}
|
|
}
|
|
});
|
|
}
|
|
}
|