如何拥有一个ListView / RecyclerView父RecyclerView里面?我有一个父列表,其中包含一些孩子名单在每一个位置 [英] How to have a ListView/RecyclerView inside a parent RecyclerView?. I have a parent list, which contains some child lists at every position
问题描述
我想添加一些子视图(列表项),其中涉及到我从一个JSON格式的数据。每个孩子列表父列表项下排。我如何填充它RecyclerView的每一行项目(父项与子项列表中的项目)。 任何建议将是非常有益的,进一步去落实。
我用RecyclerView RecyclerView父行内已经尝试(用于填充子列表),但这里的孩子的看法是不可见的。
下面是我的适配器类了。
//我的父适配器类
公共类数字化prescAdapter延伸RecyclerView.Adapter<数字化prescAdapter.ListItemViewHolder> {
私人列表< prescriptionModal> prescriptionList;
MedicinesIn prescAdapter适配器;
公开数字化prescAdapter(名单< prescriptionModal> prescriptionListModal){
如果(prescriptionListModal == NULL){
抛出新抛出:IllegalArgumentException(
prescriptionList不能为空);
}
这prescriptionList = prescriptionListModal。
}
@覆盖
公共ListItemViewHolder onCreateViewHolder(
ViewGroup中的ViewGroup,INT viewType){
查看ItemView控件= LayoutInflater。
从(viewGroup.getContext())。
膨胀(R.layout.item_row_digitised_request,
ViewGroup中,
假);
返回新ListItemViewHolder(ItemView控件);
}
@覆盖
公共无效onBindViewHolder(
ListItemViewHolder viewHolder,INT位置){
prescriptionModal模型= prescriptionList.get(位置);
。viewHolder prescnum.setText(prescription+ + +位置);
viewHolder prescNo.setText(prescription:+ model.get prescriptionID())。
viewHolder.doctorType.setText(类型:+ model.getDoctorType());
viewHolder.doctorName.setText(医生:+ model.getDoctorName());
viewHolder.patientName.setText(患者:+ model.getPatientName());
适配器=新MedicinesIn prescAdapter(model.getLstproduct());
viewHolder.lstMedicines.setAdapter(适配器);
}
@覆盖
公众诠释getItemCount(){
返回prescriptionList.size();
}
公共最后静态类ListItemViewHolder
扩展RecyclerView.ViewHolder {
TextView的prescnum;
TextView的prescNo;
TextView的doctorType;
TextView的patientName;
TextView的doctorName;
复选框全选;
RecyclerView lstMedicines;
公共ListItemViewHolder(查看ItemView控件){
超(ItemView控件);
prescnum =(TextView中)itemView.findViewById(R.id. prescnum);
prescNo =(TextView中)itemView.findViewById(R.id. prescNo);
doctorType =(TextView中)itemView.findViewById(R.id.doctorType);
patientName =(TextView中)itemView.findViewById(R.id.patientName);
doctorName =(TextView中)itemView.findViewById(R.id.doctorName);
全选=(复选框)itemView.findViewById(R.id.selectAll);
lstMedicines =(RecyclerView)itemView.findViewById(R.id.lstAllMedicines);
MyLinearLayoutManager的layoutManager =新MyLinearLayoutManager(itemView.getContext(),LinearLayoutManager.VERTICAL,假);
lstMedicines.setHasFixedSize(假);
lstMedicines.setLayoutManager(的layoutManager);
}
}
}
//我的孩子适配器类
公共类MedicinesIn prescAdapter延伸RecyclerView.Adapter< MedicinesIn prescAdapter.MedicineListItemViewHolder> {
名单< Modal_Product_List> prescriptionProducts;
公共MedicinesIn prescAdapter(名单< Modal_Product_List> prescriptionListProd){
如果(prescriptionListProd == NULL){
抛出新抛出:IllegalArgumentException(
prescriptionProductList不能为空);
}
这prescriptionProducts = prescriptionListProd。
}
@覆盖
公共MedicineListItemViewHolder onCreateViewHolder(
ViewGroup中的ViewGroup,INT viewType){
查看ItemView控件= LayoutInflater。
从(viewGroup.getContext())。
膨胀(R.layout.item_row_medicine_productlist,
ViewGroup中,
假);
返回新MedicineListItemViewHolder(ItemView控件);
}
@覆盖
公共无效onBindViewHolder(
MedicineListItemViewHolder viewHolder,INT位置){
Modal_Product_List modelMedicine = prescriptionProducts.get(位置);
viewHolder.medicineName.setText(modelMedicine.getMedicinename());
viewHolder.medQty.setText(modelMedicine.getQuantity());
viewHolder.days.setText(30);
viewHolder.Amount.setText(modelMedicine.getQuantitybasedprice());
}
@覆盖
公众诠释getItemCount(){
返回prescriptionProducts.size();
}
公共最后静态类MedicineListItemViewHolder
扩展RecyclerView.ViewHolder {
TextView的medicineName;
的EditText medQty;
TextView的天;
TextView的金额;
复选框selectMe;
公共MedicineListItemViewHolder(查看ItemView控件){
超(ItemView控件);
medicineName =(TextView中)itemView.findViewById(R.id.medicineName);
medQty =(EditText上)itemView.findViewById(R.id.medQty);
天=(TextView中)itemView.findViewById(R.id.days);
金额=(TextView中)itemView.findViewById(R.id.amount);
selectMe =(复选框)itemView.findViewById(R.id.selectMe);
}
}
}
我前几天有这个问题,最后解决了这个问题。所有你需要做的就是 @覆盖布局管理器onMeasure 的功能如下:
CustomLinearLayoutManager
公共类CustomLinearLayoutManager扩展LinearLayoutManager {
私有静态最后字符串变量= CustomLinearLayoutManager.class.getSimpleName();
公共CustomLinearLayoutManager(上下文的背景下){
超(上下文);
}
公共CustomLinearLayoutManager(上下文的背景下,INT方向,布尔reverseLayout){
超(背景下,定向,reverseLayout);
}
私人INT [] mMeasuredDimension =新INT [2];
@覆盖
公共无效onMeasure(RecyclerView.Recycler回收,RecyclerView.State状态,INT widthSpec,诠释heightSpec){
最终诠释widthMode = View.MeasureSpec.getMode(widthSpec);
最终诠释heightMode = View.MeasureSpec.getMode(heightSpec);
最终诠释widthSize = View.MeasureSpec.getSize(widthSpec);
最终诠释heightSize = View.MeasureSpec.getSize(heightSpec);
INT宽度= 0;
INT高= 0;
的for(int i = 0; I< getItemCount();我++){
measureScrapChild(回收,我,View.MeasureSpec.makeMeasureSpec(我,View.MeasureSpec.UNSPECIFIED)
View.MeasureSpec.makeMeasureSpec(ⅰ,View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
如果(getOrientation()==水平){
宽度=宽度+ mMeasuredDimension [0];
如果(我== 0){
高度= mMeasuredDimension [1];
}
} 其他 {
高度=身高+ mMeasuredDimension [1];
如果(我== 0){
宽度= mMeasuredDimension [0];
}
}
}
开关(widthMode){
案例View.MeasureSpec.EXACTLY:
宽度= widthSize;
案例View.MeasureSpec.AT_MOST:
案例View.MeasureSpec.UNSPECIFIED:
}
开关(heightMode){
案例View.MeasureSpec.EXACTLY:
身高= heightSize;
案例View.MeasureSpec.AT_MOST:
案例View.MeasureSpec.UNSPECIFIED:
}
setMeasuredDimension(宽度,高度);
}
私人无效measureScrapChild(RecyclerView.Recycler回收,INT地位,诠释widthSpec,
INT heightSpec,INT [] measuredDimension){
尝试 {
查看查看= recycler.getViewForPosition(0); //修复动态添加时报IndexOutOfBoundsException异常
如果(查看!= NULL){
RecyclerView.LayoutParams P =(RecyclerView.LayoutParams)view.getLayoutParams();
INT childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft()+ getPaddingRight(),p.width);
INT childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop()+ getPaddingBottom(),p.height);
view.measure(childWidthSpec,childHeightSpec);
measuredDimension [0] = view.getMeasuredWidth()+ p.leftMargin + p.rightMargin;
measuredDimension [1] = view.getMeasuredHeight()+ p.bottomMargin + p.topMargin;
recycler.recycleView(视图);
}
}赶上(例外五){
e.printStackTrace();
}
}
}
您可以复制和过去的自定义布局管理器如上面和设置您的recyclerview在这样父适配器:
RecyclerView.LayoutManager的layoutManager =新CustomLinearLayoutManager(mContext);
holder.childRecyclerView.setLayoutManager(的layoutManager);
记住:不要使用相同的layoutManager父适配器,或将发生错误
I want to add some child Views (List Items), which comes to me from a JSON formatted data. Each child list is under a parent list item row. How can i populate it in RecyclerView for each row item (Parent items with child list items). Any suggestions would be very helpful to go further and implement.
I have tried using RecyclerView within RecyclerView parent row (for populating child lists), but here child views are not visible.
Here is my Adapter class for it.
//My Parent Adapter Class
public class DigitizedPrescAdapter extends RecyclerView.Adapter<DigitizedPrescAdapter.ListItemViewHolder>{
private List<PrescriptionModal> prescriptionList;
MedicinesInPrescAdapter adapter;
public DigitizedPrescAdapter(List<PrescriptionModal> prescriptionListModal) {
if (prescriptionListModal == null) {
throw new IllegalArgumentException(
"PrescriptionList must not be null");
}
this.prescriptionList = prescriptionListModal;
}
@Override
public ListItemViewHolder onCreateViewHolder(
ViewGroup viewGroup, int viewType) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.item_row_digitised_request,
viewGroup,
false);
return new ListItemViewHolder(itemView);
}
@Override
public void onBindViewHolder(
ListItemViewHolder viewHolder, int position) {
PrescriptionModal model = prescriptionList.get(position);
viewHolder.prescnum.setText("Prescription "+ ++position);
viewHolder.prescNo.setText("Prescription: "+model.getPrescriptionID());
viewHolder.doctorType.setText("Type: "+model.getDoctorType());
viewHolder.doctorName.setText("Doctor: "+model.getDoctorName());
viewHolder.patientName.setText("Patient: "+model.getPatientName());
adapter = new MedicinesInPrescAdapter(model.getLstproduct());
viewHolder.lstMedicines.setAdapter(adapter);
}
@Override
public int getItemCount() {
return prescriptionList.size();
}
public final static class ListItemViewHolder
extends RecyclerView.ViewHolder {
TextView prescnum;
TextView prescNo;
TextView doctorType;
TextView patientName;
TextView doctorName;
CheckBox selectAll;
RecyclerView lstMedicines;
public ListItemViewHolder(View itemView) {
super(itemView);
prescnum = (TextView) itemView.findViewById(R.id.prescnum);
prescNo = (TextView) itemView.findViewById(R.id.prescNo);
doctorType = (TextView) itemView.findViewById(R.id.doctorType);
patientName = (TextView) itemView.findViewById(R.id.patientName);
doctorName = (TextView) itemView.findViewById(R.id.doctorName);
selectAll = (CheckBox) itemView.findViewById(R.id.selectAll);
lstMedicines = (RecyclerView) itemView.findViewById(R.id.lstAllMedicines);
MyLinearLayoutManager layoutManager = new MyLinearLayoutManager(itemView.getContext(),LinearLayoutManager.VERTICAL,false);
lstMedicines.setHasFixedSize(false);
lstMedicines.setLayoutManager(layoutManager);
}
}
}
//My Child Adapter Class
public class MedicinesInPrescAdapter extends RecyclerView.Adapter<MedicinesInPrescAdapter.MedicineListItemViewHolder>{
List<Modal_Product_List> prescriptionProducts;
public MedicinesInPrescAdapter(List<Modal_Product_List> prescriptionListProd) {
if (prescriptionListProd == null) {
throw new IllegalArgumentException(
"PrescriptionProductList must not be null");
}
this.prescriptionProducts = prescriptionListProd;
}
@Override
public MedicineListItemViewHolder onCreateViewHolder(
ViewGroup viewGroup, int viewType) {
View itemView = LayoutInflater.
from(viewGroup.getContext()).
inflate(R.layout.item_row_medicine_productlist,
viewGroup,
false);
return new MedicineListItemViewHolder(itemView);
}
@Override
public void onBindViewHolder(
MedicineListItemViewHolder viewHolder, int position) {
Modal_Product_List modelMedicine = prescriptionProducts.get(position);
viewHolder.medicineName.setText(modelMedicine.getMedicinename());
viewHolder.medQty.setText(modelMedicine.getQuantity());
viewHolder.days.setText("30");
viewHolder.Amount.setText(modelMedicine.getQuantitybasedprice());
}
@Override
public int getItemCount() {
return prescriptionProducts.size();
}
public final static class MedicineListItemViewHolder
extends RecyclerView.ViewHolder {
TextView medicineName;
EditText medQty;
TextView days;
TextView Amount;
CheckBox selectMe;
public MedicineListItemViewHolder(View itemView) {
super(itemView);
medicineName = (TextView) itemView.findViewById(R.id.medicineName);
medQty = (EditText) itemView.findViewById(R.id.medQty);
days = (TextView) itemView.findViewById(R.id.days);
Amount = (TextView) itemView.findViewById(R.id.amount);
selectMe = (CheckBox) itemView.findViewById(R.id.selectMe);
}
}
}
I got this issue few days ago and finally solved it. All you have to do is @override the layout manager onMeasure function as below:
CustomLinearLayoutManager
public class CustomLinearLayoutManager extends LinearLayoutManager {
private static final String TAG = CustomLinearLayoutManager.class.getSimpleName();
public CustomLinearLayoutManager(Context context) {
super(context);
}
public CustomLinearLayoutManager(Context context, int orientation, boolean reverseLayout) {
super(context, orientation, reverseLayout);
}
private int[] mMeasuredDimension = new int[2];
@Override
public void onMeasure(RecyclerView.Recycler recycler, RecyclerView.State state, int widthSpec, int heightSpec) {
final int widthMode = View.MeasureSpec.getMode(widthSpec);
final int heightMode = View.MeasureSpec.getMode(heightSpec);
final int widthSize = View.MeasureSpec.getSize(widthSpec);
final int heightSize = View.MeasureSpec.getSize(heightSpec);
int width = 0;
int height = 0;
for (int i = 0; i < getItemCount(); i++) {
measureScrapChild(recycler, i, View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(i, View.MeasureSpec.UNSPECIFIED),
mMeasuredDimension);
if (getOrientation() == HORIZONTAL) {
width = width + mMeasuredDimension[0];
if (i == 0) {
height = mMeasuredDimension[1];
}
} else {
height = height + mMeasuredDimension[1];
if (i == 0) {
width = mMeasuredDimension[0];
}
}
}
switch (widthMode) {
case View.MeasureSpec.EXACTLY:
width = widthSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
switch (heightMode) {
case View.MeasureSpec.EXACTLY:
height = heightSize;
case View.MeasureSpec.AT_MOST:
case View.MeasureSpec.UNSPECIFIED:
}
setMeasuredDimension(width, height);
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
try {
View view = recycler.getViewForPosition(0);//fix 动态添加时报IndexOutOfBoundsException
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight(), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom(), p.height);
view.measure(childWidthSpec, childHeightSpec);
measuredDimension[0] = view.getMeasuredWidth() + p.leftMargin + p.rightMargin;
measuredDimension[1] = view.getMeasuredHeight() + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
You can just copy and past the custom layout manager as above and in set up your recyclerview in the parent adapter like this:
RecyclerView.LayoutManager layoutManager = new CustomLinearLayoutManager(mContext);
holder.childRecyclerView.setLayoutManager(layoutManager);
Remember : Don't use same layoutManager as parent adapter, or error will occur.
这篇关于如何拥有一个ListView / RecyclerView父RecyclerView里面?我有一个父列表,其中包含一些孩子名单在每一个位置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!