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


123

我有一个片段,其中包含一个带有layout_width =“ match_parent”的RecyclerView:

<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    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_width =“ match_parent”:

<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_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp"
    card_view:cardCornerRadius="4dp">

    <TextView
        android:layout_gravity="center"
        android:id="@+id/info_text"
        android:layout_width="match_parent"
        android:gravity="center"
        android:layout_height="match_parent"
        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参数?
nhaarman

@NiekHaarman,您好,请参阅编辑。我添加了膨胀代码。是的,我已经传递了true参数。
ProgrAmmar 2014年

Answers:


291

的文档inflate

从指定的xml资源中添加新的视图层次结构。如果有错误,则抛出InflateException。

XML布局资源的参数
资源 ID,以加载(例如R.layout.main_page)根
视图作为生成的层次结构的父级(如果attachToRoot为true),或者仅仅是一个为根提供一组LayoutParams值的对象返回层次结构的值(如果attachToRoot为false。)
attachToRoot 是否应将膨胀的层次结构附加到根参数?如果为false,则root仅用于为XML中的根视图创建LayoutParams的正确子类。返回膨胀后的层次结构的根视图。如果提供了root且attachToRoot为true,则为root。否则,它是膨胀的XML文件的根。

到这里重要的不是提供真实的,但提供父:

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

提供parentView可使充气机知道要使用哪些layoutparams。提供false参数会告诉它暂时不将其附加到父级。那就是RecyclerView遗嘱对您的作用。


4
该解决方案对我不起作用,因为ListView layout_widthwrap_content。这很奇怪,因为这不会影响列表视图!所以我的理解是,当您向layoutinflater提供false作为参数时,ListView会将列表项添加到具有与ListView本身匹配的布局参数的ListView!:0
reubenjohn

1
您能再发布一些代码吗,因为我想我也在做同样的事情,但实际上却行不通
Rodi 2015年

1
我夸大了您的建议,而match_parent对我不起作用。
Zapnologica 2015年

3
我认为正确的理解是,当将attachToRoot设置为false时,需要提供一个具有定义的LayoutParams值的对象。该对象不一定是父对象。“ ...只是为返回的层次结构的根提供了一组LayoutParams值的对象(如果attachToRoot为false。)...”但是我不明白为什么充气机无法读取CardView中定义的LayoutParams,但是需要另一个对象参数通知它?
hjchin '16

1
如果我使用自定义视图,该如何处理?我的意思是ViewHolder onCreateViewHolder(...) { View v = new MyItemView(parent.getContext); return new ViewHolder(v); }
克罗斯(Kross)

64

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

<RelativeLayout 
    android:layout_width="match_parent" ... >
    <CardView 
        android:layout_width="match_parent" ... >
    </CardView>
</RelativeLayout>

是的,这似乎也对我有用。我使用的是LinearLayout,并且上面的建议没有用,因为我已经完全这样做了(即不附加到root,而是提供一个父对象)。您必须同时执行RelativeLayout +不附加父项,而是提供一个。
chubbsondubs's

1
它对我有用,但是我不知道为什么这样做可以解决问题。有谁能解释为什么?
约翰尼

1
已经有很长一段时间了,android x已投入生产,但该错误尚未修复!
穆罕默德·纳德里

最简单的方法。
Abdurahman Popal,

我有一个类似的问题,对我来说,这可以更正我的卡片视图的宽度,但高度却有类似的问题?您还能为此建议我吗?

12

这对我有用

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

6

我这样做的方式是:

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中获取屏幕宽度,然后相应地为卡片视图设置布局参数。


1
请稍微改善一下。它基本上说“试试看”
Drew

添加了解释。请检查,如果需要其他帮助,请在此处评论。
拉胡尔2015年


4

只需设置新的布局参数

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

当使用从ConstraintLayout继承的自定义视图类时,我发现在onBindViewHolder()中执行此操作很有用。
Rasmusob

这不是一个好的答案,因为设置到版面的边距将受到影响。
Emi Raz

4

默认实现强制在默认布局管理器中使用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);
}

2

这对我有用

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

1

使用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_width="match_parent"
    card_view:contentPadding="-4dp"
    card_view:cardElevation="0dp"
    android:layout_height="wrap_content">

对我有用


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.