具有不同详细信息的可扩展RecyclerView

时间:2018-07-03 07:10:03

标签: android android-recyclerview


我制作了一个可扩展的RecyclerView,我在RecyclerView中的扩展项计数不同,无法为其设置单个布局。
我的程序比较了某些服务的价格(目前有6种不同的服务),每个服务的子服务计数都不同,该计数将传递给RV适配器。
我想要这样的东西: different expanded item counts
我尝试使用以下解决方案来解决它:

首要解决方案:
我的RV数据模型有一个名为serviceCount的int变量,并从MainActivity获取每种服务类型的数据,我的布局应重复使用serviceCount size,我已经在onBindViewHolder中编写了这段代码:

        if (holder.detailLayout.getVisibility() == View.VISIBLE) {
        for (int i = 0; i < priceList.get(position).getServiceCount(); i++) {
            // Code
        }

我正在尝试以编程方式创建一个布局,并以该大小重复该布局,如下所示:

        for (int i = 0; i < priceList.get(position).getServiceCount(); i++) {
            ConstraintLayout newDetailLayout = new ConstraintLayout(context);
            ConstraintLayout.LayoutParams layoutParams = new ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.MATCH_PARENT,
                    ConstraintLayout.LayoutParams.WRAP_CONTENT);
            layoutParams.topToBottom = R.id.tv_pricedetail_service;
            layoutParams.rightToRight = 0;
            layoutParams.leftToLeft = 0;
            layoutParams.setMargins(0,margin8dp*i*6,0,0);

            Button requestButton = new Button(context);
            requestButton.setId(View.generateViewId());
            requestButton.setText("درخواست" + " " + String.valueOf(i));
            ConstraintLayout.LayoutParams requestButtonParams = new ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.WRAP_CONTENT,
                    ConstraintLayout.LayoutParams.WRAP_CONTENT);
            requestButtonParams.leftToLeft = 0;
            requestButtonParams.topToTop = 0;
            requestButtonParams.setMargins(margin8dp *4,margin8dp *2,0,0);
            newDetailLayout.addView(requestButton, requestButtonParams);

            TextView serviceName = new TextView(context);
            serviceName.setId(View.generateViewId());
            serviceName.setText("تست" + " " + String.valueOf(i));
            ConstraintLayout.LayoutParams serviceNameParams = new ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.WRAP_CONTENT,
                    ConstraintLayout.LayoutParams.WRAP_CONTENT);
            serviceNameParams.topToTop = 0;
            serviceNameParams.rightToRight = 0;
            serviceNameParams.baselineToBaseline = requestButton.getId();
            serviceNameParams.setMargins(0,margin8dp *2,margin8dp *4,0);
            newDetailLayout.addView(serviceName, serviceNameParams);

            TextView serviceCost = new TextView(context);
            serviceCost.setText("هزینه" + " " + String.valueOf(i));
            ConstraintLayout.LayoutParams serviceCostParams = new ConstraintLayout.LayoutParams(
                    ConstraintLayout.LayoutParams.WRAP_CONTENT,
                    ConstraintLayout.LayoutParams.WRAP_CONTENT);
            serviceCostParams.leftToRight = requestButton.getId();
            serviceCostParams.rightToLeft = serviceName.getId();
            serviceCostParams.baselineToBaseline = requestButton.getId();
            newDetailLayout.addView(serviceCost, serviceCostParams);

            holder.detailLayout.addView(newDetailLayout, layoutParams);

        }
        //Toast.makeText(context, String.valueOf(priceList.get(position).getServiceCount()), Toast.LENGTH_SHORT).show();
    }

我的代码的输出是这样的:output view但是,当用户展开第一项时,展开视图中的其他项将复制第一项展开的细节!我应该为每个展开的布局创建不同的布局。

第二个解决方案
我为每个服务制作了6种不同的布局(它们将来会更多),并使用实例化变量在onCreateViewHolder中对其进行膨胀

这样做对吗?还是我可以做得更好?

编辑: onBindViewHolder代码:

    public void onBindViewHolder(@NonNull itemsViewHolder holder, int position) {
    // Init Layout
    final priceItemDM items = priceList.get(position);
    holder.iv_logo.setImageDrawable(items.getLogo());
    holder.txt_name.setText(items.getName());
    holder.txt_price.setText(items.getPrice());

    // Expand & Collapse Mode
    final boolean isExpanded = position == mExpandedPosition;
    final int positionNo = position;
    holder.detailLayout.setVisibility(isExpanded ? View.VISIBLE : View.GONE);
    holder.itemView.setActivated(isExpanded);
    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (!items.getPrice().equals(receivingData) && !items.getPrice().equals(receiverError)) {
                mExpandedPosition = isExpanded ? -1 : positionNo;
                notifyItemChanged(positionNo);
            } else {
                Toast.makeText(context, "اطلاعات ناقص است ، لطفا مجددا تلاش فرمایید", Toast.LENGTH_SHORT).show();
            }
        }
    });
    if (!items.getPrice().equals(receivingData)) {
        holder.pb_loading.setVisibility(View.INVISIBLE);
        if (holder.detailLayout.getVisibility() == View.VISIBLE &&
                !items.getPrice().equals(receiverError)) {
            //priceList.get(position).getServiceNames().size()
            holder.detailLayout.removeAllViews();
            holder.detailLayout.addView(childView);
        }
    }
}

1 个答案:

答案 0 :(得分:1)

  

我在RecyclerView中展开的项目计数不同,无法为它们设置单一布局。

在您的情况下,实际上 可以对所有项目使用单个布局,因为它们看起来都一样。它们都可以以相同的方式扩展,并且它们的内容始终看起来相同-只是子项的数量不同,但这并不意味着您不能为它们使用一种布局。

您应该有两个XML布局文件-一个用于可扩展项,一个用于内部子行(一个具有按钮的文件)。

第一个解决方案是正确的,您不能选择第二个。每次都创建一个新的布局是没有意义的,因为由于文件数量和使它们膨胀的代码,您的项目将很快变成一片混乱。尽管第一个解决方案不必那么复杂。我看到您正在配置运行时中的所有视图-如果您使用XML进行配置,并且在需要时仅对视图进行膨胀,它将看起来更加简单。

  

当用户展开第一项时,展开视图中的其他项将复制第一项展开细节!我应该为每个展开的布局创建不同的布局。

我不确定我是否理解你的意思,但是这种方法是正确的。唯一要注意的是,这是一个RecyclerView,在滚动时会重用其子视图。

示例: 展开item#1并在其中添加5个子行,然后滚动。如果项#4也进行了扩展,则在显示项#4时,回收者视图将重用项#1,即,项#4将自动获得5个子行,即使该子行不应该那么多。

这意味着您必须每次清理onBindViewHolder中的子行,以确保不显示上一项的信息。如果您的onBindViewHolder总是返回给定位置的视图的正确表示,那么您将摆脱此问题。如果您忘记清理一些重复使用的视图,则滚动时可能会看到重复的信息。如果还不清楚,请阅读ViewHolder模式的工作原理,一旦习惯了,它就非常简单。

祝你好运!