CardView layout_width="match_parent" does not match parent RecyclerView width
AndroidAndroid LayoutAndroid 5.0-LollipopAndroid RecyclerviewAndroid CardviewAndroid Problem Overview
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:
Note that this was run on emulator, not a real device.
Am I doing something wrong, or is it a bug?
Android Solutions
Solution 1 - Android
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 - Android
Use RelativeLayout as the immediate parent to CardView.
<RelativeLayout
android:layout_width="match_parent" ... >
<CardView
android:layout_width="match_parent" ... >
</CardView>
</RelativeLayout>
Solution 3 - Android
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 - Android
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 - Android
This appears to be fixed in 'com.android.support:recyclerview-v7:23.2.1'
See: https://stackoverflow.com/questions/28867709/recyclerview-wrap-content for further discussions.
Solution 6 - Android
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);
}
Solution 7 - Android
Simply set new layout params
view.setLayoutParams(new RecyclerView.LayoutParams(
RecyclerView.LayoutParams.MATCH_PARENT,
RecyclerView.LayoutParams.WRAP_CONTENT
));
Solution 8 - Android
This works for me
View view = inflator.inflate(R.layout.layout_item, ***null***, false);
Solution 9 - Android
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
Solution 10 - Android
Wrap CardView
in a Layout that has width:match_parent