Spacing Issue while creating bus layout in recycler view Gridlayout manager
Asked Answered
C

2

18

I'm using recycler view with GirdLayout Manager for creating bus layout. My problem is with spacing, I'm populating data according to row column.

This is how I'm getting layout:

enter image description here

This is how I want my layout to be:

enter image description here

I want the item at row 3 and column 2 beside sleeper seat at row 2 column 0 like shown in the picture above. How can I remove that space, item should accommodate according to its upper item.

customGridAdapter = new CustomGridViewAdapter(getActivity(), busSeatModel, false, fareCategory, BusSeatLayout.this);
                       RtlGridLayoutManager gridLayoutManager = new RtlGridLayoutManager(getActivity(), busSeatModel.getMaxLowerColumn());
                       seatLayout.setLayoutManager(gridLayoutManager);
                       seatLayout.setAdapter(customGridAdapter);

This is my customGridAdapter onBindViewHolder:

public class CustomGridViewAdapter extends RecyclerView.Adapter<CustomGridViewAdapter.MyViewHolder> {

    Context context;
    BusSeatModel busSeatModel;
    HashMap<Integer, HashMap<Integer, BusSeatItemModel>> data = new HashMap<>();
    LayoutInflater inflater;
    boolean upper;
    HashMap<Integer, BusSeatItemModel> seatLowerModels;
    BusSeatItemModel lowerModel;
    int maxColumn = 0;
    int maxRow = 0;
    BusSeatLayout busSeatLayout;
    int fare;

    public CustomGridViewAdapter(Context context, BusSeatModel busSeatModel, boolean upper, int fare, BusSeatLayout busSeatLayout) {
        this.context = context;
        this.busSeatModel = busSeatModel;
        inflater = LayoutInflater.from(context);
        this.fare = fare;
        this.busSeatLayout = busSeatLayout;
        this.upper = upper;
        if (upper) {
            data = busSeatModel.getBusSeatUpperModels();
            maxColumn = busSeatModel.getMaxUpperColumn();
            maxRow = busSeatModel.getMaxUpperRow();
        } else {
            data = busSeatModel.getBusSeatLowerModels();
            maxColumn = busSeatModel.getMaxLowerColumn();
            maxRow = busSeatModel.getMaxLowerRow();
        }
    }


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

        View view = inflater.inflate(R.layout.seatrow_grid, parent, false);

        MyViewHolder myViewHolder = new MyViewHolder(view);

        return myViewHolder;
    }

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

            int row = GetRow(position);
            int column = GetCol(position);

            Log.d(" Row Column  ", "" + row + "  " + column);

            seatLowerModels = new HashMap<>();

            if (data.containsKey(row)) {
                seatLowerModels = data.get(row);
                if (seatLowerModels.containsKey(column)) {
                    lowerModel = seatLowerModels.get(column);
                    Log.v(" same fare ", " model fare " + lowerModel.getBaseFare() + " category selected " + fare);
                    if (fare == -1) {
                        Log.v("  fare  is all ", "++++    ");

                        holder.imageItem.setImageResource(lowerModel.getDrawableName(false));

                    } else {
                        Log.v("  fare  is not all ", "");
                        if (lowerModel.getBaseFare() == fare) {
                            Log.v("  fare  is same ", "");
                            holder.imageItem.setImageResource(lowerModel.getDrawableName(false));
                        } else {
                            Log.v("  fare  is diff ", "");
                            holder.imageItem.setImageResource(lowerModel.getDrawableName(true));
                        }
                    }
                    holder.imageItem.setVisibility(View.VISIBLE);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private int GetCol(int pos) {
        int col = pos % (maxColumn);
        return col;
    }

    private int GetRow(int pos) {
        int row = pos / (maxColumn);
        return row;
    }

    @Override
    public int getItemCount() {
        return maxColumn * maxRow;
    }


    public class MyViewHolder extends RecyclerView.ViewHolder {

        ImageView imageItem;


        public MyViewHolder(View itemView) {
            super(itemView);


            imageItem = (ImageView) itemView.findViewById(R.id.item_image);}
    }
}

This is the recyclerview:

<RelativeLayout
            android:id="@+id/rlRecycler"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:background="#ffffff"
            android:gravity="center">

            <android.support.v7.widget.RecyclerView
                android:id="@+id/rvFareCategory"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_centerHorizontal="true"
                android:background="#ffffff"
                android:paddingBottom="6dip"
                android:paddingTop="8dip"></android.support.v7.widget.RecyclerView>
        </RelativeLayout>

And, seat layout XML:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content">

<ImageView
    android:id="@+id/item_image"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="@null"
    android:padding="4dp"
    android:visibility="invisible"></ImageView>

</RelativeLayout>
Carolyn answered 9/9, 2016 at 12:46 Comment(8)
Post your xml layout code.Yoshi
@jayroider I've updated xml codeCarolyn
Are these rows added dynamically or using this layout itself ?Yoshi
these rows are added dynamically depending on the data. I've passed seatlayout.xml to adapterCarolyn
Could you show me the full code for both Activity and Adapter ?Yoshi
@jaydroider I've updated it please check.Carolyn
A GridLayoutManager can't help you with that layout. What you're looking for is a StaggeredGridLayoutManager which could be easily adapted to replicate the layout(I've made a small example here gist.github.com/luksprog/230c97dfb00d71141e2f3b5b26699e00), another alternative would be a LinearLayoutManager with different row types(where a row will consist of a big seat + space + 4 small seats).Laresa
@Luksprog your code Working perfectly,Post your code as answer gist.github.com/luksprog/230c97dfb00d71141e2f3b5b26699e00Folkmoot
P
0

The problem, of course, arises from the fact that your elements don't have the same height. You need to assign different row spans to the elements. I would suggest assigning the taller elements (the ones on the left) a row span of 2 and 1 for the smaller ones.

I think you could do it with a trick like setting your grid layout manager to have a horizontal orientation and use GridLayoutManager.setSpanSizeLookup(..) to control the span (since yours is horizontal now, the span would act on rows). This would require you to probably rework the logic of getting your elements from the backing array. The alternative would be I am afraid (as far as I know) to implement your own custom layout manager.

Persecution answered 12/9, 2016 at 13:9 Comment(7)
sorry but i'm completely new with GridLayout Manager, how can i Set span size of depending on the rowCarolyn
Let's say position 0 needs to span 2 rows and the rest just one: layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { @Override public int getSpanSize(int position) { if (position == 0) return 2; return 1; } });Persecution
please check I've changed images for better understanding what i want to achieveCarolyn
Looking over this again, I stumbled across StaggeredGridLayoutManager. This should work, given you can control the size of your images.Persecution
i tried StaggeredGridLayout but the layout becomes so messy because there's no empty space was left, so column 1 will not be visibleCarolyn
You can always play with padding and margins for the views, but worst things come, what prevents you from adding invisible views for the space (or use Space)?Persecution
row 3 is starting after row 2 bt i want to omit row 3,0 position as there's no item associated with itCarolyn
G
0

I suggest implementing your recycler view item layout as a TableLayout or a GridLayout, they provide more flexibility in defining row/column spans.

Some useful links:

http://android-pro.blogspot.com.eg/2010/02/table-layout.html https://developer.android.com/guide/topics/ui/layout/grid.html

Gnosticism answered 19/9, 2016 at 9:43 Comment(3)
using TableLayout or GridLayout how can i remove that spacing,I tried using Table and GridLayout bt row 3 was starting after row 2 only, i want to somewhat overlap row 3 on row 2 as shown in image.Carolyn
I'm not sure but maybe you can try to set the items' layout_gravity to topGnosticism
i tried, the layout look same as it, the pic i've shared has gravity top onlyCarolyn

© 2022 - 2024 — McMap. All rights reserved.