Skip to content

Instantly share code, notes, and snippets.

@michaldobrodenka
Created September 17, 2012 11:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michaldobrodenka/3736751 to your computer and use it in GitHub Desktop.
Save michaldobrodenka/3736751 to your computer and use it in GitHub Desktop.
FlowLayout from http://nishantvnair.wordpress.com/2010/09/28/flowlayout-in-android/ ported to c#/Mono for Android
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Util;
using Android.Views;
using Android.Widget;
namespace Bzing.Client.Droid.UserControls
{
public class FlowLayout : ViewGroup
{
private int line_height;
public class LayoutParams : ViewGroup.LayoutParams
{
public readonly int horizontal_spacing;
public readonly int vertical_spacing;
/**
* @param horizontal_spacing Pixels between items, horizontally
* @param vertical_spacing Pixels between items, vertically
*/
public LayoutParams(int horizontalSpacing, int verticalSpacing)
: base(0, 0)
{
this.horizontal_spacing = horizontalSpacing;
this.vertical_spacing = verticalSpacing;
}
}
public FlowLayout(Context context, IAttributeSet attrs) :
base(context, attrs)
{
Initialize();
}
private void Initialize()
{
}
protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
//assert (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED);
int width = MeasureSpec.GetSize(widthMeasureSpec) - PaddingLeft - PaddingRight;
int height = MeasureSpec.GetSize(heightMeasureSpec) - PaddingTop - PaddingBottom;
int count = ChildCount;
int line_height = 0;
int xpos = PaddingLeft;
int ypos = PaddingTop;
int childHeightMeasureSpec;
if (MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.AtMost)
{
childHeightMeasureSpec = MeasureSpec.MakeMeasureSpec(height, MeasureSpecMode.AtMost);
}
else
{
childHeightMeasureSpec = MeasureSpec.MakeMeasureSpec(0, MeasureSpecMode.Unspecified);
}
for (int i = 0; i < count; i++)
{
View child = GetChildAt(i);
if (child.Visibility != ViewStates.Gone)
{
LayoutParams lp = (LayoutParams)child.LayoutParameters;
child.Measure(MeasureSpec.MakeMeasureSpec(width, MeasureSpecMode.AtMost), childHeightMeasureSpec);
int childw = child.MeasuredWidth;
line_height = Math.Max(line_height, child.MeasuredHeight + lp.vertical_spacing);
if (xpos + childw > width)
{
xpos = PaddingLeft;
ypos += line_height;
}
xpos += childw + lp.horizontal_spacing;
}
}
this.line_height = line_height;
if (MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.Unspecified)
{
height = ypos + line_height;
}
else if (MeasureSpec.GetMode(heightMeasureSpec) == MeasureSpecMode.AtMost)
{
if (ypos + line_height < height)
{
height = ypos + line_height;
}
}
SetMeasuredDimension(width, height);
}
protected override ViewGroup.LayoutParams GenerateDefaultLayoutParams()
{
return new LayoutParams(1, 1); // default of 1px spacing
}
protected override bool CheckLayoutParams(ViewGroup.LayoutParams p)
{
if (p is LayoutParams)
{
return true;
}
return false;
}
protected override void OnLayout(bool changed, int l, int t, int r, int b)
{
int count = ChildCount;
int width = r - l;
int xpos = PaddingLeft;
int ypos = PaddingTop;
for (int i = 0; i < count; i++)
{
View child = GetChildAt(i);
if (child.Visibility != ViewStates.Gone)
{
int childw = child.MeasuredWidth;
int childh = child.MeasuredHeight;
LayoutParams lp = (LayoutParams)child.LayoutParameters;
if (xpos + childw > width)
{
xpos = PaddingLeft;
ypos += line_height;
}
child.Layout(xpos, ypos, xpos + childw, ypos + childh);
xpos += childw + lp.horizontal_spacing;
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment