RecyclerView getLayoutParams returns null(有时)
RecyclerView getLayoutParams returns null (sometimes)
我有一个 RecyclerView,为此我有一个自定义适配器,我已将 LayoutManager 设置为 FlexboxLayoutManager。对于每个 child,我想将 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,而不会为顶部的项目设置 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()));
}
似乎用 parent 的引用膨胀意味着 getLayoutParams() 永远不会为空,所以将我的代码更改为
View v = new MyCustomView(getContext());
parent.addView(v);
return new MyViewHolder(v);
它现在可以正常工作,始终设置 setFlexGrow()。然而,这感觉不对 - 我知道你并不是要明确地将视图添加到 RecyclerView parent.
所以我的问题是:
1 - 为什么 LayoutParams 对于某些项目随机为空,但对于其他项目却没问题?
2 - 我怎样才能让 LayoutParams 始终被设置,而不做像 'parent.addView(v);' 这样可怕的事情,或者这样做真的可以吗?
谢谢:)
这似乎是 FlexboxLayoutManager 的错误。我试过
parent.addView(v);
但这产生了非常奇怪的崩溃。
事实证明,虽然 FlexboxLayoutManager 在 onBindViewHolder
之前可能不会附加 LayoutParams,但它会在 onViewAttachedToWindow
之前附加 LayoutParams。所以你可以像这样设置 LayoutParams:
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);
我有一个 RecyclerView,为此我有一个自定义适配器,我已将 LayoutManager 设置为 FlexboxLayoutManager。对于每个 child,我想将 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,而不会为顶部的项目设置 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()));
}
似乎用 parent 的引用膨胀意味着 getLayoutParams() 永远不会为空,所以将我的代码更改为
View v = new MyCustomView(getContext());
parent.addView(v);
return new MyViewHolder(v);
它现在可以正常工作,始终设置 setFlexGrow()。然而,这感觉不对 - 我知道你并不是要明确地将视图添加到 RecyclerView parent.
所以我的问题是:
1 - 为什么 LayoutParams 对于某些项目随机为空,但对于其他项目却没问题?
2 - 我怎样才能让 LayoutParams 始终被设置,而不做像 'parent.addView(v);' 这样可怕的事情,或者这样做真的可以吗?
谢谢:)
这似乎是 FlexboxLayoutManager 的错误。我试过
parent.addView(v);
但这产生了非常奇怪的崩溃。
事实证明,虽然 FlexboxLayoutManager 在 onBindViewHolder
之前可能不会附加 LayoutParams,但它会在 onViewAttachedToWindow
之前附加 LayoutParams。所以你可以像这样设置 LayoutParams:
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);