39

当前视图是

我的回收站项目在 onCreateViewHolder 中膨胀

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:gravity="center"
    android:orientation="vertical"
    android:padding="16dp">

    <ImageView
        android:id="@+id/gridListImageView"
        android:layout_width="96dp"
        android:layout_height="96dp"
        android:src="@drawable/a" />

    <TextView
        android:id="@+id/gridListView_title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="Large Text"
        android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>

我想显示这样的东西 哪一行的高度是回收站视图的一半?并为其余空间添加填充?我可以通过 GridLayoutManager 做到这一点吗?

这是我的 GridLayoutManager

        GridLayoutManager glm = new GridLayoutManager(getActivity(), 2);
        recyclerView.setLayoutManager(glm);
4

9 回答 9

70

在适配器中为视图扩展布局时,您可以通过编程方式设置它们的高度。为了评估要使用的正确高度,您可以依赖父 ViewGroup(即 RecyclerView 本身)。这是一个示例:

@Override
public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = mLayoutInflater.inflate(R.layout.view_item, parent, false);
    // work here if you need to control height of your items
    // keep in mind that parent is RecyclerView in this case
    int height = parent.getMeasuredHeight() / 4;
    itemView.setMinimumHeight(height);
    return new ItemViewHolder(itemView);        
}

希望这会有所帮助。

于 2016-02-06T07:26:21.200 回答
27

从支持库 25.1.0 开始,上述答案不起作用。我建议进行以下修改:

    public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, parent, false);
        GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams) v.getLayoutParams();
        lp.height = parent.getMeasuredHeight() / 4;
        v.setLayoutParams(lp);
        return new ViewHolder(v);
    }
于 2017-04-03T21:59:07.020 回答
18

您不需要设置项目的高度。这里的问题是图像试图填满所有空间。只需添加 android:adjustViewBounds="true"到您的 ImageView,它不会添加空格

于 2018-02-25T22:41:37.173 回答
11
v.getLayoutParams().width = parent.getMeasuredWidth() / 2;

v.getLayoutParams().height = parent.getMeasuredWidth() / 2;
于 2018-04-28T09:35:38.443 回答
4

科特林版本

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
    val binding = ItemBinding.inflate(
        LayoutInflater.from(parent.context),
        parent,
        false
    )
    binding.root.post {
        binding.root.layoutParams.height = parent.width/3
        binding.root.requestLayout()
    }
    return ViewHolder(binding)
}

这里 3 是你的跨度计数GridLayoutManager 。如果您不使用数据绑定,则可以替换 binding.rootitemView

于 2020-03-13T06:46:21.827 回答
3

有时,在适配器中获取膨胀视图的大小返回 0 或负数。另一种方法是从适配器外部获取所需的大小,对其进行操作并将其设置为视图。就我而言,另一个问题是尺寸设置无效。所以我使用布局参数设置大小

这是在活动中设置我的适配器:

Display display = MainActivity.this.getWindowManager().getDefaultDisplay();
                    Point size = new Point();
                    display.getSize(size);
                    int  y = size.y;
                    y=(int)y/2;
 GridLayoutManager linearLayoutManager = new GridLayoutManager(MainActivity.this,2);
                    recyclerView.setLayoutManager(linearLayoutManager);
                    NewOrderAdapter newOrderAdapter=new NewOrderAdapter(MainActivity.this,arrayListname,arrayListimage,y);
                    recyclerView.setAdapter(newOrderAdapter);

我像这样设置视图大小:

@Override
    public myviewholder onCreateViewHolder(ViewGroup viewGroup, int i) {
        View view = inflator.inflate(R.layout.new_order_row, viewGroup, false);
        GridLayoutManager.LayoutParams params = (GridLayoutManager.LayoutParams) view.getLayoutParams();
        params.height = ysize;
        view.setLayoutParams(params);
        myviewholder holder = new myviewholder(view);
        return holder;
    }

并且不要忘记在您的布局中设置布局高度以进行初始化

于 2017-01-15T15:32:00.957 回答
3

在最近的 API 级别当前为 25 时,onCreateViewHolder 中回收器的高度始终为空。此代码段用于在调用回收器视图的 onMeasure 后设置高度,并将正确的高度设置为膨胀的列表视图。

@Override
public DataBindingViewHolder onCreateViewHolder(final ViewGroup parent, int viewType) {
    // You may inflate your view here.
    parent.post(new Runnable() {

        @Override
        public void run() {
            int height = parent.getMeasuredHeight() / rows;
            View view = holder.getBinding().getRoot();
            view.getLayoutParams().height = height;
        }
    });
    return holder;
}
于 2017-02-13T11:42:39.747 回答
1

这是我的代码,用于根据所需的实际纵横比调整回收视图元素的高度。

@Override
public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View itemView = LayoutInflater.from(parent.getContext()) .inflate(R.layout.adapter_offers, parent, false);

    int width =  parent.getMeasuredWidth();
    float height = (float) width / Config.ASPECT_RATIO;//(Width/Height)
    RecyclerView.LayoutParams params = (RecyclerView.LayoutParams) itemView.getLayoutParams();
    params.height = Math.round(height);
    itemView.setLayoutParams(params);
    return new MyViewHolder(itemView);
}
于 2017-06-10T06:11:23.120 回答
1

我有一个类似的要求,它需要网格中每一行的动态高度,并且能够从 RecyclerView 添加和删除项目。在此处很少有答案建议的情况下设置高度布局参数onCreateViewHolder的问题是,当从 RecyclerView 添加/删除项目时,视图被回收并且onCreateViewHolder不会再次调用,而是池中的视图被重新调用使用过(如果可用),布局管理器会计算项目的高度/宽度,我们将丢失在onCreateViewHolder.

下面的这种方法可能会对面临类似问题的人有所帮助。

这里的关键步骤是扩展GridLayoutManager和覆盖以下内容 -

  1. generateDefaultLayoutParams
  2. generateLayoutParams
  3. checkLayoutParams

布局管理器看起来像这样 -

SpanGridLayoutManager : GridLayoutManager {

constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int, defStyleRes: Int) :
        super(context, attrs, defStyleAttr, defStyleRes)

constructor(context: Context, spanCount: Int) : super(context, spanCount)
constructor(context: Context, spanCount: Int, orientation: Int, reverseLayout: Boolean) :
        super(context, spanCount, orientation, reverseLayout)

override fun generateDefaultLayoutParams(): RecyclerView.LayoutParams {
    return spanLayoutSize(super.generateDefaultLayoutParams())
}

override fun generateLayoutParams(c: Context, attrs: AttributeSet): RecyclerView.LayoutParams {
    return spanLayoutSize(super.generateLayoutParams(c, attrs))
}

override fun generateLayoutParams(lp: ViewGroup.LayoutParams): RecyclerView.LayoutParams {
    return spanLayoutSize(super.generateLayoutParams(lp))
}

override fun checkLayoutParams(lp: RecyclerView.LayoutParams): Boolean {
    val layoutParams = generateDefaultLayoutParams()
    return super.checkLayoutParams(lp) &&
            layoutParams.width == lp.width &&
            layoutParams.height == lp.height
}

private fun spanLayoutSize(layoutParams: RecyclerView.LayoutParams): RecyclerView.LayoutParams {
    layoutParams.height = if (some_condition) x else y
    return layoutParams
}

这里xy可以是您需要提供的像素高度。

于 2021-03-24T05:29:36.423 回答