Ali Sherafat
Ali Sherafat

Reputation: 3855

center items horizontally in RecyclerView(using GridLayoutManager)

I'm trying to center all my items horizontally for each row in RecyclerView

I tried many things: RelativeLayout as a parent, then use layout_centerInParent, use the basic android:layout_gravity="center", try to add some space element,using weights and .... in item_row.xml
but I didn't succeed :(

What i have

a busy cat

What i want

a busy cat

In activity

recyclerView.setLayoutManager(new GridLayoutManager(this, 3));

item_row.xml

<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/cardView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
card_view:cardCornerRadius="2dp"
card_view:cardElevation="4dp"
card_view:cardUseCompatPadding="true">

<!--   Recycler View Item Row   -->
<LinearLayout
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:orientation="vertical">


    <ImageView
        android:id="@+id/imgThumbnail"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:adjustViewBounds="true"
        android:background="@android:color/black" />

    <LinearLayout
        android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">


        <TextView
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:textAppearance="?android:attr/textAppearanceMedium"
            android:text="item name"
            android:id="@+id/txtName"
            android:layout_margin="5dp"
            android:singleLine="false"
            android:lines="2"
            android:gravity="center" />

        <LinearLayout
            android:orientation="horizontal"
            android:layout_width="match_parent"
            android:layout_height="match_parent">

            <TextView
                android:layout_width="0dp"
                android:layout_height="match_parent"
                android:textAppearance="?android:attr/textAppearanceSmall"
                android:id="@+id/txtCategory"
                android:textStyle="italic"
                android:textColor="#496fa9"
                android:text="subtitle"
                android:layout_weight="1"
                android:gravity="center_vertical"
                android:paddingLeft="10dp"
                android:layout_gravity="center" />

            <ImageButton
                android:id="@+id/imageButton"
                android:layout_width="48dp"
                android:layout_height="wrap_content"
                android:background="@android:color/black"
                android:adjustViewBounds="true"
                android:scaleType="fitCenter"
                android:padding="8dp"/>

        </LinearLayout>

    </LinearLayout>

</LinearLayout>

</android.support.v7.widget.CardView>

i googled a lot and found this answer but actually i don't know how to create a LinearLayout for each row of items!

Upvotes: 21

Views: 13128

Answers (4)

    GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 6);
    final int totalSize = customList.size();

    layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {
            int rows = Math.round((totalSize / 3f) + 0.4f);
            int itemInRow = Math.round(((position + 1) / 3f) + 0.4f);
            if (rows == 1 || rows == itemInRow) {
                int span = totalSize % 3;
                if (span == 0) {
                    return 2;
                }
                return 6 / span;
            }
            return 2;
        }
    });

Upvotes: 0

Seyyed AMir
Seyyed AMir

Reputation: 31

GridLayoutManager layoutManager = new GridLayoutManager(getContext(), 6);
final int totalSize = customList.size();

layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
        int extra;
        extra = totalSize % 3;

        if(extra == 0)
            return 2;

        if (totalSize - (position + 1) < extra) {
            return (int) 6 / extra;
        }

        return 2;
    }
});

recycler.setLayoutManager(layoutManager);

Upvotes: 0

Rahul Devanavar
Rahul Devanavar

Reputation: 4165

Use the gridLayoutManager = new GridLayoutManager(context,6) and override setSpanSizeLookup.

Example:

int totalSize=list.size();
gridLayoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
                    @Override
                    public int getSpanSize(int position) {
                        int span;
                        span = totalSize % 3;
                        if (totalSize < 3) {
                            return 6;
                        } else if (span == 0 || (position <= ((totalSize - 1) - span))) {
                            return 2;
                        } else if (span == 1) {
                            return 6;
                        } else {
                            return 3;
                        }
                    }
                });

This will work if you want to display 3 items in a row and remaining in the center of the grid.

Change the grid layout manager span counts accordingly your requirement.

Upvotes: 3

Budius
Budius

Reputation: 39836

you can use a SpanSizeLookup to make views/items with different widths for your grid view. So with that you can do some cleverness with empty views to adjust accordingly. Might be more complicate or simpler depending on how variable your layout actually is.

reference: https://developer.android.com/reference/android/support/v7/widget/GridLayoutManager.SpanSizeLookup.html

for this specific case you show on your drawing you would do something like:

GridLayoutManager lm = new GridLayoutManager(context, 6);
lm.setSpanSizeLookup(new MySizeLookup());

public static class MySizeLookup extends SpanSizeLookup {

   public int getSpanSize(int position) {
      if(position >= 0 && position <= 2) {
          return 2;
      } else if (position == 3 || position == 6) {
          return 1;
      } else {
          return 2;
      }
   }
}

and with that you'll have to make on your adapter, the position 3 and 6 to be an empty/invisible element. Something like new View(context); just to occupy that extra space

Upvotes: 4

Related Questions