Вложенный расширяемый RecyclerView задерживается при развертывании и свертывании из-за слишком большого количества зависаний дочерних элементов - PullRequest
6 голосов
/ 30 апреля 2019

Я создал расширяемое представление рециркуляции в моем приложении, как показано ниже

У него есть родительская категория элементов меню, а у категории есть дочерние элементы, как показано на изображении

enter image description here

Ниже приведена часть моего родительского кода адаптера.

 public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
    if (i > HEADER_COUNT - 1) {
        FoodMenuItem foodMenuItem = foodMenuItems.get(i - HEADER_COUNT);
        MenuViewHolder menuViewHolder = (MenuViewHolder) viewHolder;
        //menuViewHolder.rvMenu.setLayoutManager(new LinearLayoutManager(viewHolder.itemView.getContext(), LinearLayoutManager.VERTICAL, false));
        if (isVegOnly) {
            List<Item> items = new ArrayList<>();
            for (Item item : foodMenuItem.getItems()) {
                if (item.getType().equalsIgnoreCase(Item.FOOD_TYPE_VEG)) {
                    items.add(item);
                }
            }
            menuViewHolder.rvMenu.setAdapter(new FoodMenuChildRecycler(items, foodMenuParentListener, i, isAddAllowed));
            menuViewHolder.tvNumItems.setText("(" + items.size() + " items)");

        } else {
            menuViewHolder.rvMenu.setAdapter(new FoodMenuChildRecycler(foodMenuItem.getItems(), foodMenuParentListener, i, isAddAllowed));
            menuViewHolder.tvNumItems.setText("(" + foodMenuItem.getItems().size() + " items)");

        }
        menuViewHolder.ivArrow.setVisibility(menuViewHolder.rvMenu.getAdapter().getItemCount() > 0 ? View.VISIBLE : View.GONE);
        menuViewHolder.ivArrow.setImageResource(foodMenuItem.isExpanded() ? R.drawable.chev_up : R.drawable.chev_down);
        menuViewHolder.tvTitle.setText(foodMenuItem.getCategoryName());
        menuViewHolder.rvMenu.setNestedScrollingEnabled(false);
        if (foodMenuItem.isExpanded()) {
            menuViewHolder.rvMenu.setVisibility(View.VISIBLE);
        } else {
            menuViewHolder.rvMenu.setVisibility(View.GONE);
        }
    }

}

Ниже приведен код для дочернего адаптера onBindViewHolder

  public void onBindViewHolder(@NonNull RecyclerView.ViewHolder viewHolder, int i) {
    ChildMenuHolder childMenuHolder = (ChildMenuHolder) viewHolder;
    Context context = viewHolder.itemView.getContext();
    Item item = itemList.get(i);
    childMenuHolder.tvTitle.setText(item.getTitle());
    childMenuHolder.txtQty.setText(String.valueOf(item.getQuatity()));
    childMenuHolder.txtCartInc.setVisibility(item.isAddedToCart() ? View.VISIBLE : View.GONE);
    childMenuHolder.txtQty.setVisibility(item.isAddedToCart() ? View.VISIBLE : View.GONE);
    childMenuHolder.txtCartDec.setVisibility(item.isAddedToCart() ? View.VISIBLE : View.GONE);
    childMenuHolder.btnAdd.setVisibility(!item.isAddedToCart() ? View.VISIBLE : View.GONE);
    childMenuHolder.btnAdd.setBackgroundResource(isAddAllowed ? R.drawable.rounded_bottom_edge_shape_food : R.drawable.rounded_bottom_edge_shape_disable);
    childMenuHolder.btnAdd.setTextColor(isAddAllowed ? ContextCompat.getColor(context, R.color.button_green) : ContextCompat.getColor(context, R.color.gray_a1));
    childMenuHolder.ivType.setColorFilter(item.getType().equalsIgnoreCase(Item.FOOD_TYPE_VEG) ? ContextCompat.getColor(context, R.color.selected_green) : ContextCompat.getColor(context, R.color.app_red));
}

Следующий код внутри Родительский Адаптер до Развернуть & Свернуть

  public MenuViewHolder(@NonNull View itemView) {
        super(itemView);
        tvTitle = (TextView) itemView.findViewById(R.id.tvTitle);
        tvNumItems = (TextView) itemView.findViewById(R.id.tvNumItems);
        ivArrow = (ImageView) itemView.findViewById(R.id.ivArrow);
        rvMenu = (RecyclerView) itemView.findViewById(R.id.rvMenu);
        rvMenu.setLayoutManager(new LinearLayoutManager(itemView.getContext()));
       // rvMenu.setNestedScrollingEnabled(false);
        rlArrow = itemView.findViewById(R.id.rlArrow);
        rlArrow.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (foodMenuParentListener != null) {
                    foodMenuParentListener.OnExpandClick(getAdapterPosition());
                }
            }
        });
        tvTitle.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                if (foodMenuParentListener != null) {
                    foodMenuParentListener.OnExpandClick(getAdapterPosition());
                }
            }
        });
    }

onExpandClick внутри слушателя, как показано ниже

        @Override
        public void OnExpandClick(int position) {
            FoodMenuRecyclerAdapter foodMenuRecyclerAdapter = (FoodMenuRecyclerAdapter) recyclerView.getAdapter();
            foodMenuRecyclerAdapter.setExpandIndex(position);
            foodMenuRecyclerAdapter.notifyItemChanged(position);
        }

setExpandIndex внутри адаптера, как показано ниже

public void setExpandIndex(int expandIndex) {
    foodMenuItems.get(expandIndex - HEADER_COUNT).setExpanded(!foodMenuItems.get(expandIndex - HEADER_COUNT).isExpanded());
}

Поскольку в адаптере ChildRecycler слишком много элементов, я столкнулся с большой задержкойпроблема, когда есть слишком много дочерних элементов.Он работает правильно, когда количество дочерних элементов меньше

Как это исправить?

Также мне трудно иметь один вид переработчика из-за наличия карты присутствия в фоновом режиме, как показано наВ противном случае я бы использовал вид одного рециклера, а для свертывания / развертывания реализовал бы добавление и удаление элементов в позиции

Новое примечание: дата 5 мая

Новое решение, которое я пытался использовать NestedScrollView, а затем добавил виды рециркуляции к этому вложенному RecyclerView

Ниже приведен код

 for (FoodMenuItem item : foodResult.getFoodMenuItems()) {
            View view = LayoutInflater.from(getContext()).inflate(R.layout.layout_food_parent, llMenu, false);
            RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.rvMenu);
            ((TextView)view.findViewById(R.id.tvtitle)).setText(item.getCategoryName());

            recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
            view.findViewById(R.id.rlArrow).setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    recyclerView.setVisibility(recyclerView.getVisibility() == View.VISIBLE ? View.GONE : View.VISIBLE);
                }
            });
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run() {
                    recyclerView.setAdapter(new FoodMenuChildRecycler(item.getItems(), getAddItemListener(), i, isFlightAssociatedWithLocation));
                    llMenu.addView(view);
                }
            }, 200);


            i++;

        }

Ниже приведен код XML

 <android.support.v4.widget.NestedScrollView
        android:id="@+id/rvParentMenu"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:paddingBottom="160dp">

        <LinearLayout
            android:id="@+id/llMenu"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical" />

    </android.support.v4.widget.NestedScrollView>

Проблема, с которой я сталкиваюсь, - это код для добавления представлений к линейному макету внутри вложенного представления прокрутки и установки вызова адаптера для представлений переработчика, замораживающий пользовательский интерфейс почти на несколько секунд, добавленный обработчик для него, но, похоже, не очень хорошее решение

...