在垂直recyclerView中使用wrap_content的水平recyclerView

5

在我的应用程序中,我有一个情况,需要在垂直RecyclerView中创建水平RecyclerView。其中有些行将显示常规细节,而在某些行中将显示水平RecyclerView。

我已将水平RecyclerView的高度设置为wrap_content,但它不可见。但是当我将硬编码高度添加到其中时,RecyclerView就可见了。我已经搜索了很多关于这个问题的解决方案,但没有找到任何有效或令人信服的解决方案。

这是我的适配器类

public class HomeRVAdapter extends RecyclerView.Adapter<HomeRVAdapter.HomeViewHolder> {
private ArrayList<LinkedHashMap<String, Object>> data;
private Context ctx;
private int selectedIndex;

public HomeRVAdapter(Context ctx, ArrayList<LinkedHashMap<String, Object>> val) {
    data = val;
    this.ctx = ctx;
    selectedIndex = -1;
}

@Override
public HomeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    LayoutInflater inflater = ((Activity) ctx).getLayoutInflater();

    View view = inflater.inflate(R.layout.custom_home_recycler, null);

    return new HomeViewHolder(view);
}

@Override
public int getItemCount() {
    return data.size();
}

@Override
public void onBindViewHolder(final HomeViewHolder holder, final int position) {
    if (getItemCount() == position+1) {
        holder.categoryLL.setVisibility(View.GONE);
        holder.productLL.setVisibility(View.VISIBLE);

        LinearLayoutManager manager = new LinearLayoutManager(ctx);
        manager.setOrientation(LinearLayoutManager.HORIZONTAL);

        ArrayList<SubCategoryDetails> list = new ArrayList<>();
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());
        list.add(new SubCategoryDetails());

        holder.subCatRV.setAdapter(new PromoProductAdapter(list, holder.subCatRV));
        holder.subCatRV.setLayoutManager(manager);

    } else {
        holder.categoryLL.setVisibility(View.VISIBLE);
        holder.productLL.setVisibility(View.GONE);

        if (selectedIndex == position) {
            holder.subCatGrid.setVisibility(View.VISIBLE);
            showGrid(holder);
        } else {
            holder.subCatGrid.setVisibility(View.GONE);
        }

        holder.catTR.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (selectedIndex == position) {
                    holder.subCatGrid.setVisibility(View.GONE);
                    selectedIndex = -1;
                } else {
                    selectedIndex = position;
                    showGrid(holder);
                }
            }
        });
    }
}

private void showGrid(HomeViewHolder holder) {
    ArrayList<SubCategoryDetails> list = new ArrayList<>();
    list.add(new SubCategoryDetails());
    list.add(new SubCategoryDetails());
    list.add(new SubCategoryDetails());
    list.add(new SubCategoryDetails());
    list.add(new SubCategoryDetails());
    list.add(new SubCategoryDetails());
    list.add(new SubCategoryDetails());

    SubCategoryGridAdapter adapter = new SubCategoryGridAdapter(list);

    holder.subCatGrid.setAdapter(adapter);
    holder.subCatGrid.setVisibility(View.VISIBLE);
}

class HomeViewHolder extends RecyclerView.ViewHolder {
    RecyclerView subCatRV;
    TextView catTitleTV, productNameTV;
    ImageView productIV;
    NonScrollableGridView subCatGrid;
    LinearLayout categoryLL, productLL;
    TableRow catTR;

    public HomeViewHolder(View view) {
        super(view);

        subCatRV = (RecyclerView) view.findViewById(R.id.subCatRV);
        productNameTV = (TextView) view.findViewById(R.id.productNameTV);

        catTitleTV = (TextView) view.findViewById(R.id.catTitleTV);
        productIV = (ImageView) view.findViewById(R.id.productIV);
        subCatGrid = (NonScrollableGridView) view.findViewById(R.id.subCatGrid);
        categoryLL = (LinearLayout) view.findViewById(R.id.categoryLL);
        productLL = (LinearLayout) view.findViewById(R.id.productLL);
        catTR = (TableRow) view.findViewById(R.id.catTR);
    }
}

class SubCategoryGridAdapter extends BaseAdapter {
    ArrayList<SubCategoryDetails> subCatData;

    public SubCategoryGridAdapter(ArrayList<SubCategoryDetails> subCatData){
        this.subCatData = subCatData;
    }

    @Override
    public int getCount() {
        return subCatData.size();
    }

    @Override
    public Object getItem(int position) {
        return null;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        if (convertView == null) {
            convertView = ((Activity) ctx).getLayoutInflater().inflate(R.layout.custom_sub_cat_grid, null, true);
        }

        return convertView;
    }

    @Override
    public long getItemId(int position) {
        return 0;
    }
}

class PromoProductAdapter extends RecyclerView.Adapter<PromoProductAdapter.PromoHolder> {
    ArrayList<SubCategoryDetails> data;
    RecyclerView horizontalRV;

    public PromoProductAdapter(ArrayList<SubCategoryDetails> data, RecyclerView horizontalRV){
        this.data = data;
        this.horizontalRV = horizontalRV;
    }

    @Override
    public PromoHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        LayoutInflater inflater = ((Activity) ctx).getLayoutInflater();

        View view = inflater.inflate(R.layout.custom_promoted_product, null);

        if (horizontalRV != null) {
            int height = view.getMeasuredHeight();
            horizontalRV.getLayoutParams().height = height;
        }

        return new PromoHolder(view);
    }

    @Override
    public int getItemCount() {
        return data.size();
    }

    @Override
    public void onBindViewHolder(PromoHolder holder, int position) {

    }

    class PromoHolder extends RecyclerView.ViewHolder {
        public PromoHolder(View view) {
            super(view);
        }
    }
}

请帮助我解决这个问题。


1
你能发布适配器代码吗? - Anitha Manikandan
通常情况下,RecyclerView 不会使用 wrap_content 高度。 - mr.icetea
我已经更新了我的问题。 - Kislay Kumar
@mr.icetea,你有什么建议来管理我的RecyclerView的高度? - Kislay Kumar
@KislayKumar 看起来像是hack,但你尝试过将你的RecyclerView包裹在某个布局中,并设置该布局的高度,然后将RecyclerView保留为match_parent属性吗? - Dima
@Dima 它不起作用,我也尝试过那个方法... 除了添加硬编码高度之外,还有其他方法吗? - Kislay Kumar
2个回答

1
一个更简单的解决方案是将高度硬编码(因为它是水平视图,高度可以保持不变),然后在输入为空时隐藏水平滚动视图。
if(list.size() == 0){
   horizontalRecyclerView.setVisibility(View.GONE);
}

0

我自己解决了这个问题。我使用了一个自定义的LinearLayoutManager,它是从链接中找到的。

public class MyLinearLayoutManager extends LinearLayoutManager {

public MyLinearLayoutManager(Context context) {
    super(context);
}

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);

    measureScrapChild(recycler, 0,
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
            mMeasuredDimension);

    int width = mMeasuredDimension[0];
    int height = mMeasuredDimension[1];

    switch (widthMode) {
        case View.MeasureSpec.EXACTLY:
        case View.MeasureSpec.AT_MOST:
            width = widthSize;
            break;
        case View.MeasureSpec.UNSPECIFIED:
    }

    switch (heightMode) {
        case View.MeasureSpec.EXACTLY:
        case View.MeasureSpec.AT_MOST:
            height = heightSize;
            break;
        case View.MeasureSpec.UNSPECIFIED:
    }

    setMeasuredDimension(width, height);
}

private void measureScrapChild(RecyclerView.Recycler recycler, int position, int widthSpec,
                               int heightSpec, int[] measuredDimension) {
    View view = recycler.getViewForPosition(position);
    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();
        measuredDimension[1] = view.getMeasuredHeight();
        recycler.recycleView(view);
    }
}}

只需要将这个LinearLayoutManager添加到你的RecyclerView中,就可以了。

谢谢大家 干杯!!!


这个方法可能曾经有效,但现在已经不再适用了。我尝试过它,但在试图测量不存在的东西时崩溃了。但仅测量第一个项目似乎也不太合适。 - Kenny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接