可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I have several items in a RecyclerView
and each item has a long
value saved with it. I'm using FastAdapter as the adapter for my RecyclerView
.
Suppose there are 7 items in the RecyclerView
with the long values: 11122
, 12321
, -98811
, 8870
, -88009
, 3398
, and -22113
.
So, what I want to do is, I want to filter the items based on the above given long values using this logic:
if (l <= 1000) {
// show items with long value <=1000
} else if (l > 1000) {
// show items with long value >1000
}
I tried various things, but nothing worked out.
UPDATE 1: Items here are a sort of different data stored in CardView
and then shown in RecyclerView
. Each card contains different data, one of which are the above given long
values. I want to filter the data based on these long
values stored in each card based on the logic given above.
Please help me with this issue and suggest some algorithm or code with which I can achieve this.
回答1:
With the amount of information given I can only suppose l
is a foreign selector value which controls the items to be displayed inside the RecyclerView
. Comment below if this is not the case, I will try to correct my answer.
I recommend implementing a custom ViewAdapter
, sending in the list of items and the selector variable l
using respective methods:
public class ItemsAdapter extends
RecyclerView.Adapter<ItemsAdapter.ItemViewHolder> {
private List<Long> mItemList;
private List<Long> mDisplayItems;
private boolean mAboveThousand = true;
public void setItemList(List<Long> list) {
mItemList = list;
updateDisplayItems();
}
public void setSelectionType(boolean aboveThousand) {
mAboveThousand = aboveThousand;
updateDisplayItems();
}
private updateDisplayItems() {
mDisplayItems.clear();
for(Long item: mItemList) {
if(/*check your contition*/) {
mDisplayItems.add(item);
}
}
notifyDataSetChanged(); //important
}
...
// Rest of implementation
}
Also, I have never used FastAdapter, but I suppose there must be some methods to override if you extend its class.
Update
Since, you are facing problems understanding the basics of using a ViewAdapter
, I would recommend learning and implementing a custom ViewAdapter
before using any library. Here's a extensive tutorial for how to implement ViewAdapter
for RecyclerView.
Now, after you have implemented the ViewAdapter you can use my piece of code to filter out cards. Basically, what the code is doing is saving a list of all the required data inside mItemList
, while mDisplayList
is a list storing the items to be displayed, which is updated every-time mAboveThousand
, which stores the user preference of above or below 1000, is set. Now this mDisplayList
must be used to inflate data inside the RecyclerView.
回答2:
Even your very basic code there would work. You can count the number of items in that range and return the number in that range. I suggest you try to do this without FastAdapter because the core concept of parsing the data based on a filter value is rightly perfectly solid. You can iterate the loop and count them, and you can iterate the loop and return the nth item.
回答3:
If you do want to keep using FastAdapter, it has a built-in filter functionality (see point number 5 in the README of the project. Note that the filter
method should be called after withFilterPredicate
and not before as shown there).
EDIT - after you pointed out that I misunderstood you before - here is my updated proposed instructions:
You need to resolve the logics of which set you want to display (using the checkboxes in the dialog you mentioned in the comment) and pass that information onto the filter, for example:
boolean displayUnderThreshold = //put the logic here - true if you want <1000
fastAdapter.filter(Boolean.toString(displayUnderThreshold));
And where you set the adapter (before the above line is called) have:
final long threshold = 1000;
fastAdapter.withFilterPredicate(new IItemAdapter.Predicate<GRModeClass>() {
@Override
public boolean filter(GRModeClass item, CharSequence constraint) {
boolean displayUnderThreshold = new Boolean(constraint.toString());
return (displayUnderThreshold ^ (item.l<threshold)); //false to remove from list
}
});
Old answer
From when I thought you wanted to filter the items according to their
ms
long values, using an external
l
long indicator:
In your code, assuming your app does get to the if
you mentioned in the question when it should - remove the fastItemAdapter.clear();
and instead of the for
loop with the if
inside it write
fastItemAdapter.filter(Long.toString(l));
and somewhere before that, preferably where you set the adapter (most likely in the onCreate
of MainActivity
) add the following:
final long threshold = 1000;
fastAdapter.withFilterPredicate(new IItemAdapter.Predicate<GRModeClass>() {
@Override
public boolean filter(GRModeClass item, CharSequence constraint) {
long indicator = new Long(constraint.toString());
return (item.ms<threshold && indicator>=threshold) || (item.ms>=threshold && indicator<threshold) ;
}
});
(Assuming here that GRModeClass
is your items' class and that the long ms
is the long you referred to that should determine whether the )
回答4:
I guess your class is like
public Class ListItem {
// .. Some other attributes
public long l;
}
Now I hope you've some function which is called when you're putting a filter in your RecyclerView
. Let the function name is toggleFilter
.
public void toggleFilter(long l) {
if(l <= 1000) {
fastAdapter.withFilterPredicate(new IItemAdapter.Predicate<Item>() {
@Override
public boolean filter(ListItem item, CharSequence constraint) {
if(item.l <= 1000) return true;
else return false;
}
});
} else if (l > 1000) {
fastAdapter.withFilterPredicate(new IItemAdapter.Predicate<Item>() {
@Override
public boolean filter(ListItem item, CharSequence constraint) {
if(item.l > 1000) return true;
else return false;
}
});
}
// Finally call notifyDataSetChanged
fastAdapter.notifyDataSetChanged();
}
回答5:
You can filter while fetching from firebase.
l <= 1000
firebaseDatabase.child(key).orderByChild("long_value_key_in_firebase").endAt(1000);
l > 1000
firebaseDatabase.child(key).orderByChild("long_value_key_in_firebase").startAt(1000);