Android 自定义LinearLayoutManager的父RecyclerView中的嵌套/子RecyclerView工作不正常
我尝试了下面介绍如何使用自定义的Android 自定义LinearLayoutManager的父RecyclerView中的嵌套/子RecyclerView工作不正常,android,android-layout,android-activity,android-adapter,android-recyclerview,Android,Android Layout,Android Activity,Android Adapter,Android Recyclerview,我尝试了下面介绍如何使用自定义的LinearLayoutManager,但是嵌套的RecyclerView根本没有显示 活动中的父RecyclerView: 父回收器视图的适配器: 请注意,子/嵌套回收视图位于选项ViewHolder内: public class DishDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> { private List<DishOption>
LinearLayoutManager
,但是嵌套的RecyclerView
根本没有显示
活动中的父RecyclerView:
父回收器视图的适配器:
请注意,子/嵌套回收视图位于选项ViewHolder
内:
public class DishDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<DishOption> options;
private Context context;
private SharedData sharedData = SharedData.getInstance();
public DishDetailsAdapter(List<DishOption> detailsList, Context parentContext) {
options = detailsList;
context = parentContext;
sharedData.setMainFont(context);
sharedData.setSecondaryFont(context);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.category_dish_dialog_option, parent, false);
RecyclerView.ViewHolder viewHolder = new OptionsViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
DishOption dishOption = options.get(position);
OptionsViewHolder vh = (OptionsViewHolder) holder;
vh.optionName.setText(dishOption.getTitle());
vh.optionName.setTypeface(sharedData.getSecondaryFont());
List<DishOptionItem> dishOptionItems = dishOption.getItems();
ItemsAdapter itemsAdapter = new ItemsAdapter(dishOptionItems, context);
//NOTICE CHILD/NESTED RECYCLER VIEW HERE!!!!!!!!!!!!!!!!!!!!!!!
vh.nestedRecyclerView.setAdapter(itemsAdapter);
itemsAdapter.notifyDataSetChanged();
LinearLayoutManager layoutManager = new NestedLinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
vh.nestedRecyclerView.setLayoutManager(layoutManager);
}
@Override
public int getItemCount() {
return options.size();
}
/**
* View holders for dish options Options
*/
public class OptionsViewHolder extends RecyclerView.ViewHolder {
private TextView optionName;
private RecyclerView nestedRecyclerView;
public OptionsViewHolder(View itemView) {
super(itemView);
optionName = (TextView) itemView.findViewById(R.id.dish_dialog_option_title);
nestedRecyclerView = (RecyclerView) itemView.findViewById(R.id.category_nested_recycler_view);
}
}
}
公共类DishDetailsAdapter扩展了RecyclerView.Adapter{
私人名单选择;
私人语境;
private SharedData SharedData=SharedData.getInstance();
公共DishDetailsAdapter(列表详细信息列表,上下文父上下文){
选项=详细信息列表;
上下文=父上下文;
setMainFont(上下文);
sharedData.setSecondaryFont(上下文);
}
@凌驾
public RecyclerView.ViewHolder onCreateViewHolder(视图组父级,int-viewType){
LayoutInflater充气器=LayoutInflater.from(parent.getContext());
视图=充气机。充气(R.layout.category\u dish\u dialog\u选项,父项,false);
RecyclerView.ViewHolder ViewHolder=新选项ViewHolder(视图);
返回视图持有者;
}
@凌驾
BindViewHolder上的公共无效(RecyclerView.ViewHolder,int位置){
DishOption DishOption=options.get(位置);
选项视窗支架vh=(选项视窗支架)支架;
vh.optionName.setText(dishOption.getTitle());
vh.optionName.setTypeface(sharedData.getSecondaryFont());
List dishOptionItems=dishOption.getItems();
ItemsAdapter ItemsAdapter=新的ItemsAdapter(disoptionItems,上下文);
//注意这里的儿童/嵌套回收者视图!!!!!!!!!!!!!!!!!!!!!!!
vh.NestedRecyclView.setAdapter(itemsAdapter);
itemsAdapter.notifyDataSetChanged();
LinearLayoutManager布局管理器=新嵌套的LinearLayoutManager(上下文,LinearLayoutManager.VERTICAL,false);
vh.nestedRecyclView.setLayoutManager(layoutManager);
}
@凌驾
public int getItemCount(){
返回选项。size();
}
/**
*查看盘子选项的支架
*/
公共类选项ViewHolder扩展了RecyclerView.ViewHolder{
私有文本视图选项名称;
私有回收视图嵌套回收视图;
公共选项ViewHolder(查看项目视图){
超级(项目视图);
optionName=(TextView)itemView.findViewById(R.id.dish\u dialog\u option\u title);
nestedRecyclerView=(RecyclerView)itemView.findViewById(R.id.category\u nested\u RecyclerView);
}
}
}
子/嵌套的RecyclerView适配器:
公共类ItemsAdapter扩展了RecyclerView.Adapter{
私人清单项目;
私人语境;
private SharedData SharedData=SharedData.getInstance();
公共项适配器(列表项列表、上下文父上下文){
项目=项目列表;
上下文=父上下文;
}
@凌驾
public RecyclerView.ViewHolder onCreateViewHolder(视图组父级,int-viewType){
LayoutInflater充气器=LayoutInflater.from(parent.getContext());
视图=充气机。充气(R.layout.category\u dish\u dialog\u item,parent,false);
RecyclerView.ViewHolder ViewHolder=新项目ViewHolder(视图);
返回视图持有者;
}
@凌驾
BindViewHolder上的公共无效(RecyclerView.ViewHolder,int位置){
DishOptionItem item=items.get(位置);
ItemViewHolder iVH=(ItemViewHolder)holder;
iVH.itemName.setText(item.getName());
}
@凌驾
public int getItemCount(){
返回items.size();
}
/**
*查看菜肴选项项目的支架
*/
公共类ItemViewHolder扩展了RecyclerView.ViewHolder{
私有文本视图项目名称;
私有文本视图项目价格;
公共项目视图持有者(查看项目视图){
超级(项目视图);
itemName=(TextView)itemView.findViewById(R.id.dish\u dialog\u item\u name);
//itemPrice=(TextView)itemView.findViewById(R.id.dish\u dialog\u item\u price);
}
}
}
最后,自定义LinearLayoutManager:
公共类NestedLinearLayoutManager扩展了LinearLayoutManager{
公共嵌套LinearLayoutManager(上下文上下文、int方向、布尔反转){
超级(上下文、方向、反转);
}
私有int[]mMeasuredDimension=新int[2];
@凌驾
测量时的公共空隙(RecyclerView.Recycler Recycler,RecyclerView.State,
整数宽度规格、整数高度规格){
最终int-widthMode=View.MeasureSpec.getMode(widthmspec);
最终int heightMode=View.MeasureSpec.getMode(heightSpec);
最终int-widthSize=View.MeasureSpec.getSize(widthSpec);
最终int heightSize=View.MeasureSpec.getSize(heightSpec);
整数宽度=0;
整数高度=0;
对于(int i=0;ipublic class DishDetailsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<DishOption> options;
private Context context;
private SharedData sharedData = SharedData.getInstance();
public DishDetailsAdapter(List<DishOption> detailsList, Context parentContext) {
options = detailsList;
context = parentContext;
sharedData.setMainFont(context);
sharedData.setSecondaryFont(context);
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.category_dish_dialog_option, parent, false);
RecyclerView.ViewHolder viewHolder = new OptionsViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
DishOption dishOption = options.get(position);
OptionsViewHolder vh = (OptionsViewHolder) holder;
vh.optionName.setText(dishOption.getTitle());
vh.optionName.setTypeface(sharedData.getSecondaryFont());
List<DishOptionItem> dishOptionItems = dishOption.getItems();
ItemsAdapter itemsAdapter = new ItemsAdapter(dishOptionItems, context);
//NOTICE CHILD/NESTED RECYCLER VIEW HERE!!!!!!!!!!!!!!!!!!!!!!!
vh.nestedRecyclerView.setAdapter(itemsAdapter);
itemsAdapter.notifyDataSetChanged();
LinearLayoutManager layoutManager = new NestedLinearLayoutManager(context, LinearLayoutManager.VERTICAL, false);
vh.nestedRecyclerView.setLayoutManager(layoutManager);
}
@Override
public int getItemCount() {
return options.size();
}
/**
* View holders for dish options Options
*/
public class OptionsViewHolder extends RecyclerView.ViewHolder {
private TextView optionName;
private RecyclerView nestedRecyclerView;
public OptionsViewHolder(View itemView) {
super(itemView);
optionName = (TextView) itemView.findViewById(R.id.dish_dialog_option_title);
nestedRecyclerView = (RecyclerView) itemView.findViewById(R.id.category_nested_recycler_view);
}
}
}
public class ItemsAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<DishOptionItem> items;
private Context context;
private SharedData sharedData = SharedData.getInstance();
public ItemsAdapter(List<DishOptionItem> itemsList, Context parentParentContext) {
items = itemsList;
context = parentParentContext;
}
@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater inflater = LayoutInflater.from(parent.getContext());
View view = inflater.inflate(R.layout.category_dish_dialog_item, parent, false);
RecyclerView.ViewHolder viewHolder = new ItemViewHolder(view);
return viewHolder;
}
@Override
public void onBindViewHolder(RecyclerView.ViewHolder holder, int position) {
DishOptionItem item = items.get(position);
ItemViewHolder iVH = (ItemViewHolder) holder;
iVH.itemName.setText(item.getName());
}
@Override
public int getItemCount() {
return items.size();
}
/**
* View holders for dish options Items
*/
public class ItemViewHolder extends RecyclerView.ViewHolder {
private TextView itemName;
private TextView itemPrice;
public ItemViewHolder(View itemView) {
super(itemView);
itemName = (TextView) itemView.findViewById(R.id.dish_dialog_item_name);
//itemPrice = (TextView) itemView.findViewById(R.id.dish_dialog_item_price);
}
}
}
public class NestedLinearLayoutManager extends LinearLayoutManager {
public NestedLinearLayoutManager(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];
}
}
}
// If child view is more than screen size, there is no need to make it wrap content. We can use original onMeasure() so we can scroll view.
if (height < heightSize && width < widthSize) {
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);
} else {
super.onMeasure(recycler, state, widthSpec, heightSpec);
}
}
private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
int heightSpec, int[] measuredDimension) {
View view = recycler.getViewForPosition(position);
// For adding Item Decor Insets to view
super.measureChildWithMargins(view, 0, 0);
if (view != null) {
RecyclerView.LayoutParams p = (RecyclerView.LayoutParams) view.getLayoutParams();
int childWidthSpec = ViewGroup.getChildMeasureSpec(widthSpec,
getPaddingLeft() + getPaddingRight() + getDecoratedLeft(view) + getDecoratedRight(view), p.width);
int childHeightSpec = ViewGroup.getChildMeasureSpec(heightSpec,
getPaddingTop() + getPaddingBottom() + getPaddingBottom() + getDecoratedBottom(view) , p.height);
view.measure(childWidthSpec, childHeightSpec);
// Get decorated measurements
measuredDimension[0] = getDecoratedMeasuredWidth(view) + p.leftMargin + p.rightMargin;
measuredDimension[1] = getDecoratedMeasuredHeight(view) + p.bottomMargin + p.topMargin;
recycler.recycleView(view);
}
}
}