How to set different columns for rows in android gridview

I have something similar and i solved with the new RecyclerView.

I created a Fragment with an a RecyclerView. RecyclerView on xml:

<android.support.v7.widget.RecyclerView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/filter_subtypes" android:layout_width="match_parent" android:layout_height="match_parent" />

On your Fragment/Activity (OnViewCreated in my fragment case). I find the RecyclerView and set an Adapter- a normal Adapter class inherit from RecyclerView.Adapter< YOUR VIEW HOLDER class >- And then i create a GridLayoutManager

final GridLayoutManager mng_layout = new GridLayoutManager(this.getActivity(), TOTAL_CELLS_PER_ROW/*In your case 4*/);


Then i override this method to set a dynamic numbers of columns (cells)

mng_layout.setSpanSizeLookup( new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                switch( adapterSubtype.getItemViewType(position) ) {
                    case FilterSubtypesAdapter.TYPE_LOW:
                        return TOTAL_CELLS_PER_ROW;
                    case FilterSubtypesAdapter.TYPE_HIGH:
                        return 2;
                    default:
                        return -1;
                }
            }
        });
myRecyclerView.setLayoutManager(mng_layout);

With this you will get dynamic numbers of cell on your rows.

EXTRA: Then if you are using the same view/type view on your adapter, you will get the same w & h view. You will need to create 2 xml views for TYPE_HIGH and other view for TYPE_LOW.

So, in your adapter, you need to have 2 kind of data (1 for high images and 1 for low images). You must override this methods

@Override
public SubtypeViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View view = null;
    if (viewType==TYPE_HIGH) {
        view = inflater.inflate(R.layout.item_image_high, parent, false);
    } else {
        view = inflater.inflate(R.layout.item_image_low, parent, false);
    }
    return new SubtypeViewHolder(view, viewType);
}

 @Override
 public int getItemViewType(int position) {
     return (list.get(position).getType()==Subtype_type.HIGH) ? TYPE_HIGH : TYPE_LOW;
 }

I hope i was clear, any problem tell me.


Instead of considering a single image views i am taking group of three images as a single grid item,

enter image description here

try this inside your grid adapter

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/linear"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/green"
    android:orientation="vertical">
<ImageView
    android:id="@+id/image"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:scaleType="fitXY"
    android:src="@drawable/user"
     />
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <ImageView
            android:id="@+id/image_1"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:scaleType="fitXY"
            android:src="@drawable/user"

            />
        <ImageView
            android:id="@+id/image_2"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:src="@drawable/user"
            android:scaleType="fitXY"
            android:layout_weight="1"
            />

        </LinearLayout>

    </LinearLayout>

and your grid view would be like

<GridView xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/RelativeLayout1"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:numColumns="2"
    >

</GridView>

The only thing you have to take care of is, the sequence of your image. might be this will help you


If you are using RecyclerView for GridView, then there is solution that should work for you:

GridLayoutManager layoutManager = new GridLayoutManager(this, 4);
layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
    @Override
    public int getSpanSize(int position) {
         int mod = position % 6;    

         if(position == 0 || position == 1)
              return 2;
         else if(position < 6)
              return 1;
         else if(mod == 0 || mod == 1)
              return 2;
         else
              return 1;
    }
});

recyclerView.setLayoutManager(layoutManager);

Hope this work for you!