horizo​​ntal recyclerView与vertical recycconView中的wrap_content一起使用

时间:2015-09-21 07:33:05

标签: android android-recyclerview

在我的应用程序中,我遇到了必须在垂直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);
        }
    }
}

}

请帮我解决这个问题。

2 个答案:

答案 0 :(得分:1)

我自己解决了这个问题。我使用了从link找到的自定义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即可。

谢谢大家 干杯!!!

答案 1 :(得分:1)

更简单的解决方案可以是保持高度硬编码(因为它是水平视图,高度可以保持固定),然后如果输入为空则隐藏水平回收器视图。

if(list.size() == 0){
   horizontalRecyclerView.setVisibility(View.GONE);
}