ProgrAmmar
ProgrAmmar

Reputation: 3095

CardView layout_width="match_parent" does not match parent RecyclerView width

I have a fragment with contains a RecyclerView with 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" />

The item in the RecyclerView is a CardView also with 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>

I inflate the item view as below:

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

But when I run the app, the CardView is rendered as wrap_content as shown below:

CardsBug

Note that this was run on emulator, not a real device.

Am I doing something wrong, or is it a bug?

Upvotes: 134

Views: 67919

Answers (10)

issamux
issamux

Reputation: 1415

Default implementation force the use of wrap_content in the default layout manager :

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

All you have to do is to override this method in your LayoutManager like this :

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

Upvotes: 4

Ganesh Kanna
Ganesh Kanna

Reputation: 2275

Use RelativeLayout as the immediate parent to CardView.

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

Upvotes: 78

Vlad
Vlad

Reputation: 8572

Simply set new layout params

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

Upvotes: 4

anurag_dake
anurag_dake

Reputation: 1148

This worked for me,

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

Upvotes: 14

Vladimir Salguero
Vladimir Salguero

Reputation: 5947

Use card_view:contentPadding with a negative value

<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">

It worked for me

Upvotes: 1

Samuel Moshie
Samuel Moshie

Reputation: 570

Wrap CardView in a Layout that has width:match_parent

Upvotes: -1

DiRiNoiD
DiRiNoiD

Reputation: 1361

This works for me

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

Upvotes: 2

speedynomads
speedynomads

Reputation: 2682

This appears to be fixed in 'com.android.support:recyclerview-v7:23.2.1'

See: RecyclerView wrap_content for further discussions.

Upvotes: 5

Rahul
Rahul

Reputation: 749

The way I did it is:

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

Explanation: In your onCreateViewHolde once you get card view, get the screen width and then set the layout param accordingly for card view.

Upvotes: 6

nhaarman
nhaarman

Reputation: 100468

The docs for inflate:

Inflate a new view hierarchy from the specified xml resource. Throws InflateException if there is an error.

Parameters
resource ID for an XML layout resource to load (e.g., R.layout.main_page) root
view to be the parent of the generated hierarchy (if attachToRoot is true), or else simply an object that provides a set of LayoutParams values for root of the returned hierarchy (if attachToRoot is false.)
attachToRoot Whether the inflated hierarchy should be attached to the root parameter? If false, root is only used to create the correct subclass of LayoutParams for the root view in the XML. Returns The root View of the inflated hierarchy. If root was supplied and attachToRoot is true, this is root; otherwise it is the root of the inflated XML file.

It is important here to not supply true, but do supply the parent:

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

Supplying the parent View lets the inflater know what layoutparams to use. Supplying the false parameter tells it to not attach it to the parent just yet. That is what the RecyclerView will do for you.

Upvotes: 306

Related Questions