【问题标题】:How to add child item to last item from RecyclerView?如何从 RecyclerView 将子项添加到最后一项?
【发布时间】:2018-06-27 09:03:57
【问题描述】:

实际上,我正在尝试制作一个接受餐厅订单的应用程序,但在将子项目添加到我的订单后我遇到了一些问题。

我有一个 recyclerView,当我按下其中一个时,我有不同类型的食物,我将它添加到 recyclerView,它的工作类似于笔记本,然后我有一个按钮可以打开一个 AlertDialog,其中还有另一个带有变体的 recyclerView .

示例:我从 food recyclerView 按 PIZZA,在我按变体后将其添加到笔记本中,我可以添加“WITH PEPERONI”或“LARGE”或两者兼而有之。

我已按照 this 指南(指南中的 here github 项目)制作带有子项的 recyclerView。

现在的问题是如何将子项添加到最后一个父项?

就像我正在使用这个添加父项:

                dummyParentDataItem = new ItemPTERM();
                dummyParentDataItem.setButton_name(filteredList.get(position).getDeskS());
                dummyParentDataItem.setQuant( Integer.parseInt(filteredList.get(position).getQuant()));
                dummyChildDataItems = new ArrayList<>();

                dummyParentDataItem.setChildDataItems(dummyChildDataItems);
                itemCassas.add(dummyParentDataItem);

当我从变体的 recyclerView 添加一个孩子时

                dummyChildDataItem = new DummyChildDataItem();
                dummyChildDataItem.setChildName(tipo.toString());
                dummyChildDataItems.add(dummyChildDataItem);

                dummyParentDataItem.setChildDataItems(dummyChildDataItems);
                itemCassas.add(dummyParentDataItem);

但显然应用程序崩溃了,因为它不知道哪个是添加子项的最后一个父项。 当我从 recyclerView 添加食物时尝试将父母和孩子都放在:

                dummyParentDataItem = new ItemPTERM();
                dummyParentDataItem.setButton_name(filteredList.get(position).getDeskS());
                dummyParentDataItem.setQuant( Integer.parseInt(filteredList.get(position).getQuant()));
                dummyChildDataItems = new ArrayList<>();

                dummyChildDataItem = new DummyChildDataItem();
                dummyChildDataItem.setChildName("WITH PEPERONI");
                dummyChildDataItems.add(dummyChildDataItem);

                dummyParentDataItem.setChildDataItems(dummyChildDataItems);
                itemCassas.add(dummyParentDataItem);

这显然有效,但我必须以单独的方法将孩子添加到最后一个父母。

我该怎么做?有什么建议吗? 这也是我的适配器代码:

public class AdapterPTERM extends RecyclerView.Adapter<AdapterPTERM.ExampleViewHolder> {

    private ArrayList<ItemPTERM> mExampleList;


    @NonNull
    @Override
    public ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recyclerview_pterm,parent,false);
        return new ExampleViewHolder(v);
    }

    AdapterPTERM(ArrayList<ItemPTERM> exampleList){
        mExampleList = exampleList;
    }

    @Override
    public void onBindViewHolder(@NonNull ExampleViewHolder holder, int position) {
        ItemPTERM item = mExampleList.get(position);

        holder.desc.setText(item.getBtnName());
        holder.qta.setText(String.valueOf(item.getQuant()));

        int noOfChildTextViews = holder.linearLayout_childItems.getChildCount();
        int noOfChild = item.getChildDataItems().size();

        if (noOfChild < noOfChildTextViews) {
            for (int index = noOfChild; index < noOfChildTextViews; index++) {
                TextView currentTextView = (TextView) holder.linearLayout_childItems.getChildAt(index);
                currentTextView.setVisibility(View.GONE);
            }
        }
        for (int textViewIndex = 0; textViewIndex < noOfChild; textViewIndex++) {
            TextView currentTextView = (TextView) holder.linearLayout_childItems.getChildAt(textViewIndex);
            currentTextView.setText(item.getChildDataItems().get(textViewIndex).getChildName());
        }

        if(position % 2 == 0 ){
            holder.itemView.setBackgroundColor(Color.parseColor("#C0C0C0"));

        }else if(position % 2 == 1){
            holder.itemView.setBackgroundColor(Color.parseColor("#D3D3D3"));
        }

    }

    @Override
    public int getItemCount() {
        return mExampleList.size();
    }

    public class ExampleViewHolder extends RecyclerView.ViewHolder {

        public TextView desc;
        public TextView qta;
        private LinearLayout linearLayout_childItems;
        private Context context;

        ExampleViewHolder(View itemView) {
            super(itemView);

            desc = itemView.findViewById(R.id.Desc);
            qta = itemView.findViewById(R.id.Qta);
            linearLayout_childItems = itemView.findViewById(R.id.ll_child_items);
            context = itemView.getContext();

            int intMaxNoOfChild = 0;
            for (int index = 0; index < mExampleList.size(); index++) {
                int intMaxSizeTemp = mExampleList.get(index).getChildDataItems().size();
                if (intMaxSizeTemp > intMaxNoOfChild) intMaxNoOfChild = intMaxSizeTemp;
            }
            for (int indexView = 0; indexView < intMaxNoOfChild; indexView++) {
                TextView textView = new TextView(context);
                textView.setId(indexView);
                textView.setPadding(0, 20, 0, 20);
                textView.setGravity(Gravity.CENTER);
                textView.setBackground(ContextCompat.getDrawable(context, R.drawable.background_sub_module_text));
                LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT);
                linearLayout_childItems.addView(textView, layoutParams);
            }

        }
    }

    public void removeItem(int position) {
        mExampleList.remove(position);
        notifyItemRemoved(position);
    }


}

这是我的活动截图

【问题讨论】:

    标签: android android-recyclerview


    【解决方案1】:

    要在 RecylerView 中显示数据,您需要向其适配器提供项目列表。

    要添加新元素,您只需将项目添加到列表中并在适配器上调用notifyDataSetChange()

    例如,您可以在适配器中创建一个新方法,如下所示:

    public void addItem(ItemPTERM item){
       mExampleList.add(item);
       notifyDataSetChange();
    }
    

    编辑

    所以你可以做的是让你的项目有一个“变体”列表。

    例如,如果您选择“Pizza”并想要吃“big”和“pepperoni”,那么您的商品将是变体列表中的 Pizza 和“big”和“pepperoni”部分。

    Food {
      String name;
      List<Variant> variants;
      //... Other attributes
    
      public void setVariant(Variant variant){
         if (variants == null) // We want to initialise the array only when necessary
            variants = new ArrayList<>();
         variants.add(variant);
      }
    
      @Nullable
      public List<Variant> getVariants(){
         return variants;
      }
    }
    
    Variant{
       String name;
      //... Other attributes
    }
    

    当您选择一个变体时,您将其添加到相应的 Food 对象中。

    方法 1

    然后在您的适配器中,您可以在 onBindViewHolder 中动态地将变体添加到项目中;

    这种方式不是最优化的,但应该可以:

    项目布局

        <!-- Food Views-->
        ...
    
        <!-- Container for the variants -->
        <LinearLayout
            android:id="@+id/variants_list"
            android:layout_width="match_parent"
            android:orientation="vertical"
            android:layout_height="wrap_content"/>
    </LinearLayout>
    

    变体布局

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal">
    
        <TextView
            android:id="@+id/variant_name"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    
        <TextView
            android:id="@+id/variant_other_info"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </LinearLayout>
    

    适配器

    final LayoutInflater mInflater;
    List<Food> mFoods;
    
    public FoodAdapter(Context context, ...){
       //...
       mInflater = LayoutInflater.from(context);
    }
    
    @Override
    public void onBindViewHolder(@NonNull ExampleViewHolder holder, int position) {
       Food food = mFood.get(position);
       // Display food attributes
       //... 
       // Clear the container to set fresh info
       holder.variantsContainer.removeAllViews();
    
       List<Variant> variants = food.getVariants();
       if (variants != null && variants.size() > 0){
          // Display the variants when necessary
          for(Variant v : variants){
             View vView = mInflater.inflate(R.layout.variant_layout);
             TextView nameTV = vView.findViewById(R.id.variant_name);
             nameTV.setText(v.getName());
             // Set other fields values
             // ...
             holder.variantsContainer.addView(vView);
          }
       }
    }
    

    方法 2

    另一种方法是拥有一个包含上述变体列表的食物对象列表,但不要直接在适配器中使用此列表。

    适配器将使用它自己的列表,该列表将 Food 和 Variant 对象混合在一起。然后您的适配器应该能够显示 2 种对象。这种方式更灵活,但每次更改时都必须重新创建整个适配器列表。

    例如:

    假设您在列表中有 3 个 Food 对象。第一个有 1 个变体,第二个没有,第三个有 2 个。

    然后你的适配器会得到一个这样的列表:

    List<Object> items;
    

    项目将包含: {food1, variant1a, food2, food3, variant3a, variant3b}

    然后您的适配器将不得不使用两种不同的布局来显示 Food 或 Variant 对象。

    @NonNull
    @Override
    public ExampleViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        if (viewType == 0) { // if food
            View vFood = mInflater.inflate(R.layout.food_layout, parent, false);
            return new FoodViewHolder(vFood);
        } else { // variant
            View vVariant = mInflater.inflate(R.layout.variant_layout, parent, false);
            return new VariantViewHolder(vVariant;
        }
    }
    
    @Override
    public int getItemViewType(int position) {
        return (mItems.get(position) instanceof Food) ? 0 : 1;
    }
    

    【讨论】:

    • 所以你的意思是当我在适配器中添加 addItem 后添加父级时,我必须编写 myAdapter.addItem(dummyParentDataItem); ?
    • 你的问题不是很清楚。但是,如果我理解正确,您基本上有一个空列表,您想根据用户按下的内容添加一些内容。这个空列表是一个 RecyclerView,因此它意味着它有一个要显示的对象列表(空)和一个适配器。因此,在适配器中添加上述方法,当用户选择某些内容时,使用要添加的元素调用此方法
    • 我已经为问题添加了一个屏幕截图,正如你所看到的,当我按下其中一些项目时,我有一个带有项目“FOOD”的机器人 recyclerView,如你所见,它们被添加到顶部 recyclerView 2PIC 我从 bot recyclerView 添加的项目是“食物”元素,现在如果我按下按钮“VARIANTI”,它会打开一个 AlertDialog,其中有另一个带有变体的 recyclerView 添加到之前添加的“食物”中,就像我一样从变体中添加“PIZZA”我可以添加到“PIZZA”属性“BIG”、“WIT​​H PEPERONI”并且这个元素必须是 PIZZA 的子元素
    • 我有一些问题,第一个食品和变体我可以使用构造函数吗?第二个是当我尝试实现方法 1 时,我在 mInflater.inflate(R.layout.variant_layout) 中遇到错误;无法解析方法 inflate(int)
    • 是的,您可以使用构造函数。我只是给了你一个关于如何做的全局想法,其余的取决于你。应该是mInflater.inflate(R.layout.variant_layout,parent,false);。父级是容器(holder.variantsContainer
    猜你喜欢
    • 1970-01-01
    • 2020-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-13
    • 2019-01-19
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多