使用RecyclerView过滤CardView,不更新卡,始终显示第一张卡

时间:2016-05-04 12:24:50

标签: android android-recyclerview android-cardview

我正在使用Cardview来填充我的Recyclerview。

我正在使用EditText字段进行过滤,这在调试时我知道这很好。

问题是,当我拨打adapter.notifyDataSetChanged();时,顶级卡会停留。 (取决于通过过滤器的卡数量)

我正在过滤的4个字符串是

Antwerpen
Deinze
Gent
Edegem 

在图片上你可以看到"ge"有2张牌,但只有2张牌...不是正确的牌。

我在我的片段中摆弄了container.removeAllViewsInLayout();,但我不知道在哪里实现它。我在OnCreateViewHolder之前的layoutInflater中执行了此操作,但过滤器工作正常,但卡片显示效果不佳。

enter image description here

更新

我已经实现了Jeffalee给出的答案,谢谢你的回复!

但没有运气,仍然遇到同样的问题,我会在下面发布我的代码。

ADAPTER:

public class GemeenteAdapter extends RecyclerView.Adapter<GemeenteAdapter.GemeenteViewHolder> {

    private List<Gemeente> gemeentes;
    private List<Gemeente> filteredList;


    public GemeenteAdapter(List<Gemeente> gemeentes, List<Gemeente> original) {
        this.gemeentes = gemeentes;
        filteredList = new ArrayList<>();
    }

    @Override
    public int getItemCount() {
        if (isFilterActive) {
            return filteredList.size();
        } else {
            return gemeentes.size();
        }
    }

    @Override
    public void onBindViewHolder(GemeenteAdapter.GemeenteViewHolder holder, int i) {
        Gemeente gemeente;
        if (isFilterActive) {
            gemeente = filteredList.get(i);
        } else {
            gemeente = gemeentes.get(i);
        }
        GemeenteViewHolder.vNaam.setText(gemeente.naam);
    }


    @Override
    public GemeenteViewHolder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View v = LayoutInflater.from(viewGroup.getContext()).inflate(R.layout.fragment_cardview_small, viewGroup, false);
        return new GemeenteViewHolder(v);
    }


    public static class GemeenteViewHolder extends RecyclerView.ViewHolder {
        protected static TextView vNaam;
        public GemeenteViewHolder(View v) {
            super(v);
            vNaam = (TextView) v.findViewById(R.id.txtNaam);
        }
    }


    /**
     * FILTER TEST 2
     */

    boolean isFilterActive = false;

    public void setFilter(String searchCriteria) {

        setFilteredItems(searchCriteria);
        isFilterActive = true;
        notifyDataSetChanged();
    }

    public void clearFilter() {
        isFilterActive = false;
        notifyDataSetChanged();
    }

    private void setFilteredItems(String searchCriteria) {
        System.out.println(searchCriteria);
        for (Gemeente item : gemeentes) {
            if (item.getNaam().toLowerCase().trim().contains(searchCriteria.toLowerCase())) {
                System.out.println(item.getNaam());
                filteredList.add(item);
            }
        }
    }

FRAGMENT:

public class FragmentSearch extends Fragment {
    //Methode om de fragment te initializeren
    public static FragmentSearch newInstance() {
        FragmentSearch fragment = new FragmentSearch();
        return fragment;
    }

    public FragmentSearch() {

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);


    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.fragment_recycler_gemeente, container, false);
        Context context = getActivity();
        RecyclerView rv = (RecyclerView) view.findViewById(R.id.cardList);

        rv.setHasFixedSize(true);


        LinearLayoutManager llm = new LinearLayoutManager(context);
        llm.setOrientation(LinearLayoutManager.VERTICAL);
        rv.setLayoutManager(llm);

        Gemeente gemeente = new Gemeente();
        final GemeenteAdapter adapter = new GemeenteAdapter(gemeente.init(),gemeente.init());

        rv.setAdapter(adapter);

        /**
         * Set filter when text is changed in EditText
         */
        final EditText yourEditText = (EditText) view.findViewById(R.id.edittext);

        yourEditText.addTextChangedListener(new TextWatcher() {

            @Override
            public void beforeTextChanged(CharSequence s, int start, int count, int after) {

            }

            @Override
            public void onTextChanged(CharSequence s, int start, int before, int count) {
            }


            @Override
            public void afterTextChanged(Editable s) {
                adapter.setFilter(yourEditText.getText().toString());


            }
        });
        return view;
    }

我希望这能为你们提供更多信息。

1 个答案:

答案 0 :(得分:2)

搜索标准&#39; ge&#39; Gent和Edegem有两个结果。您将Adapter的计数设置为正确的数量(在本例中为2)。但是在您的onBindViewHolder()方法中,您忘记了过滤过的List项目的位置。我通常用来过滤RecyclerView的内容如下。

第1步:Adapter创建自定义RecyclerView(我假设您已经这样做了)

第2步:创建第二个List项(我假设您使用ArrayList String个,这将是填充了与searchcriteria匹配的项目(在此示例中为&#39; ge&#39;以及boolean,如果Adapter应使用已过滤的List或非List,则会跟踪-filtered List<String> items = new ArrayList<>(); List<String> filteredItems = new ArrayList<>(); boolean isFilterActive = false;

setFilter(String searchCriteria)

第3步:在自定义适配器中创建clearFilter() public void setFilter(String searchCriteria) { setFilteredItems(searchCriteria); isFilterActive = true; notifyDataSetChanged(); } public void clearFilter() { isFilterActive = false; notifyDataSetChanged(); } private void setFilteredItems(String searchCriteria) { for(String item: items) { if(item.toLowerCase().contains(searchCriteria.toLowerCase())) { filteredItems.add(item); } } } 方法,如下所示:

    @Override
    public int getItemCount() {
        if(isFilterActive) {
            return filteredItems.size();
        } else {
            return items.size();
        }
    }

第4步:在每个位置返回正确的itemcount和正确的项目。要为过滤的项目返回适当的金额,只需使用:

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {
        String item;
        if (isFilterActive) {
            item = filteredItems.get(position);
        } else {
            item = items.get(position);
        }

        //TODO set the value of 'item' to your TextView
    }

要在RecyclerView中显示正确的项目,请使用此选项:

Adapter

第5步:调用过滤方法。如果需要,您只需从RecyclerView获取适配器,然后调用set / clear过滤器方法(在将其转换为自定义 MyCustomAdapter adapter = (MyCustomAdapter) myRecyclerView.getAdapter(); adapter.setFilter("ge"); 类之后),如下所示:

      adapter.clearFilter();

def create
        @activity = Activity.new(params[:activity])

        respond_to do |format|
            if @activity.save
                format.html {redirect_to activities_url}
                format.json { render activities_url, status: :created, location: @activity}
            end
        end

end

希望这有帮助!