Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spannable RecyclerView like Snapchat-Discover

Im trying to create a spannable recyclerView like the following image using the TwoWayView library: https://github.com/lucasr/twoway-view

But I'm unable to get the desired view and there are empty cells being left out.

        final SpannableGridLayoutManager.LayoutParams lp = (SpannableGridLayoutManager.LayoutParams) itemView.getLayoutParams();

        //final int span1 = (itemId == 0 || itemId == 3 ? 2 : 1);
        //final int span2 = (itemId == 0 ? 2 : (itemId == 3 ? 3 : 1));

        int span1 = 0; //h
        int span2 = 0; //w

        switch(itemId)
        {
        case 0:
            span1 = 2;
            span2 = 1;
            break;

        case 1:
            span1 = 2;
            span2 = 1;
            break;

        case 2:
            span1 = 2;
            span2 = 1;
            break;

        case 3:
            span1 = 3;
            span2 = 1;
            break;

        case 4:
            span1 = 3;
            span2 = 1;
            break;

        case 5:
            span1 = 4;
            span2 = 3;
            break;

        case 6:
            span1 = 2;
            span2 = 1;
            break;

        case 7:
            span1 = 2;
            span2 = 1;
            break;

        case 8:
            span1 = 2;
            span2 = 1;
            break;

        case 9:
            span1 = 2;
            span2 = 1;
            break;

        case 10:
            span1 = 4;
            span2 = 3;
            break;
        }

        final int colSpan = span2;
        final int rowSpan = span1;

        if (lp.rowSpan != rowSpan || lp.colSpan != colSpan) 
        {
            lp.rowSpan = rowSpan;
            lp.colSpan = colSpan;
            itemView.setLayoutParams(lp);
        }

XML:

<org.lucasr.twowayview.widget.TwoWayView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:id="@+id/list"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    style="@style/TwoWayView"
    app:twowayview_layoutManager="ListLayoutManager"/>

Ref: enter image description here

Edit 1 I was able to solve this by changing the rowWidth to 12 in the XML and the following spans:

        //PADDING-- left / top / right / bottom
    switch(itemId%11)
    {
    case 0:
        span1 = 4;
        span2 = 7;
        //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
        break;

    case 1:
        span1 = 4;
        span2 = 7;
        //holder.cont_frienddetail.setPadding(dpAsPixels2, dpAsPixels1, dpAsPixels2, dpAsPixels1);
        break;

    case 2:
        span1 = 4;
        span2 = 7;
        //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
        break;

    case 3:
        span1 = 4;
        span2 = 7;
        //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
        break;

    case 4:
        span1 = 8;
        span2 = 14;
        //holder.cont_frienddetail.setPadding(dpAsPixels2, dpAsPixels1, dpAsPixels0, dpAsPixels1);
        break;

    case 5:
        span1 = 4;
        span2 = 7;
        //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
        break;

    case 6:
        span1 = 6;
        span2 = 10;
        //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels2, dpAsPixels1);
        break;

    case 7:
        span1 = 6;
        span2 = 10;
        //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
        break;

    case 8:
        span1 = 8;
        span2 = 14;
        //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels2, dpAsPixels1);
        break;

    case 9:
        span1 = 4;
        span2 = 7;
        ///holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
        break;

    case 10:
        span1 = 4;
        span2 = 7;
        //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
        break;
    }
like image 362
Zen Avatar asked Aug 28 '16 19:08

Zen


2 Answers

Imagine taking your example image and extending the vertical boundary of each cell through the entire screen. If you did that, you'd see that there are six columns. And that is the insight that will solve your problem.

Now you can do this with a regular RecyclerView and GridLayoutManager, and not have to depend on somebody fixing all the bugs in their GitHub library.

Create a GridLayoutManager with 6 columns, then specify a custom SpanSizeLookup that will make your cells different widths.

In your example image, the three cells in the first row would span 2 columns each. The two larger cells in the second row span 3 columns each. The bottom left cell spans 4 columns.

So now all you have to do is create a SpanSizeLookup that will set the correct widths.

    // Create a grid layout with 6 columns
    // (least common multiple of 2 and 3)
    GridLayoutManager layoutManager = new GridLayoutManager(this, 6);

    layoutManager.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() {
        @Override
        public int getSpanSize(int position) {

            int widthClass = determineWidth(position) // TODO here you figure out what the cell width should be

            switch (widthClass) {
            case SMALL:
                return 2;   // fits 3 per row

            case MEDIUM:
                return 3;   // fits 2 per row

            case LARGE:     // fits 2 per row, one LARGE and one SMALL
                return 4;

            default:
                throw new IllegalStateException("don\'t know about widthClass " + widthClass);
            }
        }
    });

You can view my original answer to a similar question here.

like image 117
kris larson Avatar answered Sep 28 '22 05:09

kris larson


I was able to solve this by changing the rowWidth to 12 in the XML and the following spans:

        //PADDING-- left / top / right / bottom
switch(itemId%11)
{
case 0:
    span1 = 4;
    span2 = 7;
    //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
    break;

case 1:
    span1 = 4;
    span2 = 7;
    //holder.cont_frienddetail.setPadding(dpAsPixels2, dpAsPixels1, dpAsPixels2, dpAsPixels1);
    break;

case 2:
    span1 = 4;
    span2 = 7;
    //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
    break;

case 3:
    span1 = 4;
    span2 = 7;
    //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
    break;

case 4:
    span1 = 8;
    span2 = 14;
    //holder.cont_frienddetail.setPadding(dpAsPixels2, dpAsPixels1, dpAsPixels0, dpAsPixels1);
    break;

case 5:
    span1 = 4;
    span2 = 7;
    //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
    break;

case 6:
    span1 = 6;
    span2 = 10;
    //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels2, dpAsPixels1);
    break;

case 7:
    span1 = 6;
    span2 = 10;
    //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
    break;

case 8:
    span1 = 8;
    span2 = 14;
    //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels2, dpAsPixels1);
    break;

case 9:
    span1 = 4;
    span2 = 7;
    ///holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
    break;

case 10:
    span1 = 4;
    span2 = 7;
    //holder.cont_frienddetail.setPadding(dpAsPixels0, dpAsPixels1, dpAsPixels0, dpAsPixels1);
    break;
}
like image 42
Zen Avatar answered Sep 28 '22 04:09

Zen