【问题标题】:Refresh SearchView, when changing RecyclerView item更改 RecyclerView 项时刷新 SearchView
【发布时间】:2020-05-02 18:07:56
【问题描述】:

我正在努力解决一个问题 - 尝试在 RecyclerView 项目被删除后刷新搜索结果。

现在,当我过滤掉项目并删除其中一个时,RecyclerView 会再次显示所有其他项目,而没有应用搜索过滤器。 但是如何实现搜索过滤器,即使在 RecyclerView 列表发生变化时它仍然存在?

这是我在主要活动中加载数据的方式:

private void loadData(final int ordernumber) {

    orderLineViewModel.getAllUnCheckedSingleOrderLines(ordernumber).observe(this, new Observer<List<OrderLine>>() {
        @Override
        public void onChanged(List<OrderLine> orderLines) {

            orderLineListAdapter.setOrderLines(orderLines);
        }
    });
}

这是我在主要活动中的 SearchView 代码:

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String s) {
            orderLineListAdapter.getFilter().filter(s);
            return false;
        }

        @Override
        public boolean onQueryTextChange(String s) {
            orderLineListAdapter.getFilter().filter(s);
            return false;
        }
    });

这是我在 RecyclerViewAdapter 中的过滤器:

public void setOrderLines(List<OrderLine> orderLines) {

    orderLineList = orderLines;
    orderLineListFull = new ArrayList<>(orderLines);

    notifyDataSetChanged();
}

@Override
public Filter getFilter() {
    return orderFilter;
}

private Filter orderFilter = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence charSequence) {
        List<OrderLine> filteredList = new ArrayList<>();

        if (charSequence == null || charSequence.length() == 0){
            filteredList.addAll(orderLineListFull);
        }else {
            String filterPattern = charSequence.toString().toLowerCase().trim();

            for (OrderLine orderLine: orderLineListFull){
                if (orderLine.getProductCode().toLowerCase().contains(filterPattern)){
                    filteredList.add(orderLine);
                }
            }
        }

        FilterResults results = new FilterResults();
        results.values = filteredList;

        return results;
    }

    @Override
    protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
        orderLineList.clear();
        orderLineList.addAll((List)filterResults.values);
        notifyDataSetChanged();
    }
};

在 RecyclerView 项目中按下复选框:

@Override
    public void onClick(View view) {

        int position = getAdapterPosition();
        OrderLine line = orderLineList.get(position);

        switch (view.getId()) {

            case R.id.foam_in_checkbox:

                if (okCheckBox.isChecked()) {

                    line.setIsArrived(1);
                    orderLineViewModel.update(line);
                    orderLineList.remove(position);
                    notifyItemRemoved(position);

                } else {
                    line.setIsArrived(0);
                    orderLineViewModel.update(line);
                }
                break;
        }
    }

编辑:添加了整个 RecyclerViewAdapter:

public class OrderLineListAdapter extends 

RecyclerView.Adapter<OrderLineListAdapter.OrderLineViewHolder> implements Filterable {

private Context context;
private final LayoutInflater orderLineInflater;
private List<OrderLine> orderLineList;
private List<OrderLine> orderLineListFull;
private OrderLineViewModel orderLineViewModel;

public OrderLineListAdapter(Context context) {
    this.context = context;
    orderLineInflater = LayoutInflater.from(context);
    orderLineViewModel = ViewModelProviders.of((FoamInActivity) context).get(OrderLineViewModel.class);
}

@NonNull
@Override
public OrderLineViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View view = orderLineInflater.inflate(R.layout.foam_in_single_line, parent, false);

    return new OrderLineViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull OrderLineViewHolder orderLineViewHolder, int position) {

    if (orderLineList != null) {

        OrderLine current = orderLineList.get(position);

        orderLineViewHolder.productCodeTextView.setText(current.getProductCode());
        orderLineViewHolder.orderedQuantityTextView.setText(String.valueOf(current.getOrderedQuantity()));

        orderLineViewHolder.okCheckBox.setOnCheckedChangeListener(null);
        orderLineViewHolder.okCheckBox.setChecked(false);

    } else {
        orderLineViewHolder.productCodeTextView.setText(R.string.no_open_positions);
    }
}

public void setOrderLines(List<OrderLine> orderLines) {

    orderLineList = orderLines;
    orderLineListFull = new ArrayList<>(orderLines);

    notifyDataSetChanged();
}

@Override
public int getItemCount() {

    if (orderLineList != null) {
        return orderLineList.size();
    } else {
        return 0;
    }
}

public class OrderLineViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView productCodeTextView, orderedQuantityTextView;
    public CheckBox okCheckBox;

    public OrderLineViewHolder(@NonNull View itemView) {
        super(itemView);

        productCodeTextView = itemView.findViewById(R.id.foam_in_product_code);
        orderedQuantityTextView = itemView.findViewById(R.id.foam_in_quantity);
        okCheckBox = itemView.findViewById(R.id.foam_in_checkbox);

        okCheckBox.setOnClickListener(this);
        productCodeTextView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {

        int position = getAdapterPosition();

        OrderLine line = orderLineList.get(position);

        switch (view.getId()) {

            case R.id.foam_in_checkbox:

                if (okCheckBox.isChecked()) {

                    line.setIsArrived(1);
                    orderLineViewModel.update(line);
                    orderLineList.remove(position);
                    notifyItemRemoved(position);

                } else {
                    line.setIsArrived(0);
                    orderLineViewModel.update(line);
                }

                break;

            case R.id.foam_in_product_code:
                Toast.makeText(context, "Status: " + line.getIsArrived(), Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

@Override
public Filter getFilter() {
    return orderFilter;
}

private Filter orderFilter = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence charSequence) {
        List<OrderLine> filteredList = new ArrayList<>();

        if (charSequence == null || charSequence.length() == 0){
            filteredList.addAll(orderLineListFull);
        }else {
            String filterPattern = charSequence.toString().toLowerCase().trim();

            for (OrderLine orderLine: orderLineListFull){
                if (orderLine.getProductCode().toLowerCase().contains(filterPattern)){
                    filteredList.add(orderLine);
                }
            }
        }

        FilterResults results = new FilterResults();
        results.values = filteredList;

        return results;
    }

    @Override
    protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
        orderLineList.clear();
        orderLineList.addAll((List)filterResults.values);
        notifyDataSetChanged();
    }
};

【问题讨论】:

  • 请贴出RecyclreviewAdapter的完整代码
  • 您好!添加了整个 RecyclerViewAdapter!
  • 一旦适配器列表被过滤。从该过滤列表中删除项目并通知适配器。它将保持您的过滤器完好无损。您还需要从原始列表中删除该项目。

标签: java android android-studio android-recyclerview


【解决方案1】:

整个 RecyclerViewAdapter:

public class OrderLineListAdapter extends RecyclerView.Adapter<OrderLineListAdapter.OrderLineViewHolder> implements Filterable {

private Context context;
private final LayoutInflater orderLineInflater;
private List<OrderLine> orderLineList;
private List<OrderLine> orderLineListFull;
private OrderLineViewModel orderLineViewModel;

public OrderLineListAdapter(Context context) {
    this.context = context;
    orderLineInflater = LayoutInflater.from(context);
    orderLineViewModel = ViewModelProviders.of((FoamInActivity) context).get(OrderLineViewModel.class);
}

@NonNull
@Override
public OrderLineViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {

    View view = orderLineInflater.inflate(R.layout.foam_in_single_line, parent, false);

    return new OrderLineViewHolder(view);
}

@Override
public void onBindViewHolder(@NonNull OrderLineViewHolder orderLineViewHolder, int position) {

    if (orderLineList != null) {

        OrderLine current = orderLineList.get(position);

        orderLineViewHolder.productCodeTextView.setText(current.getProductCode());
        orderLineViewHolder.orderedQuantityTextView.setText(String.valueOf(current.getOrderedQuantity()));

        orderLineViewHolder.okCheckBox.setOnCheckedChangeListener(null);
        orderLineViewHolder.okCheckBox.setChecked(false);

    } else {
        orderLineViewHolder.productCodeTextView.setText(R.string.no_open_positions);
    }
}

public void setOrderLines(List<OrderLine> orderLines) {

    orderLineList = orderLines;
    orderLineListFull = new ArrayList<>(orderLines);

    notifyDataSetChanged();
}

@Override
public int getItemCount() {

    if (orderLineList != null) {
        return orderLineList.size();
    } else {
        return 0;
    }
}

public class OrderLineViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {

    public TextView productCodeTextView, orderedQuantityTextView;
    public CheckBox okCheckBox;

    public OrderLineViewHolder(@NonNull View itemView) {
        super(itemView);

        productCodeTextView = itemView.findViewById(R.id.foam_in_product_code);
        orderedQuantityTextView = itemView.findViewById(R.id.foam_in_quantity);
        okCheckBox = itemView.findViewById(R.id.foam_in_checkbox);

        okCheckBox.setOnClickListener(this);
        productCodeTextView.setOnClickListener(this);
    }

    @Override
    public void onClick(View view) {

        int position = getAdapterPosition();

        OrderLine line = orderLineList.get(position);

        switch (view.getId()) {

            case R.id.foam_in_checkbox:

                if (okCheckBox.isChecked()) {

                    line.setIsArrived(1);
                    orderLineViewModel.update(line);
                    orderLineList.remove(position);
                    notifyItemRemoved(position);

                } else {
                    line.setIsArrived(0);
                    orderLineViewModel.update(line);
                }

                break;

            case R.id.foam_in_product_code:
                Toast.makeText(context, "Status: " + line.getIsArrived(), Toast.LENGTH_SHORT).show();
                break;
        }
    }
}

@Override
public Filter getFilter() {
    return orderFilter;
}

private Filter orderFilter = new Filter() {
    @Override
    protected FilterResults performFiltering(CharSequence charSequence) {
        List<OrderLine> filteredList = new ArrayList<>();

        if (charSequence == null || charSequence.length() == 0){
            filteredList.addAll(orderLineListFull);
        }else {
            String filterPattern = charSequence.toString().toLowerCase().trim();

            for (OrderLine orderLine: orderLineListFull){
                if (orderLine.getProductCode().toLowerCase().contains(filterPattern)){
                    filteredList.add(orderLine);
                }
            }
        }

        FilterResults results = new FilterResults();
        results.values = filteredList;

        return results;
    }

    @Override
    protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
        orderLineList.clear();
        orderLineList.addAll((List)filterResults.values);
        notifyDataSetChanged();
    }
};

}

【讨论】:

  • 您好!我回复了 androidbash 请求,添加了整个 RecyclerViewAdapter。
  • 请不要将问题更新为答案,您可以改为编辑问题
  • 谢谢你,我没注意到是你问的:)
【解决方案2】:

附加示例:请将您的适配器更新为

public class ListAdapter extends RecyclerView.Adapter<ListViewHolder> implements
        Filterable {

    private List<Status> statusList;
    private List<Status> statusListFiltered;
    private OnClickActionListener listener;

    public ListAdapter(List<Status> statusList,
            OnClickActionListener listener) {
        this.statusList = statusList;
        this.statusListFiltered = statusList;
        this.listener = listener;
    }

    @Override
    public void onBindViewHolder(@NonNull ListViewHolder holder, int position) {
        Status status = statusListFiltered.get(position);
        holder.cellListBinding.setStatus(status);
    }

    @Override
    public int getItemCount() {
        if (statusListFiltered != null) {
            return statusListFiltered.size();
        } else {
            return 0;
        }
    }

    @Override
    public int getItemViewType(int position) {
        return position;
    }

    @NonNull
    @Override
    public ListViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        CellListBinding binding = DataBindingUtil
                .inflate(LayoutInflater.from(parent.getContext()), R.layout.cell_list,
                        parent, false);
        return new ListViewHolder(binding);
    }

    /**
     * Reloads list of rooms.
     */
    public void loadRooms(List<Status> roomsList) {
        this.statusList = roomsList;
        this.statusListFiltered = roomsList;
        notifyDataSetChanged();
    }


    @Override
    public Filter getFilter() {
        return new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence charSequence) {
                String charString = charSequence.toString();
                if (charString.isEmpty()) {
                    statusListFiltered = statusList;
                } else {
                    List<Status> filteredList = new ArrayList<>();
                    for (Status row : statusList) {
                        if (row.getStatusName().toLowerCase().contains(charString.toLowerCase()) {
                            filteredList.add(row);
                        }
                    }

                    statusListFiltered = filteredList;
                }

                FilterResults filterResults = new FilterResults();
                filterResults.values = statusListFiltered;
                return filterResults;
            }

            @Override
            protected void publishResults(CharSequence charSequence, FilterResults filterResults) {
                if (filterResults.values instanceof RealmList) {
                    statusListFiltered = (RealmList<Status>) filterResults.values;
                } else {
                    statusListFiltered = (ArrayList<Status>) filterResults.values;
                }

                notifyDataSetChanged();
            }
        };
    }

    class ListViewHolder extends RecyclerView.ViewHolder implements OnClickListener {

        // Your Code
    }
}

【讨论】:

  • 您好!我进行了所有更改,除了检查 filterResults.values 是否为 instanceof RealmList (我无法实现它)。但是,一旦我删除了 RecyclerView 项目之一,过滤仍然会消失。
  • 是的,所以过滤器文本需要存储在活动/适配器中,您需要使用存储的文本调用 getFilter
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-04
相关资源
最近更新 更多