我制作了一个可扩展的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);
}
}
}
答案 0 :(得分:1)
我在RecyclerView中展开的项目计数不同,无法为它们设置单一布局。
在您的情况下,实际上 可以对所有项目使用单个布局,因为它们看起来都一样。它们都可以以相同的方式扩展,并且它们的内容始终看起来相同-只是子项的数量不同,但这并不意味着您不能为它们使用一种布局。
您应该有两个XML布局文件-一个用于可扩展项,一个用于内部子行(一个具有按钮的文件)。
第一个解决方案是正确的,您不能选择第二个。每次都创建一个新的布局是没有意义的,因为由于文件数量和使它们膨胀的代码,您的项目将很快变成一片混乱。尽管第一个解决方案不必那么复杂。我看到您正在配置运行时中的所有视图-如果您使用XML进行配置,并且在需要时仅对视图进行膨胀,它将看起来更加简单。
当用户展开第一项时,展开视图中的其他项将复制第一项展开细节!我应该为每个展开的布局创建不同的布局。
我不确定我是否理解你的意思,但是这种方法是正确的。唯一要注意的是,这是一个RecyclerView
,在滚动时会重用其子视图。
示例: 展开item#1并在其中添加5个子行,然后滚动。如果项#4也进行了扩展,则在显示项#4时,回收者视图将重用项#1,即,项#4将自动获得5个子行,即使该子行不应该那么多。
这意味着您必须每次清理onBindViewHolder
中的子行,以确保不显示上一项的信息。如果您的onBindViewHolder
总是返回给定位置的视图的正确表示,那么您将摆脱此问题。如果您忘记清理一些重复使用的视图,则滚动时可能会看到重复的信息。如果还不清楚,请阅读ViewHolder
模式的工作原理,一旦习惯了,它就非常简单。
祝你好运!