web-dev-qa-db-ja.com

SearchViewの一時的なフィルタリングを備えたツールバーRecyclerView

Androidアプリを使用するツールバー、SlidingTabLayout、およびフラグメントを保持するViewPagerの内部に検索機能を実装する必要があります。各フラグメントの内部には、アイテムのリストを含むRecyclerViewがあります。

RecyclerViewデータは別のクラス(DataAccess.Java)で静的に定義され、これらのリストは更新され、RecyclerViewは(新しいデータを渡さずに)呼び出すだけで更新されます

mRecyclerView.getAdapter().notifyDataSetChanged();

データを変更せずに、ユーザーがツールバー内の[戻る]ボタンを押してフィルターを削除し、最初のリストを表示した後で、RecyclerViewを一時的にフィルターする簡単な方法はありますか?.

ツールバーメニュー内の検索アイコンを押す前に:

enter image description here

したがって、ユーザーが「Josip ...」と入力すると、フィルターがアクティブになります

enter image description here

そして、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
}
15
fpopic
@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();
    }
}
24
merovingen

コメントとして追加したかったのですが、評判が低かったため...投稿に回答しています。このメソッドは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");
    }
3
Ravi Yadav

私は与えられた、受け入れられた答えに反対しません。パフォーマンスの落とし穴が生じる可能性があります。 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());
    }

}
3