如何从RecyclerView将子项添加到最后一个项?

时间:2018-06-27 09:03:58

标签: android android-recyclerview

实际上,我正在尝试制作一个可以接收餐厅订单的应用,并且在将子项目添加到我的订单后出现了一些问题。

我有一个recyclerView,当我按其中一个食物时,我会得到不同类型的食物,然后将其添加到工作原理类似于笔记本电脑的recyclerView中,然后我有一个按钮可以打开AlertDialog,其中有另一个带有变体的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);
    }


}

这是我的活动的屏幕截图

enter image description here

1 个答案:

答案 0 :(得分:1)

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

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

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

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

编辑

所以您可以做的是允许您的商品包含“变体”列表。

例如,如果您选择“披萨”并希望拥有“大”和“意大利辣味香肠”,则您的商品将是变体列表中的“比萨”和“大”和“意大利辣味香肠”部分。

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个食物对象。第一个有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;
}