我有一个带有多个ViewHolders的RecyclerView适配器。每个ViewHolder都有一个标题TextView和一个嵌套的RecyclerView,它们工作正常。但是我想实现一个扩展/折叠功能,以便隐藏嵌套的RecyclerView,直到单击标题为止。我使用了这种方法RecyclerView expand/collapse items。它可以工作,但是当我单击标题以展开嵌套的recylerview时,recyclerview不会填充任何数据。明确地说,它检索数据,但不可见。任何想法为什么会这样?
这是我的onBindViewMethod:
public class EligibilityAdapter extends RecyclerView.Adapter<EligibilityAdapter.ViewHolder> {
private Context mContext;
private List<EligibilityDetails> mEligsList;
private List<Items> mItemslist;
private LayoutInflater inflater;
private int mExpandedPosition = -1;
public EligibilityAdapter(Context context, List<EligibilityDetails> eligsList) {
mContext = context;
mEligsList = eligsList;
inflater = LayoutInflater.from(context);
}
@Override
public int getItemViewType(int position) {
switch (position) {
case 0:
return R.layout.rv_eligs_item_domestic;
case 1:
return R.layout.rv_eligs_item_overseas;
default:
return R.layout.rv_eligs_item_military;
}
}
@NonNull
@Override
public ViewHolder onCreateViewHolder(@NonNull ViewGroup viewGroup, int i) {
inflater = LayoutInflater.from(viewGroup.getContext());
View view = inflater.inflate(i, viewGroup, false);
ViewHolder holder = null;
switch (i) {
case R.layout.rv_eligs_item_domestic:
holder = new DomesticViewHolder(view);
break;
case R.layout.rv_eligs_item_overseas:
holder = new OverseasViewHolder(view);
break;
case R.layout.rv_eligs_item_military:
holder = new MilitaryViewHolder(view);
break;
}
return holder;
}
@Override
public int getItemCount() {
return mEligsList.size();
}
public abstract class ViewHolder extends RecyclerView.ViewHolder {
RecyclerView itemsRv;
TextView mHeader;
ItemsAdapter adapter;
public ViewHolder(View itemView) {
super(itemView);
mHeader = (TextView) itemView.findViewById(R.id.header_tv);
itemsRv = itemView.findViewById(R.id.recyclerViewItems);
}
public void setData(List<Items> list) {
adapter.updateList(list);
}
abstract void bind(EligibilityDetails item);
}
public class DomesticViewHolder extends ViewHolder {
TextView mHeader;
RecyclerView itemsRv;
ItemsAdapter adapter;
public DomesticViewHolder(View itemView) {
super(itemView);
mHeader = (TextView) itemView.findViewById(R.id.header_tv);
itemsRv = itemView.findViewById(R.id.recyclerViewItems);
}
public void setData(List<Items> list) {
adapter.updateList(list);
}
@Override
void bind(EligibilityDetails eligibilityDetails) {
mHeader.setText(eligibilityDetails.getRequirementHeader());
mItemslist = eligibilityDetails.getItemsList();
ItemsAdapter itemsAdapter = new ItemsAdapter(mContext, mItemslist);
itemsRv.setHasFixedSize(true);
itemsRv.setLayoutManager(new CustomLinearLayoutManager(mContext));
itemsRv.setAdapter(itemsAdapter);
itemsRv.setNestedScrollingEnabled(false);
}
}
public class OverseasViewHolder extends ViewHolder {
TextView mHeader;
RecyclerView itemsRv;
ItemsAdapter adapter;
public OverseasViewHolder(View itemView) {
super(itemView);
mHeader = (TextView) itemView.findViewById(R.id.header_tv);
itemsRv = itemView.findViewById(R.id.recyclerViewItems);
}
public void setData(List<Items> list) {
adapter.updateList(list);
}
@Override
void bind(EligibilityDetails eligibilityDetails) {
mHeader.setText(eligibilityDetails.getRequirementHeader());
mItemslist = eligibilityDetails.getItemsList();
ItemsAdapter itemsAdapter = new ItemsAdapter(mContext, mItemslist);
itemsRv.setHasFixedSize(true);
itemsRv.setLayoutManager(new CustomLinearLayoutManager(mContext));
itemsRv.setAdapter(itemsAdapter);
itemsRv.setNestedScrollingEnabled(false);
}
}
public class MilitaryViewHolder extends ViewHolder {
TextView mHeader;
RecyclerView itemsRv;
ItemsAdapter adapter;
public MilitaryViewHolder(View itemView) {
super(itemView);
mHeader = (TextView) itemView.findViewById(R.id.header_tv);
itemsRv = itemView.findViewById(R.id.recyclerViewItems);
}
public void setData(List<Items> list) {
adapter.updateList(list);
}
@Override
void bind(EligibilityDetails eligibilityDetails) {
mHeader.setText(eligibilityDetails.getRequirementHeader());
mItemslist = eligibilityDetails.getItemsList();
final ItemsAdapter itemsAdapter = new ItemsAdapter(mContext, mItemslist);
itemsRv.setHasFixedSize(true);
itemsRv.setLayoutManager(new CustomLinearLayoutManager(mContext));
itemsRv.setAdapter(itemsAdapter);
itemsRv.setNestedScrollingEnabled(false);
}
}
@Override
public void onBindViewHolder(@NonNull final EligibilityAdapter.ViewHolder viewHolder, int i) {
viewHolder.bind(mEligsList.get(i));
final boolean isExpanded = i == mExpandedPosition;
viewHolder.itemsRv.setVisibility(isExpanded?View.VISIBLE:View.GONE);
viewHolder.itemView.setActivated(isExpanded);
viewHolder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mExpandedPosition = isExpanded ? -1:viewHolder.getAdapterPosition();
ItemsAdapter itemsAdapter = new ItemsAdapter(mContext, mItemslist);
viewHolder.itemsRv.setAdapter(itemsAdapter);
//TransitionManager.beginDelayedTransition(recyclerView);
notifyDataSetChanged();
}
});
}
其中itemsRv是嵌套的RecyclerView。 我尝试将这种逻辑移到各个视图持有者,并在这里将recyclerview逻辑移到这里,就像在onClick方法中设置适配器一样。每次出现空白。
谢谢。
答案 0 :(得分:0)
您可以创建一个多视图类型的适配器,而不是为每个标头添加一个新的子Recyclerview
,该适配器将为您的标头提供一个视图类型,并为您的子项提供一个视图类型。
使用通用类型将数据类型转换为自己的视图类型,而不是仅将标题数据项用于数据列表。
要做到这一点,我们需要创建一个空接口,所有数据类型都将以这种方式实现它们都是通用的。
public interface GenericDataType {}
因此您的数据类型将如下所示
class HeaderItem implements GenericDataType {
//All of your pojo data
List<ChildrenItem> childrens; //ChildrenItem will also implement the GenericDataType that way both of the items are acceptable
}
所以我们做到了,我们可以替换当前的项目
private List<EligibilityDetails> mEligsList;
private List<Items> mItemslist;
收件人
private List<GenericDataType> adapterItems;
现在,我们需要确保只要我们有某个ViewHolder
,该职位的项目就会是正确的类型。为此,我们需要更改getItemViewType
@Override
public int getItemViewType(int position) {
GenericItem currentItem = adapterItems.get(position);
if (currentItem instanceOf HeaderItem) { //We have to use if else becasue java's switch does not supprt checking instancesOf
return R.layout.your_header_item_layout_id;
} else if(currentItem instanceOf ChildrenItem) {
return R.layout.your_children_item_layout_id;
} else if(repeat for any other types you have) {
return R.layout.your_other_item_layout_id;
} else {
throw new Throwable("Unsupported type"); //This should never happen but we add it to make the compiler compile
}
}
现在,我们终于可以更改我们的onBind
方法以支持两种类型
@Override
public void onBindViewHolder(@NonNull final EligibilityAdapter.ViewHolder viewHolder, int i) {
if (viewHolder instanceOf HeaderViewHolder) {
HeaderViewHolder holder = (HeaderViewHolder) viewHolder;
headerItem = (HeaderItem) items.get(i);
//Do rest of binding here
holder.viewToAddMoreItems.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!headerItem.isEpanded()) { //Add to your header type a Boolean to check if it is expanded or not
adapterItems.addAll(headerItem.getChildrens()); //They are the same generic type but the getItemViewType will handle it for us
notifyItemRangeInserted(); //Provied item start index and size of the list
} else {
adapterItems.removeAll(headerItem.getChildrens());
notifyItemRangeRemoved(); I don't remember what it require but you'll figure that out
}
headerItem.setExpanded(!headerItem.isExpanded()); //Flipping the value
}
});
} else if (viewHolder instanceOf ChildrenViewHolder) {
ChildrenViewHolder holder = (ChildrenViewHolder) viewHolder;
childrenItem = (ChildrenItem) items.get(i);
//Do your binding here
} else if(repeate for other view-types) {}
}