Androidアプリを使用するツールバー、SlidingTabLayout、およびフラグメントを保持するViewPagerの内部に検索機能を実装する必要があります。各フラグメントの内部には、アイテムのリストを含むRecyclerViewがあります。
RecyclerViewデータは別のクラス(DataAccess.Java)で静的に定義され、これらのリストは更新され、RecyclerViewは(新しいデータを渡さずに)呼び出すだけで更新されます
mRecyclerView.getAdapter().notifyDataSetChanged();
データを変更せずに、ユーザーがツールバー内の[戻る]ボタンを押してフィルターを削除し、最初のリストを表示した後で、RecyclerViewを一時的にフィルターする簡単な方法はありますか?.
ツールバーメニュー内の検索アイコンを押す前に:
したがって、ユーザーが「Josip ...」と入力すると、フィルターがアクティブになります
そして、SearchViewでXボタンを押すと、ユーザーは以前と同じデータをフィルターなしで取得します。
@Override
public boolean onQueryTextChange(String newText) {
// filter data (temporary remove all items from DataAccess.list that don't .startsWith(newText)
}
@Override
public boolean onQueryTextSubmit(String query)
// Doesn't help if I revert deleted items here
}
@Override
public boolean onQueryTextSubmit(String query){
((ItemAdapter) myRecList.getAdapter()).setFilter(query)
}
public class ItemAdapter extends RecyclerView.Adapter<ItemAdapter.ViewHolder> {
private List<String> visibleObjects;
private List<String> allObjects;
.....
public void flushFilter(){
visibleObjects=new ArrayList<>();
visibleObjects.addAll(allObjects);
notifyDataSetChanged();
}
public void setFilter(String queryText) {
visibleObjects = new ArrayList<>();
constraint = constraint.toString().toLowerCase();
for (String item: allObjects) {
if (item.toLowerCase().contains(queryText))
visibleObjects.add(item);
}
notifyDataSetChanged();
}
}
コメントとして追加したかったのですが、評判が低かったため...投稿に回答しています。このメソッドはif(item.toLowerCase()。contains(queryText))の場合は正常に機能しますが、最初の反復で一致が見つからない場合はどうすればよいですか。
for (RouteByATMList.Route_ATM item: Main_ATMItemList)
{
if (item.ATMNumber.contains(queryText)) {
visibleObjects.add(item);
}else {
Toast.makeText(mContext,"No search result found!",Toast.LENGTH_SHORT).show();
break;
}
}
私は上司から答えを得ました、それが役に立てば幸いです。
public void setFilter(String queryText) {
visibleObjects = new ArrayList<>();
for (RouteByATMList.Route_ATM item: Main_ATMItemList)
{
if (item.ATMNumber.contains(queryText))
{
visibleObjects.add(item);
}
}
if(visibleObjects.size()==0){
Toast.makeText(mContext,"No search result found!",Toast.LENGTH_SHORT).show();
}
notifyDataSetChanged();
Log.e("dataset changed","dataset changed");
}
私は与えられた、受け入れられた答えに反対しません。パフォーマンスの落とし穴が生じる可能性があります。 Filterabe
インターフェースを使用する必要があります。これを実装すると、非同期にフィルタリングを行ったol'good ListView
として動作します。次に必要なのは、独自のFilter
を記述して、オーバーライドされたgetFilter()
メソッドでインスタンス化することだけです。
私の場合、Filter
を使用して、多くの(そう、多くの)アイテムのアダプターをソートしました。 UIスレッドで並べ替えるのはジャンキーでした。
だから私はこの抽象クラスを持っていました
public abstract class BaseFilterableRecyclerViewAdapter<VH extends RecyclerView.ViewHolder> extends RecyclerView.Adapter<VH> implements Filterable {
private Context mContext;
public BaseFilterableRecyclerViewAdapter(Context context) {
this.mContext = context;
}
public abstract void sort(SortingFilter.Sort sortingStrategy);
//...Other methods
}
そして継承するクラス:
public class ItemAdapter extends BaseFilterableRecyclerViewAdapter<RecyclerView.ViewHolder>{
//... RecyclerView methods
@Override
public Filter getFilter() {
return new SortingFilter(mData) {
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results.values != null) {
int last = mData.size();
mData = (List<Product>) results.values;
notifyDataSetChanged();
}
}
};
}
@Override
public void sort(SortingFilter.Sort sortingStrategy) {
getFilter().filter(sortingStrategy.toString());
}
}