public void showAttributes(final Collection<Geocache> caches) {
        final Context context = getContext();

        // collect attributes and counters
        final Map<String, Integer> attributes = new HashMap<>();
        CacheAttribute ca;
        for (final Geocache cache : caches) {
            for (String attr : cache.getAttributes()) {
                // OC attributes are always positive, to count them with GC attributes append "_yes"
                final String attrVal;
                ca = CacheAttribute.getByName(attr);
                if (ca != null && attr.equals(ca.rawName)) {
                    attrVal = ca.getValue(true);
                } else {
                    attrVal = attr;
                }
                final Integer count = attributes.get(attrVal);
                if (count == null) {
                    attributes.put(attrVal, 1);
                } else {
                    attributes.put(attrVal, count + 1);
                }
            }
        }

        // traverse by category and attribute order
        final ArrayList<String> orderedAttributeNames = new ArrayList<>();
        final StringBuilder attributesText = new StringBuilder();
        CacheAttributeCategory lastCategory = null;
        for (CacheAttributeCategory category : CacheAttributeCategory.getOrderedCategoryList()) {
            for (CacheAttribute attr : CacheAttribute.getByCategory(category)) {
                for (Boolean enabled : Arrays.asList(false, true)) {
                    final String key = attr.getValue(enabled);
                    final Integer value = attributes.get(key);
                    if (value != null && value > 0) {
                        if (lastCategory != category) {
                            if (lastCategory != null) {
                                attributesText.append("<br /><br />");
                            }
                            attributesText.append("<b><u>").append(category.getName(context)).append("</u></b><br />");
                            lastCategory = category;
                        } else {
                            attributesText.append("<br />");
                        }
                        orderedAttributeNames.add(key);
                        attributesText.append(attr.getL10n(enabled)).append(": ").append(value);
                    }
                }
            }
        }

        final View v = LayoutInflater.from(context).inflate(R.layout.cachelist_attributeoverview, null);
        ((WrappingGridView) v.findViewById(R.id.attributes_grid)).setAdapter(new AttributesGridAdapter((Activity) context, orderedAttributeNames, null));
        ((TextView) v.findViewById(R.id.attributes_text)).setText(HtmlCompat.fromHtml(attributesText.toString(), 0));
        Dialogs.bottomSheetDialogWithActionbar(context, v, R.string.cache_filter_attributes).show();
    }
Apply a new filter to the adapter (e.g. after filter was changed by user in menu)
main/src/main/java/cgeo/geocaching/ui/CacheListAdapter.java