RecyclerView getLayoutParams返回null(有时)



我有一个RecyclerView,我有一个自定义适配器,并且我已经将LayoutManager设置为FlexboxLayoutManager。对于每个孩子,我想将 FlexGrow 设置为 1。

在Google的例子demo-cat-gallery(https://github.com/google/flexbox-layout(中,他们在ViewHolder中这样做:

void bindTo(Drawable drawable) {
mImageView.setImageDrawable(drawable);
ViewGroup.LayoutParams lp = mImageView.getLayoutParams();
if (lp instanceof FlexboxLayoutManager.LayoutParams) {
FlexboxLayoutManager.LayoutParams flexboxLp = (FlexboxLayoutManager.LayoutParams) lp;
flexboxLp.setFlexGrow(1.0f);
}
}

然后由 onBindViewHolder 中的 RecyclerView.Adapter 调用。这工作正常,但是当我在我的应用程序中执行相同的操作时,它只会为某些项目设置 FlexGrow,而不会设置顶部的项目。我意识到对于某些项目(看似随机(,getLayoutParams((返回null,但对于其他项目,它返回正确的FlexboxLayoutManager.LayoutParams。

我意识到不同之处在于,在Cat-gallery示例中,onCreateViewHolder正在做

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.viewholder_cat, parent, false);
return new CatViewHolder(view);
}

当我在我的应用程序中做

public RecyclerView.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType)
{
return new MyViewHolder(new MyCustomView(getContext()));
}

似乎使用对父级的引用进行膨胀意味着getLayoutParams((永远不会为空,因此将我的代码更改为

View v = new MyCustomView(getContext());
parent.addView(v);
return new MyViewHolder(v);

它现在可以正常工作,并且始终设置setFlexGrow((。但是,这感觉不对 - 我知道您不应该明确地将视图添加到 RecyclerView 父级。

所以我的问题是:

1 - 为什么 LayoutParams 对某些项目随机为空,但对其他项目很好?

2 - 如何让 LayoutParams 始终被设置,而不做一些可怕的事情,比如"parent.addView(v(;",或者这样做真的没问题吗?

谢谢:)

这似乎是FlexboxLayoutManager的一个错误。我试过做

parent.addView(v);

但这产生了非常奇怪的崩溃。

事实证明,虽然FlexboxLayoutManager可能不会在onBindViewHolder之前附加LayoutParams,但它会在onViewAttachedToWindow之前这样做。因此,您可以像这样设置布局参数:

override fun onViewAttachedToWindow(holder: ViewHolder<View>) {
super.onViewAttachedToWindow(holder)
holder.itemView.updateLayoutParams {
// Whatever
}
}

旧答案:仍然有效,但更笨拙。

最后,我产生了这个解决方法:

parent.addView(v);
ViewGroup.LayoutParams params = v.getLayoutParams();
parent.removeView(v);
v.setLayoutParams(params);

最新更新