CardView layout_width="match_parent" 与父 RecyclerView 宽度不匹配

Posted

技术标签:

【中文标题】CardView layout_width="match_parent" 与父 RecyclerView 宽度不匹配【英文标题】:CardView layout_width="match_parent" does not match parent RecyclerView width 【发布时间】:2014-08-21 15:06:24 【问题描述】:

我有一个片段,其中包含一个 RecyclerView,layout_:

<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_
    android:layout_
    android:layout_gravity="center"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin"
    tools:context=".MainActivity$PlaceholderFragment" />

RecyclerView 中的项目也是 CardView,layout_:

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:id="@+id/card_view"
    android:layout_gravity="center"
    android:layout_
    android:layout_
    android:layout_margin="20dp"
    card_view:cardCornerRadius="4dp">

    <TextView
        android:layout_gravity="center"
        android:id="@+id/info_text"
        android:layout_
        android:gravity="center"
        android:layout_
        android:textAppearance="?android:textAppearanceLarge"/>
</android.support.v7.widget.CardView>

我将项目视图放大如下:

public MyAdapter.ViewHolder onCreateViewHolder(ViewGroup parent,
                                                   int viewType) 
        CardView v = (CardView) LayoutInflater.from(parent.getContext())
                .inflate(R.layout.card_listitem, null, true);

        ViewHolder vh = new ViewHolder(v);
        return vh;
    

但是当我运行应用程序时,CardView 呈现为 wrap_content 如下所示:

请注意,这是在模拟器上运行的,而不是真实设备。

是我做错了什么,还是一个错误?

【问题讨论】:

膨胀 CardView 时,是否为父视图提供了 true 参数? 嗨@NiekHaarman,请查看编辑。我添加了膨胀代码。是的,我已经传递了真正的参数。 【参考方案1】:

inflate 的文档:

从指定的 xml 资源扩充新的视图层次结构。投掷 InflateException 如果有错误。

Parametersresource 要加载的 XML 布局资源的 ID(例如, R.layout.main_page) 根view 成为 生成的层次结构(如果 attachToRoot 为真),或者只是一个 提供一组 LayoutParams 值的对象 返回的层次结构(如果 attachToRoot 为 false。)attachToRoot 是否 膨胀的层次结构应该附加到根参数吗?如果 false,root 仅用于创建正确的子类 XML 中根视图的 LayoutParams。返回根视图 膨胀的等级制度。如果提供了 root 并且 attachToRoot 为真, 这是根;否则它是膨胀的 XML 文件的根。

这里重要的是提供true,但提供父:

LayoutInflater.from(parent.getContext())
            .inflate(R.layout.card_listitem, parent, false);

提供parent 视图可以让inflater 知道要使用什么布局参数。提供false 参数告诉它 将它附加到父级。这就是RecyclerView 将为您做的事情。

【讨论】:

该解决方案对我不起作用,因为 ListView 的 layout_widthwrap_content。这很奇怪,因为这不应该影响列表视图!所以我的理解是,当您向 layoutinflater 提供 false 作为参数时,ListView 会将列表项添加到 ListView 中,其布局参数与 ListView 本身匹配! :0 你能不能多贴一点代码,因为我想我也在做同样的事情,但实际上它不起作用 我夸大了你的建议,而 match_parent 对我不起作用。 我认为正确的理解是当你将attachToRoot设置为false时,你需要提供一个定义了LayoutParams值的对象。该对象不一定是父对象。 “......只是一个对象,它为返回的层次结构的根提供一组 LayoutParams 值(如果 attachToRoot 为假。)......”但我不明白为什么 inflater 无法读取 CardView 中定义但需要的 LayoutParams另一个对象参数通知它? 如果我使用自定义视图,如何处理?我的意思是ViewHolder onCreateViewHolder(...) View v = new MyItemView(parent.getContext); return new ViewHolder(v); 【参考方案2】:

使用 RelativeLayout 作为 CardView 的直接父级。

<RelativeLayout 
    android:layout_ ... >
    <CardView 
        android:layout_ ... >
    </CardView>
</RelativeLayout>

【讨论】:

是的,这似乎也对我有用。我正在使用 LinearLayout 并且上面的建议不起作用,因为我已经在这样做了(即不附加到根,但提供父级)。您必须同时执行 RelativeLayout + 不附加父级,但提供一个。 它对我有用,但我不知道为什么这样做可以解决问题。谁能解释一下原因? 好久不见,android x 正在生产中,bug 还没有修复! 最简单的方法。 我遇到了类似的问题,这对我来说可以纠正我的卡片视图的宽度,但我在高度方面遇到了类似的问题?你能不能也给我一些建议?【参考方案3】:

这对我有用,

 View viewHolder= LayoutInflater.from(parent.getContext())
            .inflate(R.layout.item, null, false);
 viewHolder.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.WRAP_CONTENT));
 return new ViewOffersHolder(viewHolder);

【讨论】:

【参考方案4】:

我的做法是:

View view = mInflater.inflate(R.layout.row_cardview, null, true);
            WindowManager windowManager = (WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE);
            int width = windowManager.getDefaultDisplay().getWidth();
            view.setLayoutParams(new RecyclerView.LayoutParams(width, RecyclerView.LayoutParams.MATCH_PARENT));

解释: 获得卡片视图后,在 onCreateViewHolde 中获取屏幕宽度,然后为卡片视图设置相应的布局参数。

【讨论】:

请稍微改进一下。它基本上说“试试这个” 添加说明。请检查,如果需要任何进一步的帮助,请在此处发表评论。【参考方案5】:

这似乎已在'com.android.support:recyclerview-v7:23.2.1' 中修复

更多讨论请参见:RecyclerView wrap_content。

【讨论】:

【参考方案6】:

只需设置新的布局参数

view.setLayoutParams(new RecyclerView.LayoutParams(
    RecyclerView.LayoutParams.MATCH_PARENT,
    RecyclerView.LayoutParams.WRAP_CONTENT
));

【讨论】:

我发现在使用继承自 ConstraintLayout 的自定义视图类时,在 onBindViewHolder() 中执行此操作很有用。 这不是一个好的答案,因为布局设置的边距会受到影响。【参考方案7】:

默认实现强制在默认布局管理器中使用 wrap_content

  @Override
public LayoutParams generateDefaultLayoutParams() 
    return new LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
            ViewGroup.LayoutParams.WRAP_CONTENT);

您所要做的就是在您的 LayoutManager 中重写此方法,如下所示:

  @Override
public LayoutParams generateDefaultLayoutParams() 
    return new LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
            ViewGroup.LayoutParams.WRAP_CONTENT);

【讨论】:

【参考方案8】:

这对我有用

View view = inflator.inflate(R.layout.layout_item, ***null***, false);

【讨论】:

【参考方案9】:

使用负值的card_view:contentPadding

<android.support.v7.widget.CardView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:card_view="http://schemas.android.com/apk/res-auto"
    android:layout_
    card_view:contentPadding="-4dp"
    card_view:cardElevation="0dp"
    android:layout_>

它对我有用

【讨论】:

【参考方案10】:

CardView 包裹在一个具有宽度的布局中:match_parent

【讨论】:

以上是关于CardView layout_width="match_parent" 与父 RecyclerView 宽度不匹配的主要内容,如果未能解决你的问题,请参考以下文章

CardView

CardView

RecyclerView和CardView

使ImageView适合CardView的宽度

RecyclerView 结合 CardView 使用

在ConstraintLayout中为CardView设置约束参数