序言-我的目标是能够使用字段搜索NestedRecyclerView中的项。
在我的应用程序中,我有一个HomeFragment。在上述片段中,我有一个回收器视图(父回收视图),这个视图又包含一个recyclerView(进一步的子级或嵌套的recyclerview)。以下是分别用于家长和儿童回收视图的适配器。
public class HomeFragmentRvParentAdapter extends RecyclerView.Adapter<HomeFragmentRvParentAdapter.ParentRvViewHolder> {
private Context context;
private Map<String, ArrayList<Product>> products;
private FragmentChangeCallback fragmentChangeCallback;
ArrayList<String> categories;
public HomeFragmentRvParentAdapter(Context context, Map<String, ArrayList<Product>> products, FragmentChangeCallback callback){
this.context = context;
this.fragmentChangeCallback = callback;
this.products = products;
}
@NonNull
@Override
public ParentRvViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_fragment_recyclerview_item_parent, parent, false);
categories = new ArrayList<>(products.keySet());
return new ParentRvViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ParentRvViewHolder holder, int position) {
holder.itemCategoryName.setText(categories.get(position));
setChildAdapter(holder.itemChildRecyclerView, products.get(categories.get(position)));
}
@Override
public int getItemCount() {
return products.size();
}
public class ParentRvViewHolder extends RecyclerView.ViewHolder {
TextView itemCategoryName;
RecyclerView itemChildRecyclerView;
public ParentRvViewHolder(@NonNull View itemView) {
super(itemView);
itemCategoryName = itemView.findViewById(R.id.category_name);
itemChildRecyclerView = itemView.findViewById(R.id.child_recycler);
}
}
private void setChildAdapter(RecyclerView recyclerView, ArrayList<Product> products){
HomeFragmentRvChildAdapter adapter = new HomeFragmentRvChildAdapter(context ,products, fragmentChangeCallback);
recyclerView.setLayoutManager(new LinearLayoutManager(context, LinearLayoutManager.HORIZONTAL, false));
recyclerView.setAdapter(adapter);
}
}public class HomeFragmentRvChildAdapter extends RecyclerView.Adapter<HomeFragmentRvChildAdapter.ChildViewHolder> {
ArrayList<Product> products;
Context context;
FragmentChangeCallback fragmentChangeCallback;
public HomeFragmentRvChildAdapter(Context context, ArrayList<Product>products, FragmentChangeCallback callback){
this.products = products;
this.context = context;
this.fragmentChangeCallback = callback;
}
@NonNull
@Override
public ChildViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.home_fragment_recyclerview_item_child, parent, false);
return new ChildViewHolder(view);
}
@Override
public void onBindViewHolder(@NonNull ChildViewHolder holder, int position) {
Glide.with(context).load(products.get(position).getIcon()).into(holder.iconView);
holder.name.setText(products.get(position).getName());
holder.description.setText(products.get(position).getDescription());
holder.itemView.setOnClickListener(view -> {
fragmentChangeCallback.fragmentChange(products.get(position).getPackageName());
});
}
@Override
public int getItemCount() {
return products.size();
}
public class ChildViewHolder extends RecyclerView.ViewHolder {
public ImageView iconView;
public TextView name;
public TextView description;
public CardView cardView;
public ChildViewHolder(@NonNull View itemView) {
super(itemView);
cardView = itemView.findViewById(R.id.cardView);
iconView = itemView.findViewById(R.id.hf_item_icon_image);
name = itemView.findViewById(R.id.app_title);
description = itemView.findViewById(R.id.app_description);
}
}
}public class Product{
private String name;
private String icon;
private String category;
private String description;
}用于填充儿童回收器的Product的^字段。
我传递数据的方式是--在我的HomeFragmentViewModel中,我得到数据。然后,我将数据分类为一个HashMap,其中键是类别。然后,我将said映射传递给我的ParentRecyclerViewAdapter,该映射将category_title设置为键的值,并将链接的ArrayList传递给ChildRecyclerViewAdapter,然后将其分割为显示。
我的目标是,如前所述,能够使用EditText在HomeFragment中搜索儿童回收商中的物品。我尝试过只获取整个数据库,并使用项目的名称对其进行排序,然后在recyclerView中显示它,但我认为可能有一种更优雅的方法。
我能想到的唯一更好的方法是,也许只是将View.GONE应用于名称不包含用于搜索的字符串的视图。这将需要子项目的名称,但我不知道如何获得。
发布于 2022-04-28 20:35:18
我解决这个问题的方法是:创建一个自定义的CardView类,其中有一个字段作为名称。
public class CustomCardView extends CardView {
private String name;
private String description;
private String icon;
public CustomCardView(@NonNull Context context) {
super(context);
}
public CustomCardView(@NonNull Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomCardView, 0,0);
try{
name = a.getString(R.styleable.CustomCardView_appName);
description = a.getString(R.styleable.CustomCardView_descriptionText);
}finally {
a.recycle();
}
}
public CustomCardView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
TypedArray a = context.getTheme().obtainStyledAttributes(attrs, R.styleable.CustomCardView, 0,0);
try{
name = a.getString(R.styleable.CustomCardView_appName);
description = a.getString(R.styleable.CustomCardView_descriptionText);
}finally {
a.recycle();
}
}
public String getName(){
return name;
}
public String getDescription(){
return description;
}
public void setName(String name){
this.name = name;
invalidate();
requestLayout();
}
public void setDescription(String description){
this.description = description;
invalidate();
requestLayout();
}
}然后,我创建了一个静态ArrayList,它可以容纳所有的子对象。
public class RecyclerViewItemHolder {
public static ArrayList<CustomCardView> childViews = new ArrayList<>();
private static RecyclerViewItemHolder instance = null;
private RecyclerViewItemHolder(){
}
public static RecyclerViewItemHolder getInstance(){
if (instance == null){
instance = new RecyclerViewItemHolder();
}
return instance;
}
public static ArrayList<CustomCardView> getChildViews(){
return childViews;
}
}在onBindViewHolder of ChildRecyclerViewAdapter中,我将每个CustomCardView添加到ArrayList中。
@Override
public void onBindViewHolder(@NonNull ChildViewHolder holder, int position) {
RecyclerViewItemHolder.getInstance().childViews.add(holder.cardView);
}然后,从设置为ArrayList的TextWatcher的afterTextChanged方法访问EditText。我使用for循环检查cardView的名称是否包含搜索查询,如果不包含,则应用View.GONE。
private void initListeners() {
binding.searchView.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
@Override
public void afterTextChanged(Editable editable) {
for (CustomCardView cardView: RecyclerViewItemHolder.getChildViews()) {
if (!cardView.getName().contains(editable.toString())) {
cardView.setVisibility(View.GONE);
}else{
cardView.setVisibility(View.VISIBLE);
}
}
}
});剩下的唯一问题是,空类别不会消失,而是保持在空的状态。
现在,这可能不是最好的方法,所以我仍然感激任何关于如何改进这个解决方案的答案或评论。
https://stackoverflow.com/questions/72048447
复制相似问题