Reputation: 852
I'm using RecyclerView and I'm trying to make the width item of RecyclerView match_parent since I'm using
LinearLayoutManager.HORIZONTAL
<android.support.v7.widget.RecyclerView
android:id="@+id/listOffersHits"
android:layout_width="match_parent"
android:layout_height="match_parent" />
custom_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<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_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_weight="1"
android:layout_margin="2dp"
card_view:cardCornerRadius="2dp">
<ImageView
android:id="@+id/offerImage"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/item_selector"
android:scaleType="fitXY"
android:src="@drawable/offer"
/>
</android.support.v7.widget.CardView>
LayoutManager
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(getActivity(),LinearLayoutManager.HORIZONTAL, false);
listOffersHits.setLayoutManager(linearLayoutManager);
ViewHolder
View view= LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_layout, parent, false);
ViewOffersHolder viewHolder=new ViewOffersHolder(view);
return viewHolder;
Upvotes: 10
Views: 23925
Reputation: 436
Calling to GridLayoutManager instead of LinearLayoutManager and put one column is most simple
From your xml:
<androidx.recyclerview.widget.RecyclerView
app:layoutManager="androidx.recyclerview.widget.GridLayoutManager"
app:spanCount="1"
...
Or from Kotlin:
recyclerView.layoutManager = GridLayoutManager(this,1)
Or from Java:
recyclerView.setLayoutManager(new GridLayoutManager (this, 1);
Upvotes: 1
Reputation: 278
Note: See update at the very end of this post.
Old Answer:
The following worked for me:
view.getLayoutParams ().width = parentViewGroup.getWidth ();
, right after inflating the view 'view' .
It basically takes the width of the parent and replaces the new view's layout_width with the parent's width.
You can also add a check for MATCH_PARENT, to make sure it appears correctly in case you modify the XML to a different width in the future. So like this:
public ViewHolder onCreateViewHolder (ViewGroup parent, int type) {
View vItem = LayoutInflater.from (parent.getContext ())
.inflate (R.layout.bookmark_card, parent, false);
if (vItem.getLayoutParams ().width == RecyclerView.LayoutParams.MATCH_PARENT)
vItem.getLayoutParams ().width = parent.getWidth ();
return new ViewHolder (vItem);
}
It will only make it the parent width if the width was MATCH_PARENT before this.
EDIT:
Do be careful about excessive use of this fix, as a variation of it has caused me a layout bug. I did this:
public ViewHolder onCreateViewHolder (ViewGroup parent, int type) {
View vItem = LayoutInflater.from (parent.getContext ())
.inflate (R.layout.page_tile, parent, false);
if (vItem.getLayoutParams ().width == RecyclerView.LayoutParams.MATCH_PARENT)
vItem.getLayoutParams ().width = parent.getWidth ();
if (vItem.getLayoutParams ().height == RecyclerView.LayoutParams.MATCH_PARENT)
vItem.getLayoutParams ().height = parent.getHeight ();
return new ViewHolder (vItem);
}
That worked, but it did not update the width and height when the RecyclerView was resized. Therefore, one of two fixes to this fix can be applied:
The following fix seems to work:
public ViewHolder onCreateViewHolder (ViewGroup parent, int type) {
View vItem = LayoutInflater.from (parent.getContext ())
.inflate (R.layout.page_tile, parent, false);
ViewHolder holder = new ViewHolder (vItem); // Create view holder.
holder.vItem = vItem; // Save top-level View.
holder.vParent = parent; // Save its parent.
ViewGroup.LayoutParams lp = vItem.getLayoutParams ();
if (lp != null) { // Save the original width and height from lp:
holder.originalWidth = lp.width;
holder.originalHeight = lp.height;
refreshLayoutParams (holder); // Check for MATCH_PARENT.
} else holder.originalHeight = holder.originalWidth = 0;
return holder;
}
public void onBindViewHolder (ViewHolder holder, int position) {
... do work here ...
refreshLayoutParams (holder); // Check AGAIN for MATCH_PARENT.
}
private void refreshLayoutParams (ViewHolder holder) {
ViewGroup.LayoutParams lp = holder.vItem.getLayoutParams ();
View parent = holder.vParent;
if (parent == null) return; // Is there a parent to check against?
if (lp == null)
holder.vItem.setLayoutParams (lp =
new RecyclerView.LayoutParams (holder.originalWidth, holder.originalHeight));
if (holder.originalWidth == RecyclerView.LayoutParams.MATCH_PARENT)
lp.width = parent.getWidth (); // Check width.
if (holder.originalHeight == RecyclerView.LayoutParams.MATCH_PARENT)
lp.height = parent.getHeight (); // Check height.
}
Note Also: If you use this approach of resizing inside the onBindViewHolder () method, you will also need to getAdapter ().notifyDataSetChanged () inside the Activity.onSizeChanged ()!
In short, the main idea is: check for MATCH_PARENT on every bind, not just on create view holder. This way resizing the RecyclerView works too.
UPDATE: As of RecyclerView v7:23.2.1 at least, it seems they have fixed it so that now these custom fixes are no longer necessary. RecyclerView itself should now recognize both WRAP_CONTENT and MATCH_PARENT settings.
Upvotes: 8
Reputation: 852
I fixed the problem:
1- Get the screen size (width).
2- make the ViewHolder width same as screen size.
Below my code if any one need it.
WindowManager windowManager = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
int width = windowManager.getDefaultDisplay().getWidth();
int height = windowManager.getDefaultDisplay().getHeight();
view.setLayoutParams(new RecyclerView.LayoutParams(width, RecyclerView.LayoutParams.MATCH_PARENT));
Upvotes: 18
Reputation: 1170
Remove this in the layout.
android:layout_weight="1"
And set layout params for item in adapter once again.
View view= LayoutInflater.from(parent.getContext())
.inflate(R.layout.custom_layout, parent, false);
view.setLayoutParams(new RecyclerView.LayoutParams(RecyclerView.LayoutParams.MATCH_PARENT, RecyclerView.LayoutParams.MATCH_PARENT));
ViewOffersHolder viewHolder=new ViewOffersHolder(view);
return viewHolder;
Upvotes: 4