CardView layout_width = "match_parent" не соответствует родительской ширине RecyclerView

У меня есть фрагмент с содержит RecyclerView с layout_width = "match_parent":

<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, как показано ниже:

CardsBug

Обратите внимание, что это было запущено на эмуляторе, а не на реальном устройстве.

Я делаю что-то не так, или это ошибка?

Ответ 1

Документы для inflate:

Наполните новую иерархию представлений из указанного ресурса xml. Броски InflateException, если есть ошибка.

Параметры
ресурс для ресурса компоновки XML для загрузки (например, R.layout.main_page) root
view, чтобы быть родителем (если attachToRoot истинно), либо просто объект, который предоставляет набор значений LayoutParams для корня из возвращенная иерархия (если attachToRoot - false.)
attachToRootзавышенная иерархия должна быть присоединена к корневому параметру? Если false, root используется только для создания правильного подкласса LayoutParams для представления корня в XML. Возвращает Корневой вид завышенная иерархия. Если root был поставлен и attachToRoot имеет значение true, это корень; в противном случае это корень завышенного XML файла.

Здесь важно не поставлять true, но снабжать родителя:

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

Поставка представления parent позволяет надувателю узнать, какие шаблоны использовать. Поставка параметра false указывает, что он еще не привязал его к родительскому элементу. Это то, что сделает RecyclerView для вас.

Ответ 2

Используйте RelativeLayout в качестве непосредственного родителя для CardView.

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

Ответ 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
));

Ответ 7

Это работает для меня

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

Ответ 8

Реализация по умолчанию вынуждает использовать 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);
}

Ответ 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_width="match_parent"
    card_view:contentPadding="-4dp"
    card_view:cardElevation="0dp"
    android:layout_height="wrap_content">

Это сработало для меня

Ответ 10

Оберните CardView в макете с шириной: match_parent