如何在 GridLayoutManager 中设置项目行的高度
How to set the height of an item row in GridLayoutManager
我的 Recycler Item 在 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>
I want to display something like this
哪一行的高度是回收器视图的一半?
并向 space 的其余部分添加填充?
我可以通过 GridLayoutManager 做到这一点吗?
这是我的 GridLayoutManager
GridLayoutManager glm = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(glm);
在适配器中为您的视图扩充布局时,您可以通过编程方式设置它们的高度。为了评估要使用的适当高度,您可以依赖父 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);
}
希望这对您有所帮助。
有时,在适配器 return 中获取膨胀视图的大小为 0 或负数。另一种方法是从适配器外部获取所需的大小,对其进行操作并将其设置为可见。就我而言,另一个问题是大小设置无效。所以我使用布局参数设置大小
这里是在 activity 中设置我的适配器:
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;
}
并且不要忘记在您的布局中设置高度以进行初始化
在最近的 API 关卡中,当前距离 onCreateViewHolder 中回收站的高度为 25
总是空的。此代码段用于在回收站视图的 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;
}
从支持库 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);
}
这是我根据实际所需的纵横比调整回收视图元素高度的代码。
@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);
}
您不需要设置项目的高度。这里的问题是图像试图填充所有 space。只需添加
android:adjustViewBounds="true"
到您的 ImageView,它不会添加空白 spaces
v.getLayoutParams().width = parent.getMeasuredWidth() / 2;
v.getLayoutParams().height = parent.getMeasuredWidth() / 2;
kotlin 版本
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
的跨度数
.如果您不使用 Databinding
,则可以将 binding.root
替换为 itemView
我有一个类似的要求,需要为网格中的每一行设置一个动态高度,并能够在 RecyclerView 中添加和删除项目。在 onCreateViewHolder
中设置高度布局参数的问题正如这里的一些答案所暗示的那样,当一个项目是来自 RecyclerView 的 added/removed 时,视图被回收,而 onCreateViewHolder
不是再次调用,而是重新使用池中的视图(如果可用),布局管理器将通过计算项目的 height/width,我们将丢失原始预期的 height/width 集onCreateViewHolder
.
下面的这种方法可能会对遇到类似问题的人有所帮助。
这里的关键步骤是扩展 GridLayoutManager
并覆盖以下 -
generateDefaultLayoutParams
generateLayoutParams
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
}
此处 x
和 y
可以是您需要提供的高度(以像素为单位)。
我的 Recycler Item 在 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>
I want to display something like this 哪一行的高度是回收器视图的一半? 并向 space 的其余部分添加填充? 我可以通过 GridLayoutManager 做到这一点吗?
这是我的 GridLayoutManager
GridLayoutManager glm = new GridLayoutManager(getActivity(), 2);
recyclerView.setLayoutManager(glm);
在适配器中为您的视图扩充布局时,您可以通过编程方式设置它们的高度。为了评估要使用的适当高度,您可以依赖父 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);
}
希望这对您有所帮助。
有时,在适配器 return 中获取膨胀视图的大小为 0 或负数。另一种方法是从适配器外部获取所需的大小,对其进行操作并将其设置为可见。就我而言,另一个问题是大小设置无效。所以我使用布局参数设置大小
这里是在 activity 中设置我的适配器:
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;
}
并且不要忘记在您的布局中设置高度以进行初始化
在最近的 API 关卡中,当前距离 onCreateViewHolder 中回收站的高度为 25 总是空的。此代码段用于在回收站视图的 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;
}
从支持库 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);
}
这是我根据实际所需的纵横比调整回收视图元素高度的代码。
@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);
}
您不需要设置项目的高度。这里的问题是图像试图填充所有 space。只需添加
android:adjustViewBounds="true"
到您的 ImageView,它不会添加空白 spaces
v.getLayoutParams().width = parent.getMeasuredWidth() / 2;
v.getLayoutParams().height = parent.getMeasuredWidth() / 2;
kotlin 版本
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
的跨度数
.如果您不使用 Databinding
binding.root
替换为 itemView
我有一个类似的要求,需要为网格中的每一行设置一个动态高度,并能够在 RecyclerView 中添加和删除项目。在 onCreateViewHolder
中设置高度布局参数的问题正如这里的一些答案所暗示的那样,当一个项目是来自 RecyclerView 的 added/removed 时,视图被回收,而 onCreateViewHolder
不是再次调用,而是重新使用池中的视图(如果可用),布局管理器将通过计算项目的 height/width,我们将丢失原始预期的 height/width 集onCreateViewHolder
.
下面的这种方法可能会对遇到类似问题的人有所帮助。
这里的关键步骤是扩展 GridLayoutManager
并覆盖以下 -
generateDefaultLayoutParams
generateLayoutParams
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
}
此处 x
和 y
可以是您需要提供的高度(以像素为单位)。