GridView with two columns, first item spans both columns
Asked Answered
G

1

34

I have one Imageview & one gridview..

My layout design here..

enter image description here

I want to combine these two views into single gridview

my question:

How to set gridview first item spans in both columns?

Gay answered 27/6, 2015 at 18:44 Comment(1)
I added an answer. I would like to suggest that you change the title and content of your question, just so that other people who are searching for this solution can find it. Perhaps something like: "GridView with two columns, first item spans both columns".Shorthanded
S
72

In researching your question, I learned something new: I happened to look at GridLayoutManager for RecyclerView and I noticed that you can set a custom SpanSizeLookup. Now a "span" is just a column if you're scrolling vertically and a row if you're scrolling horizontally. So the SpanSizeLookup allows you to specify for example, item 0 takes 2 columns, item 1 takes 1 column, etc.

It turns out that if you use RecyclerView with a GridLayoutManager the solution is easy-peasy:

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Create a grid layout with two columns
        GridLayoutManager layoutManager = new GridLayoutManager(this, 2);

        // Create a custom SpanSizeLookup where the first item spans both columns
        layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
            @Override
            public int getSpanSize(int position) {
                return position == 0 ? 2 : 1;
            }
        });

        RecyclerView recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
        recyclerView.setLayoutManager(layoutManager);
        recyclerView.setAdapter(new MyGridAdapter());
    }

I created a test project just to try it out and make sure it did what I expected it to, and it worked like a charm.


A note about the adapter: RecyclerView.Adapter is not compatible with ListAdapter. You need to extend your adapter from RecyclerView.Adapter and make the appropriate changes.

Here is the adapter I created for my test project:

    public static class MyViewHolder extends RecyclerView.ViewHolder {

        ImageView mImageView;
        TextView mTextView;

        public MyViewHolder(View itemView) {
            super(itemView);
            mImageView = (ImageView) itemView.findViewById(R.id.imageView);
            mTextView = (TextView) itemView.findViewById(R.id.textView);
        }
    }

    public static class MyGridAdapter extends RecyclerView.Adapter<MyViewHolder> {

        private int[] mDrawables;

        public MyGridAdapter() {
            this.mDrawables = new int[] {
                    R.drawable.images_01,
                    R.drawable.images_02,
                    .
                    .
                    .
            };
        }

        @Override
        public int getItemCount() {
            return mDrawables.length;
        }

        @Override
        public MyViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

            LayoutInflater inflater = (LayoutInflater) parent.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            View view = inflater.inflate(R.layout.layout_grid_item, parent, false);
            MyViewHolder holder = new MyViewHolder(view);
            // set up any onClickListener you need on the view here
            return holder;
        }

        @Override
        public void onBindViewHolder(MyViewHolder holder, int position) {

            holder.mImageView.setImageResource(mDrawables[position]);
            holder.mTextView.setText("Image " + position);
        }
    }

First, create a RecyclerView.ViewHolder subclass. The view holder pattern is now an integral part of this new way of doing adapter views. Your ViewHolder will set up all the child views for your view.

Then in your RecyclerView.Adapter subclass, override onCreateViewHolder() and onBindViewHolder(). In onCreateViewHolder() you inflate your view and construct the ViewHolder. In onBindViewHolder(), you use position to get the adapter data and set up the child views using the ViewHolder. So RecyclerView technically recycles ViewHolders that contain Views.

Once you make those changes to your adapter, you should be all set.

Shorthanded answered 28/6, 2015 at 3:12 Comment(5)
I replace my imageview & gridview with recyclerview.after apply the your code.. I got error in recyclerView.setAdapter(adapter);Gay
Sadly, RecyclerView.Adapter is not compatible with ListAdapter, so you will have to rearrange your adapter a little bit. I will update my answer to add something about that.Shorthanded
Thanks man..It works amazing..can you share how to you find solution? because I search more than 10 days for this problem.lot of googling not provide answer..Gay
Don't know exactly. After doing this stuff for so many years, I think there's an instinct. I just started looking through docs for GridView and RecyclerView.GridLayoutManager, then I saw SpanSizeLookup and something clicked. But I had to do a test project just to make sure my hunch was right.Shorthanded
only works for horizontal layout? how to implement for vertical layout (I mean to combine rows)Winze

© 2022 - 2024 — McMap. All rights reserved.