如何在适配器上应用多个过滤器?

时间:2012-07-09 07:45:57

标签: android android-listview android-adapter

我有一个listView和一个调用我的Adapter的getFilter()。filter(keyword)func的搜索字段。 它工作得非常好,但我想添加一个其他过滤器,用于搜索listViews对象的不同标签。

所以我需要为我的适配器安装两个过滤器,这是最好的解决方案吗?

谢谢,

3 个答案:

答案 0 :(得分:4)

我想你自己实现了过滤器。由于您无法获得两个过滤器,因此您可以在过滤器中使用一个字段来定义应该应用的过滤类型(您可以在过滤器中使用多个过滤器)。

在使用过滤器之前,将过滤器的字段设置为所需的值。

或者:

使用关键字选择要应用的过滤器。在关键字的开头添加一些定义要应用的过滤器的字符。使用String.beginsWith(),您可以检查应用的过滤类型。这必须在Filter本身完成。 getFilter.filter(keyword)的调用者必须知道字符串前面添加了哪些字符。

答案 1 :(得分:0)

在Listview中应用多个过滤器,并在ListView中使用多重排序,请尝试以下链接:

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

答案 2 :(得分:0)

我有类似的需求,并且为自己写过书。该过滤器与AND运算符组合在一起。使其尽可能简单。没有声称它是完美的,但对我有用。您可以根据需要进行更改。

ItemModel

public class ItemModel {

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

还有parser.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");
    }

还有有助于制作精美动画的difutils

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);
    }