Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apply offset to GridLayout items and preserve equal size among all items

I want to create a space between items in the grid. The items should all have equal width/height.

What I've tried:

Create a GridLayoutOffsetDecorator that applies an offset to all grid items:

class GridLayoutOffsetDecorator(var offset: Int) : RecyclerView.ItemDecoration() {

    override fun getItemOffsets(
            outRect: Rect,
            view: View,
            parent: RecyclerView,
            state: RecyclerView.State?) {

        super.getItemOffsets(outRect, view, parent, state)

        outRect.set(offset, offset, offset, offset)
    }
}

Having an offset of 8dp creates a 16dp space between the items. So we still have to apply 8dp of padding to the outer edges:

<android.support.v7.widget.RecyclerView
        android:id="@+id/productList"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:clipToPadding="false"
        android:padding="8dp" />

The result is:

enter image description here

Problem: the items are not equal in size:

enter image description here

You notice a slight difference in height when you look at the blue line. This difference appears only after padding the recyclerview. This padding seems to slightly resize some of the items. Do you guys have any experience with this problem? Any idea how this can be solved?


By removing the image from the items, the height difference disappears. This is how the image is set:

<SquareImageView
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="centerCrop"
    app:imageResource="@{product.image}" />

SquareImageView:

class SquareImageView : ImageView {

    constructor(context: Context) : super(context)
    constructor(context: Context, attributeSet: AttributeSet) : super(context, attributeSet)
    constructor(context: Context, attributeSet: AttributeSet, defStyleAttr: Int) : super(context, attributeSet, defStyleAttr)

    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
        super.onMeasure(widthMeasureSpec, widthMeasureSpec)
    }
}

So the problem may be caused by the image itself.

like image 222
UpCat Avatar asked Apr 25 '17 13:04

UpCat


2 Answers

I had the same problem when working with GridLayoutManager. Solved it by setting width and height for image in adapter. Here's my solution, hope it help.

That's how I placed ImageView in my layout.

<LinearLayout
     android:id="@+id/layoutImageProduct"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
     android:gravity="center"
     tools:minHeight="100dp"
     tools:minWidth="150dp">

       <ImageView
           android:id="@+id/imageProduct"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:scaleType="fitCenter"
           android:src="@drawable/placeholder_product"/>
</LinearLayout>

And then apply LayoutParams on parent layout and ImageView

//Setting View width/height
LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) holder.layoutImageProduct.getLayoutParams();
params.width = (int) ResourcesUtils.getColumnWidth(context);
params.height = ((int) (ResourcesUtils.getColumnWidth(context)));
holder.layoutImageProduct.setLayoutParams(params);

params = (LinearLayout.LayoutParams) holder.imageProduct.getLayoutParams();
params.width = (int) ResourcesUtils.getColumnWidth(context);
params.height = (int) ResourcesUtils.getColumnWidth(context);
holder.imageProduct.setLayoutParams(params);

Here's the getWidth method.

public static float getColumnWidth(Context context) {
        if (GRID_COLUMN_WIDTH == -1) {
            int screenWidth = getDisplayMetrics(context).widthPixels;
            float horizontalPadding = getDimensInPixel(context, R.dimen.activity_horizontal_margin);
            // NUM OF COLUMN = 2
            GRID_COLUMN_WIDTH = screenWidth / 2 - horizontalPadding * 2;
        }

        return GRID_COLUMN_WIDTH;
    }

See the screenshot, one with placeholder and one with image. One with placeholder and one with image.

like image 76
Noman Rafique Avatar answered Oct 13 '22 01:10

Noman Rafique


Can you please try with imageview height as fixed.

like image 31
Sunisha Sindhu Avatar answered Oct 13 '22 00:10

Sunisha Sindhu