android - RecyclerView getLayoutParams 返回 null(有时)

标签 android android-recyclerview layoutparams

我有一个 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()));
}

似乎用对父级的引用膨胀意味着 getLayoutParams() 永远不会为 null,所以将我的代码更改为

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

现在它可以正常工作,setFlexGrow() 始终处于设置状态。但是,这感觉不对 - 我知道您不打算将 View 显式添加到 RecyclerView 父级。

所以我的问题是:

1 - 为什么 LayoutParams 对于某些项目随机为 null,但对于其他项目却没问题?

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);

关于android - RecyclerView getLayoutParams 返回 null(有时),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45242737/

相关文章:

android - 为什么 9 补丁图形大小在模拟器中正确但在手机上不正确?

android - 设置Android模拟器的IP地址

java - android 上的语言支持

java - 按大小、日期、名称等在回收站 View 中排序并记住选择

android - 如何在Android中顺利展开 View ?

Android 获取换行内容 View 的高度,膨胀为 0dp

java - 使用 StaticClass 使按钮可见并保存

java - 获取recyclerView中选择的id

Android在recyclerview的所有行上显示和隐藏复选框

android - 如果我提交具有不同项目顺序的相同列表,ListAdapter 不会刷新 RecyclerView