3

I would like to achieve this layout for (n) items list: this layout

So far now I'm able to display the items in two columns but how can I merge two columns in one for specific position (i.e as item 7)?

I have tried many solution provided at SO and also other but none of them worked for me. The solutions provided there were either using LinearLayout inflating static layouts or were providing solution for partition with in the columns.

I've also tried using setSpanLookup method but no luck..

Muahmmad Tayyib
  • 689
  • 11
  • 28
  • 1
    The sugestions are ok, if you want to see a "fake working sample" I had to do it for an Ad-supported grid and so I created a prototype [here](https://github.com/Gryzor/GridToShowAds). More specifically, the "Adapter" that does this is located in the same repo, [here](https://github.com/Gryzor/GridToShowAds/blob/master/app/src/main/java/com/neutobo/recyclerviewwithads/ThingAdapterWithAds.kt). All that being said, I used a GridLayout, not the staggered version. – Martin Marconcini Jul 01 '19 at 10:47
  • @MartinMarconcini i've tried your code and works fine.. but look at my solution also.this sound more optimal. i think.. whats your thoughts about that... – Muahmmad Tayyib Jul 01 '19 at 10:54
  • 1
    I see it; I'm not a big fan to be honest. You're touching layout params by hand and delegating the responsibility of what to display to your activity. If it works for you, that's fine, but I wouldn't rely on "view attached to window" to decide what/how to show something. I don't know, maybe others see that and think it's fine; I wouldn't have thought of using that method; this is a presentation problem. In your example, you're putting your Business Logic in a lifecycle method, not easy to test, not easy to change, not easy to find or to expand, etc. /shrug – Martin Marconcini Jul 01 '19 at 11:22

3 Answers3

4

Finally the solution that worked for me after exhaustive struggle is here:

    @Override
        public void onViewAttachedToWindow(MyViewHolder holder) {
            super.onViewAttachedToWindow(holder);
            ViewGroup.LayoutParams lp = holder.itemView.getLayoutParams();
            if(lp != null
                    && lp instanceof StaggeredGridLayoutManager.LayoutParams
                    && (holder.getLayoutPosition() == 6 || holder.getLayoutPosition() == 13)) {
                StaggeredGridLayoutManager.LayoutParams p = (StaggeredGridLayoutManager.LayoutParams) lp;
                p.setFullSpan(true);
            }
           holder.setIsRecyclable(false);
        }

Hope this will help u also.

Muahmmad Tayyib
  • 689
  • 11
  • 28
1

As you said, setSpanLookup is the best method, I think.

Try this code:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val layoutManager = GridLayoutManager(this, 2)
        layoutManager.spanSizeLookup = object : GridLayoutManager.SpanSizeLookup() {
            override fun getSpanSize(position: Int): Int {
                if (position == 6 || position == 13) return 2
                else return 1
            }
        }
        rv.layoutManager = layoutManager

        val items = mutableListOf<String>()
        for (i in 1..14) {
            items.add("item$i")
        }
        rv.adapter = MyAdapter(items)
    }
}

You need to know the value getSpanSize returned means weight, not column count.

In terms of item layout, you can use different ViewHolder in special position.

For example:

companion object{
    const val NORMAL = 0
    const val WIDE = 1
}

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): Holder {
    ...
    if (viewType == WIDE) return WideViewHolder(wideView)
    else return NormalViewHolder(normalView)
}

override fun getItemViewType(position: Int): Int {
    if (position == 6 || position == 13) {
        return WIDE
    }
    return NORMAL
}
Kevin
  • 139
  • 6
0

Just create a table : In your case is is 8 rows and 3 columns, set the borderline and border alignment, item 7 and 14 will take 3 cells. Here an example :

private void insertCell(PdfPTable table, String text, int align, int colspan, Font font) {

    //create a new cell with the specified Text and Font
    PdfPCell cell = new PdfPCell(new Phrase(text.trim(), font));
    //set the cell alignment
    cell.setHorizontalAlignment(align);
    //set the cell column span in case you want to merge two or more cells
    cell.setColspan(colspan);
    //in case there is no text and you wan to create an empty row
    if (text.trim().equalsIgnoreCase("")) {
        cell.setMinimumHeight(10f);
    }
    //add the call to the table
    table.addCell(cell);
}
alan
  • 48
  • 1
  • 13