≡ Menu

How to Write Android Auto Wrap Layout using Relative Layout

There are 4 kinds of layouts in Android:

  1. Linear – Views can be aligned horizontally or vertically
  2. Relative – Views are located according to the relationship to each other
  3. List View – Views are displayed one by one vertically and scrollable
  4. Grid View – Views are displayed inside a vertical scrollable grid


For these non-scrollable layout, views should not exceed the maximum height/width of the parent view. Sometimes there is a need for autowrap/autobreak layout, in which a view will occupy the next “line” when it reach the border of its parent, as shown in below figure.

Android Auto-wrap Layout

This kind of layout is very useful when working on keypad/remote controller like apps, in which user can define various number of buttons and each button can have different width according to its content. Another benefit of autobreak feature is that there is no need of extra routine/configuration for the handling of different resolution and rotation event.

We can implement such layout based on relative layout with below steps:

  • Walk through all the views and accumulate the width horizontally
  • Mark the head of current “line” and the previous view
  • For each view, compare accumulated width against layout width
    • If there is enough width left for current view, align it to the right of previous view, and update the reference of previous view.
    • If there is not enough width left for current view, align it to the bottom of head view, and update the reference of head view.

Below code implements a simple version of such layout, assuming that buttons is of the same height but different width.

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);
  RelativeLayout layout = (RelativeLayout) findViewById(R.id.main_relative_layout);
  for (int i = 0; i < btns.length; i++) {
    btns[i] = new VKButton(this);
    btns[i].setId(BUTTON_ID_BASE+i);
    layout.addView(btns[i]);	//add button into the layout dynamically
  }
  	layout.post(new Runnable() {	//post a Runnable that call reLayout to layout object
  	@Override
  	public void run() {
  	 reLayout();
  	}
  });
}

protected void reLayout() {
// TODO Auto-generated method stub
  int totalWidth;
  int curWidth;
  int layoutPadX;
  RelativeLayout layout = (RelativeLayout) findViewById(R.id.main_relative_layout);
  int w = layout.getMeasuredWidth();  //get width of current layout
  totalWidth = 0;
  layoutPadX = layout.getPaddingLeft() + layout.getPaddingRight();
  w = w - layoutPadX;
  Button upBtn = null, leftBtn = btns[0];
  for (int i = 0; i < btns.length; i++) {
    //create a layout parameter first
    RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams(
    RelativeLayout.LayoutParams.WRAP_CONTENT,
    RelativeLayout.LayoutParams.WRAP_CONTENT);
    curWidth = btns[i].getMeasuredWidth(); //get the width, beware of the caller site
    if (i > 0) {
      lp.addRule(RelativeLayout.END_OF, btns[i - 1].getId()); //add END_OF property by default.
      if (totalWidth + curWidth > w) {	//check if need to wrap
        upBtn = leftBtn;
        leftBtn = btns[i];
        totalWidth = curWidth;
        lp.removeRule(RelativeLayout.END_OF);   //remove the END_OF for wrap case
      } else {
        totalWidth += curWidth;
      }
      if (upBtn != null)  //add below property for none-first "line"
        lp.addRule(RelativeLayout.BELOW, upBtn.getId());
    } else {
    	totalWidth += curWidth;
    }
    btns[i].setLayoutParams(lp);	//set layout parameter for button
  }
}

Notice that, the calling of getMeasuredWidth inside onCreate will turns out to be 0, so let the layout.post() do the tricky part.

Add your comment

If you enjoyed this article, you might also like..

  1. 50 Linux Sysadmin Tutorials
  2. 50 Most Frequently Used Linux Commands (With Examples)
  3. Top 25 Best Linux Performance Monitoring and Debugging Tools
  4. Mommy, I found it! – 15 Practical Linux Find Command Examples
  5. Linux 101 Hacks 2nd Edition eBook Linux 101 Hacks Book

Bash 101 Hacks Book Sed and Awk 101 Hacks Book Nagios Core 3 Book Vim 101 Hacks Book

Comments on this entry are closed.

  • duskoKoscica March 19, 2014, 1:17 am

    Mhm, the relative and the wrapper?

    Don’t have time to study it now, but very promising!

  • Hari krishna February 23, 2015, 12:11 am

    remove rule needs min 17 version. but my min version was 14.

    i cannot change min version is there any other trick.

  • Ramy February 26, 2016, 11:31 am

    You can use this to remove Rule
    lp.addRule(RelativeLayout.END_OF, 0);