Как применить несколько фильтров к адаптеру?

У меня есть listView и поле поиска, которое вызывает мой адаптер getFilter().filter(keyword) func. Это работает очень хорошо, но я хотел бы добавить другой фильтр, который ищет в разных тегах моих объектов listViews.

Итак, мне нужно два фильтра для моего адаптера, какое лучшее решение для этого?

Спасибо,


person Adam Varhegyi    schedule 09.07.2012    source источник


Ответы (3)


Я предполагаю, что вы реализовали фильтр самостоятельно. Поскольку вы не можете получить два фильтра, у вас может быть поле в фильтре, которое определяет, какой тип фильтрации должен применяться (вы можете использовать несколько фильтров в своем фильтре).

Перед использованием фильтра установите в поле фильтра нужное значение.

Or:

Используйте ключевое слово, чтобы выбрать фильтр для применения. Добавьте в начало ключевого слова несколько символов, определяющих применяемый фильтр. С помощью String.beginsWith() вы можете проверить, какой тип фильтрации должен применяться. Это нужно сделать в самом фильтре. Вызывающий getFilter.filter(keyword) должен знать, какие символы должны быть добавлены перед строкой.

person RaphMclee    schedule 27.07.2012
comment
Я действительно не понимаю идею. Вы можете объяснить больше? извините, я нуб, но мне нужно это в моем проекте - person Philipus Silaen; 24.04.2016
comment
@PhilipusSilaen, можете ли вы объяснить свой вариант использования, чтобы мы могли найти правильное решение вашей проблемы. Может быть, вам стоит написать отдельный вопрос. - person RaphMclee; 29.04.2016
comment
эй, я уже разместил свой вопрос здесь (stackoverflow.com/questions/36825456/) пожалуйста, помогите мне - person Philipus Silaen; 29.04.2016

Примените множественный фильтр в Listview, а также используйте множественную сортировку в ListView, попробуйте эту ссылку:

https://github.com/apurv3039/filter_listview/tree/master

person Apoorv Bambarde    schedule 03.10.2016
comment
Этот проект не завершен и даже не содержит кода, применяющего множественный фильтр. Реализация адаптера даже не реализует Filterable. - person punisher_malade; 20.10.2016
comment
зачем вы дали эту ссылку? есть релевантность? - person Amit Vaghela; 16.05.2018

У меня была похожая потребность, и я написал для себя. Фильтр сочетается с оператором AND. Держите его как можно проще. Не утверждаю, что он идеален, но он работает для меня. Вы можете изменить в соответствии с вашими потребностями.

Модель элемента

public class ItemModel {

    public int ID;
    public int rating;
    public float avg;
    public String name;
    public String shortDesc;
    public boolean read;
}

И парсер.java

/**
 * This class is designed to be simple for parsing a filter of the form
 *             "object field name: variable type: operator: value"
 *
 * "ID:int:>:20";"name:string:=:20"
 * Where ';' means AND, however this is not parsed here.
 * If you need different logic, use the results.O
 *
 * Multiple filters seperated by ';'
 */
public class Parser {

    private static final String TAG = "Parser";


    public static boolean isPassingTheFiler(String filter, String field, String val) {

        String[] mGroups = parseMainGroups(filter);

        for (String mGroup : mGroups) {

            Log.e(TAG,"Working on the main Group " +mGroup );

            String[] subCommand = parseSubCommand(mGroup);

            if ( field.equals(subCommand[0])) {
                if (!processCommand(subCommand, val)) {
                    return false;
                }
            }
        }

        return true;
    }

    /**
     * parses that data assuming they are all sperated by `;`
     */
    public static String[] parseMainGroups(CharSequence commands) {

        String buffer = commands.toString();

        String parts[] = buffer.split(";");

        return parts;
    }

    public static String[] parseSubCommand(String subCommand) {

        //remove the double quotes.
        String buffer = removeDoubleQuotes(subCommand.toString());

        String parts[] = buffer.split(":");

        return parts;
    }

    public static String removeDoubleQuotes(String quotedString) {

        if ((quotedString.charAt(0) == '\"') && (quotedString.charAt(quotedString.length() - 1) == '\"')) {
            return quotedString.substring(1, quotedString.length() - 1);
        } else {
            Log.e(TAG, quotedString + " doesn't contained in double quotes!\nReturned empty string!!!");
            return "";
        }
    }

    public static boolean processCommand(String[] subCommand, String val) {

        switch (subCommand[1]) {

            case "int":
                Log.e("TAG","\tint Filer");
                return intStatement(subCommand, val);
            case "float":
                Log.e("TAG","\tfloat Filer");
                return floatStatement(subCommand, val);
            case "string":
                Log.e("TAG","\tString Filer");
                return stringStatement(subCommand, val);

            default:
                return false;
        }
    }

    /**
     * Evaluate the Int statement's correctness with the given INT value
     */
    public static boolean intStatement(String[] subCommand, String cVal) {

        String operString = subCommand[2];

        int iVal;
        int val;

        try {
            iVal = Integer.parseInt(subCommand[3]);
            val = Integer.parseInt(cVal);
        } catch (NumberFormatException e) {
            return false;
        }

        switch (operString) {

            case "=":
                return val == iVal;
            case "<":
                return val < iVal;
            case ">":
                return val > iVal;
            case "<=":
                return val <= iVal;
            case ">=":
                return val >= iVal;
            case "!=":
                return val != iVal;
            case "s" :
                //digit search as string. We look into string from that we already have
                return cVal.contains(subCommand[3]);

            default:
                Log.e("Parser", "invalid Integer Operation");

                return false;
        }
    }


    public static boolean floatStatement(String[] subCommand, String cVal) {

        String operString = subCommand[2];
        float iVal;
        float val;

        try {
            iVal = Float.parseFloat(subCommand[3]);
            val = Float.parseFloat(cVal);

        } catch (NumberFormatException e) {
            return false;
        }

        switch (operString) {

            case "=":
                return val == iVal;
            case "<":
                return val < iVal;
            case ">":
                return val > iVal;
            case "<=":
                return val <= iVal;
            case ">=":
                return val >= iVal;
            case "!=":
                return val != iVal;
            case "s" :
                //digit search as string. We look into string from that we already have
                return cVal.contains(subCommand[3]);

            default:

                Log.e("Parser", "invalid Integer Operation");

                return false;
        }
    }

    public static boolean stringStatement(String[] subCommand, String val) {

        String operString = subCommand[2];

        switch (operString) {

            case "=":
                //equality
                return val.equals(subCommand[3]);
            case "<":
                //substring
                return val.contains(subCommand[3]);
            case "sw":
                //prefix
                return val.startsWith(subCommand[3]);
            case "ew":
                //postfix
                return val.endsWith(subCommand[3]);

            default:

                Log.e("Parser", "invalid Integer Operation");

                return false;
        }
    }
}

Частный класс фильтра в адаптере.

    private class ItemFilter extends Filter {

        @Override
        protected FilterResults performFiltering(CharSequence constraint) {
            String charString = constraint.toString();
            String[] parts;

            FilterResults filterResults = new FilterResults();

            if (charString.isEmpty()) {
                filterResults.values = new ArrayList<>(itemList);
            } else {
                //Parse the main group
                parts = parseMainGroups(charString);

                if (parts.length < 1) {
                    filterResults.values =  new ArrayList<>(itemList);

                } else {

                    List<ItemModel> filteredList = new ArrayList<>();

                    for (ItemModel row : itemList) {

                        if ( !isPassingTheFiler(charString,"ID",""+row.ID)) {
                            continue;
                        } else {
                            Log.e("Filter", "passed on ID" + row.ID);
                        }
                        if ( !isPassingTheFiler(charString,"name",""+row.name)) {
                            continue;
                        } else {
                            Log.e("Filter", "passed on name" + row.name);
                        }
                        // passed every test asked. If empty they returned true!
                        filteredList.add(row);
                    }

                    filterResults.values = new ArrayList<>(filteredList);
                }
            }

            return filterResults;
        }

        @Override
        protected void publishResults(CharSequence constraint, FilterResults results) {

            updateList((List<ItemModel>) results.values);

        }
    }

И функция члена updateList для адаптера

    public void updateList(List<ItemModel> newList) {
        DiffUtil.DiffResult diffResult = DiffUtil.calculateDiff(new ItemDiffUtilCallback(newList, itemListFiltered));

        itemListFiltered.clear();
        itemListFiltered.addAll(newList);
        diffResult.dispatchUpdatesTo(this);

        Log.e("TAG", "updated with dispatch");
    }

И дифутилы, которые помогают хорошей анимации

public class ItemDiffUtilCallback extends DiffUtil.Callback {

    private List<ItemModel> oldList;
    private List<ItemModel> newList;

    public ItemDiffUtilCallback(List<ItemModel> newList, List<ItemModel> oldList) {
        this.newList = newList;
        this.oldList = oldList;
    }

    @Override
    public int getOldListSize() {
        return oldList.size();
    }

    @Override
    public int getNewListSize() {
        return newList.size();
    }

    @Override
    public boolean areItemsTheSame(int oldItemPosition, int newItemPosition) {
        return oldList.get(oldItemPosition).ID == newList.get(newItemPosition).ID;
    }

    @Override
    public boolean areContentsTheSame(int oldItemPosition, int newItemPosition) {

         return oldList.get(oldItemPosition).equals(newList.get(newItemPosition));
    }


    @Override
    public Object getChangePayload(int oldItemPosition, int newItemPosition) {
        return super.getChangePayload(oldItemPosition, newItemPosition);
    }
person kelalaka    schedule 30.01.2020