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

64,872

Solution 1

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.

Solution 2

Use RelativeLayout as the immediate parent to CardView.

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

Solution 3

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

Solution 4

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.

Solution 5

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

See: RecyclerView wrap_content for further discussions.

Share:
64,872
ProgrAmmar
Author by

ProgrAmmar

A software engineer.

Updated on July 23, 2022

Comments

  • ProgrAmmar
    ProgrAmmar almost 2 years

    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?

  • joeschmidt45
    joeschmidt45 about 9 years
    Could you explain why supplying true would cause it to be wrap_content in the first place?
  • reubenjohn
    reubenjohn almost 9 years
    The solution didn't work for me because the ListView's layout_width was wrap_content. Its weird because this shouldn't affect the list view! So my understanding is that when you provide false as a parameter to the layoutinflater, the ListView adds the list items to the ListView with layout parameters matching the ListView itself! :0
  • M4rk
    M4rk over 8 years
    could you post a little more code, because I think I'm doing the same, but actually it isn't working
  • Zapnologica
    Zapnologica over 8 years
    I am inflating how you suggestion and match_parent is not working for me.
  • Drew
    Drew over 8 years
    please improve this slightly. It basically says "Try this"
  • Rahul
    Rahul over 8 years
    Added Explanation. Please check and if need any further help, comment here.
  • chubbsondubs
    chubbsondubs almost 8 years
    Yes this seemed to work for me as well. I was using LinearLayout and the suggestion above didn't work since I was already doing exactly that (ie not attaching to root, but providing a parent). You have to do both RelativeLayout + not attaching parent, but providing one.
  • Johnny
    Johnny almost 8 years
    It works for me, but I don't know why do this can solve the problem. Does anyone can explain why?
  • hjchin
    hjchin over 7 years
    I think the correct understanding is that when you set attachToRoot to false, you need to supply an object with defined LayoutParams value. That object is not necessarily the parent. "...simply an object that provides a set of LayoutParams values for root of the returned hierarchy (if attachToRoot is false.)..." But I don't understand why inflater cannot read the LayoutParams that defined in the CardView but need another object parameter to inform it?
  • krosshj
    krosshj almost 7 years
    If I use custom view, how to deal with it? I mean ViewHolder onCreateViewHolder(...) { View v = new MyItemView(parent.getContext); return new ViewHolder(v); }
  • Rasmusob
    Rasmusob over 6 years
    I found doing this in onBindViewHolder() useful when using a custom view class that inherits from ConstraintLayout.
  • Nikson
    Nikson about 6 years
    @nhaarman can you please help me to solve this issue stackoverflow.com/questions/50066346/…
  • nhaarman
    nhaarman about 6 years
    @Nikson No I cannot.
  • Muhammad Naderi
    Muhammad Naderi about 5 years
    it's been ages, android x is in production, still the bug is not fixed !
  • Abdurahman Popal
    Abdurahman Popal almost 5 years
    the easiest way.
  • Admin
    Admin about 4 years
    I had a similar problem and this worked for me to correct the width of my card view but I am having a similar problem with the height? Can you suggest me something for that as well?
  • Mrunal
    Mrunal about 4 years
    Work like charm
  • Emad Razavi
    Emad Razavi almost 4 years
    It is not a good answer because the margin that is been set to the layout will be affected.