アダプターのgetFilter()。filter(keyword)funcを呼び出すlistViewと検索フィールドを取得しました。非常にうまく機能していますが、listViewsのオブジェクトのさまざまなタグを検索する別のフィルターを追加したいと思います。
だから私は私のアダプターのために2つのフィルターが必要です、これのための最良の解決策は何ですか?
ありがとう、
アダプターのgetFilter()。filter(keyword)funcを呼び出すlistViewと検索フィールドを取得しました。非常にうまく機能していますが、listViewsのオブジェクトのさまざまなタグを検索する別のフィルターを追加したいと思います。
だから私は私のアダプターのために2つのフィルターが必要です、これのための最良の解決策は何ですか?
ありがとう、
自分でフィルターを実装したと思います。2つのフィルターを取得できないため、フィルターに適用するフィルターの種類を定義するフィールドを含めることができます(フィルターで複数のフィルターを使用できます)。
フィルタを使用する前に、フィルタのフィールドを必要な値に設定してください。
または:
キーワードを使用して、適用するフィルターを選択します。キーワードの先頭に、適用するフィルターを定義するいくつかの文字を追加します。を使用String.beginsWith()
すると、どのタイプのフィルタリングを適用する必要があるかを確認できます。これは、フィルター自体で実行する必要があります。getFilter.filter(keyword)の呼び出し元は、文字列の前に追加する必要がある文字を知っている必要があります。
Listviewで複数のフィルターを適用し、ListViewで複数の並べ替えを使用するには、次のリンクを試してください。
私も同様のニーズがあり、自分で書いた。フィルタは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);
}