Last active
March 12, 2016 17:02
-
-
Save deveshmittal/e34f95d242a84ded89ef to your computer and use it in GitHub Desktop.
FlowImplementation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| public class FlowLayout extends ViewGroup { | |
| public static final int HORIZONTAL = 0; | |
| public static final int VERTICAL = 1; | |
| private int horizontalSpacing = 0; | |
| private int verticalSpacing = 0; | |
| private int orientation = 0; | |
| private boolean debugDraw = false; | |
| public FlowLayout(Context context) { | |
| super(context); | |
| this.readStyleParameters(context, null); | |
| this.horizontalSpacing = dptopx(15); | |
| this.verticalSpacing = dptopx(10); | |
| } | |
| public FlowLayout(Context context, AttributeSet attributeSet) { | |
| super(context, attributeSet); | |
| this.readStyleParameters(context, attributeSet); | |
| } | |
| public FlowLayout(Context context, AttributeSet attributeSet, int defStyle) { | |
| super(context, attributeSet, defStyle); | |
| this.readStyleParameters(context, attributeSet); | |
| } | |
| private int dptopx(int dp) | |
| { | |
| DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics(); | |
| return (int)((dp * displayMetrics.density) + 0.5); | |
| } | |
| @Override | |
| protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { | |
| int sizeWidth = MeasureSpec.getSize(widthMeasureSpec) - this.getPaddingRight() - this.getPaddingLeft(); | |
| int sizeHeight = MeasureSpec.getSize(heightMeasureSpec) - this.getPaddingRight() - this.getPaddingLeft(); | |
| int modeWidth = MeasureSpec.getMode(widthMeasureSpec); | |
| int modeHeight = MeasureSpec.getMode(heightMeasureSpec); | |
| int size; | |
| int mode; | |
| if (orientation == HORIZONTAL) { | |
| size = sizeWidth; | |
| mode = modeWidth; | |
| } else { | |
| size = sizeHeight; | |
| mode = modeHeight; | |
| } | |
| int lineThicknessWithSpacing = 0; | |
| int lineThickness = 0; | |
| int lineLengthWithSpacing = 0; | |
| int lineLength; | |
| int prevLinePosition = 0; | |
| int controlMaxLength = 0; | |
| int controlMaxThickness = 0; | |
| final int count = getChildCount(); | |
| for (int i = 0; i < count; i++) { | |
| final View child = getChildAt(i); | |
| if (child.getVisibility() == GONE) { | |
| continue; | |
| } | |
| child.measure( | |
| MeasureSpec.makeMeasureSpec(sizeWidth, modeWidth == MeasureSpec.EXACTLY ? MeasureSpec.AT_MOST : modeWidth), | |
| MeasureSpec.makeMeasureSpec(sizeHeight, modeHeight == MeasureSpec.EXACTLY ? MeasureSpec.AT_MOST : modeHeight) | |
| ); | |
| LayoutParams lp = (LayoutParams) child.getLayoutParams(); | |
| int hSpacing = this.getHorizontalSpacing(lp); | |
| int vSpacing = this.getVerticalSpacing(lp); | |
| /* hSpacing = 18; | |
| vSpacing = 13;*/ | |
| int childWidth = child.getMeasuredWidth(); | |
| int childHeight = child.getMeasuredHeight(); | |
| int childLength; | |
| int childThickness; | |
| int spacingLength; | |
| int spacingThickness; | |
| if (orientation == HORIZONTAL) { | |
| childLength = childWidth; | |
| childThickness = childHeight; | |
| spacingLength = hSpacing; | |
| spacingThickness = vSpacing; | |
| } else { | |
| childLength = childHeight; | |
| childThickness = childWidth; | |
| spacingLength = vSpacing; | |
| spacingThickness = hSpacing; | |
| } | |
| lineLength = lineLengthWithSpacing + childLength; | |
| lineLengthWithSpacing = lineLength + spacingLength; | |
| boolean newLine = lp.newLine || (mode != MeasureSpec.UNSPECIFIED && lineLength > size); | |
| if (newLine) { | |
| prevLinePosition = prevLinePosition + lineThicknessWithSpacing; | |
| lineThickness = childThickness; | |
| lineLength = childLength; | |
| lineThicknessWithSpacing = childThickness + spacingThickness; | |
| lineLengthWithSpacing = lineLength + spacingLength; | |
| } | |
| lineThicknessWithSpacing = Math.max(lineThicknessWithSpacing, childThickness + spacingThickness); | |
| lineThickness = Math.max(lineThickness, childThickness); | |
| int posX; | |
| int posY; | |
| if (orientation == HORIZONTAL) { | |
| posX = getPaddingLeft() + lineLength - childLength; | |
| posY = getPaddingTop() + prevLinePosition; | |
| } else { | |
| posX = getPaddingLeft() + prevLinePosition; | |
| posY = getPaddingTop() + lineLength - childHeight; | |
| } | |
| lp.setPosition(posX, posY); | |
| controlMaxLength = Math.max(controlMaxLength, lineLength); | |
| controlMaxThickness = prevLinePosition + lineThickness; | |
| } | |
| /* need to take far side padding into account */ | |
| if (orientation == HORIZONTAL) { | |
| controlMaxLength += getPaddingRight(); | |
| controlMaxThickness += getPaddingBottom(); | |
| } else { | |
| controlMaxLength += getPaddingBottom(); | |
| controlMaxThickness += getPaddingRight(); | |
| } | |
| if (orientation == HORIZONTAL) { | |
| this.setMeasuredDimension(resolveSize(controlMaxLength, widthMeasureSpec), resolveSize(controlMaxThickness, heightMeasureSpec)); | |
| } else { | |
| this.setMeasuredDimension(resolveSize(controlMaxThickness, widthMeasureSpec), resolveSize(controlMaxLength, heightMeasureSpec)); | |
| } | |
| } | |
| private int getVerticalSpacing(LayoutParams lp) { | |
| int vSpacing; | |
| if (lp.verticalSpacingSpecified()) { | |
| vSpacing = lp.verticalSpacing; | |
| } else { | |
| vSpacing = this.verticalSpacing; | |
| } | |
| return vSpacing; | |
| } | |
| private int getHorizontalSpacing(LayoutParams lp) { | |
| int hSpacing; | |
| if (lp.horizontalSpacingSpecified()) { | |
| hSpacing = lp.horizontalSpacing; | |
| } else { | |
| hSpacing = this.horizontalSpacing; | |
| } | |
| return hSpacing; | |
| } | |
| @Override | |
| protected void onLayout(boolean changed, int l, int t, int r, int b) { | |
| final int count = getChildCount(); | |
| for (int i = 0; i < count; i++) { | |
| View child = getChildAt(i); | |
| LayoutParams lp = (LayoutParams) child.getLayoutParams(); | |
| child.layout(lp.x, lp.y, lp.x + child.getMeasuredWidth(), lp.y + child.getMeasuredHeight()); | |
| } | |
| } | |
| @Override | |
| protected boolean drawChild(Canvas canvas, View child, long drawingTime) { | |
| boolean more = super.drawChild(canvas, child, drawingTime); | |
| this.drawDebugInfo(canvas, child); | |
| return more; | |
| } | |
| @Override | |
| protected boolean checkLayoutParams(ViewGroup.LayoutParams p) { | |
| return p instanceof LayoutParams; | |
| } | |
| @Override | |
| protected LayoutParams generateDefaultLayoutParams() { | |
| return new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT); | |
| } | |
| @Override | |
| public LayoutParams generateLayoutParams(AttributeSet attributeSet) { | |
| return new LayoutParams(getContext(), attributeSet); | |
| } | |
| @Override | |
| protected LayoutParams generateLayoutParams(ViewGroup.LayoutParams p) { | |
| return new LayoutParams(p); | |
| } | |
| private void readStyleParameters(Context context, AttributeSet attributeSet) { | |
| TypedArray a = context.obtainStyledAttributes(attributeSet, R.styleable.FlowLayout); | |
| try { | |
| horizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_horizontalSpacing, 0); | |
| verticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_verticalSpacing, 0); | |
| orientation = a.getInteger(R.styleable.FlowLayout_orientation, HORIZONTAL); | |
| debugDraw = a.getBoolean(R.styleable.FlowLayout_debugDraw, false); | |
| } finally { | |
| a.recycle(); | |
| } | |
| } | |
| private void drawDebugInfo(Canvas canvas, View child) { | |
| if (!debugDraw) { | |
| return; | |
| } | |
| Paint childPaint = this.createPaint(0xffffff00); | |
| Paint layoutPaint = this.createPaint(0xff00ff00); | |
| Paint newLinePaint = this.createPaint(0xffff0000); | |
| LayoutParams lp = (LayoutParams) child.getLayoutParams(); | |
| if (lp.horizontalSpacing > 0) { | |
| float x = child.getRight(); | |
| float y = child.getTop() + child.getHeight() / 2.0f; | |
| canvas.drawLine(x, y, x + lp.horizontalSpacing, y, childPaint); | |
| canvas.drawLine(x + lp.horizontalSpacing - 4.0f, y - 4.0f, x + lp.horizontalSpacing, y, childPaint); | |
| canvas.drawLine(x + lp.horizontalSpacing - 4.0f, y + 4.0f, x + lp.horizontalSpacing, y, childPaint); | |
| } else if (this.horizontalSpacing > 0) { | |
| float x = child.getRight(); | |
| float y = child.getTop() + child.getHeight() / 2.0f; | |
| canvas.drawLine(x, y, x + this.horizontalSpacing, y, layoutPaint); | |
| canvas.drawLine(x + this.horizontalSpacing - 4.0f, y - 4.0f, x + this.horizontalSpacing, y, layoutPaint); | |
| canvas.drawLine(x + this.horizontalSpacing - 4.0f, y + 4.0f, x + this.horizontalSpacing, y, layoutPaint); | |
| } | |
| if (lp.verticalSpacing > 0) { | |
| float x = child.getLeft() + child.getWidth() / 2.0f; | |
| float y = child.getBottom(); | |
| canvas.drawLine(x, y, x, y + lp.verticalSpacing, childPaint); | |
| canvas.drawLine(x - 4.0f, y + lp.verticalSpacing - 4.0f, x, y + lp.verticalSpacing, childPaint); | |
| canvas.drawLine(x + 4.0f, y + lp.verticalSpacing - 4.0f, x, y + lp.verticalSpacing, childPaint); | |
| } else if (this.verticalSpacing > 0) { | |
| float x = child.getLeft() + child.getWidth() / 2.0f; | |
| float y = child.getBottom(); | |
| canvas.drawLine(x, y, x, y + this.verticalSpacing, layoutPaint); | |
| canvas.drawLine(x - 4.0f, y + this.verticalSpacing - 4.0f, x, y + this.verticalSpacing, layoutPaint); | |
| canvas.drawLine(x + 4.0f, y + this.verticalSpacing - 4.0f, x, y + this.verticalSpacing, layoutPaint); | |
| } | |
| if (lp.newLine) { | |
| if (orientation == HORIZONTAL) { | |
| float x = child.getLeft(); | |
| float y = child.getTop() + child.getHeight() / 2.0f; | |
| canvas.drawLine(x, y - 6.0f, x, y + 6.0f, newLinePaint); | |
| } else { | |
| float x = child.getLeft() + child.getWidth() / 2.0f; | |
| float y = child.getTop(); | |
| canvas.drawLine(x - 6.0f, y, x + 6.0f, y, newLinePaint); | |
| } | |
| } | |
| } | |
| private Paint createPaint(int color) { | |
| Paint paint = new Paint(); | |
| paint.setAntiAlias(true); | |
| paint.setColor(color); | |
| paint.setStrokeWidth(2.0f); | |
| return paint; | |
| } | |
| public static class LayoutParams extends ViewGroup.LayoutParams { | |
| private static int NO_SPACING = -1; | |
| private int x; | |
| private int y; | |
| private int horizontalSpacing = NO_SPACING; | |
| private int verticalSpacing = NO_SPACING; | |
| private boolean newLine = false; | |
| public LayoutParams(Context context, AttributeSet attributeSet) { | |
| super(context, attributeSet); | |
| this.readStyleParameters(context, attributeSet); | |
| } | |
| public LayoutParams(int width, int height) { | |
| super(width, height); | |
| } | |
| public LayoutParams(ViewGroup.LayoutParams layoutParams) { | |
| super(layoutParams); | |
| } | |
| public boolean horizontalSpacingSpecified() { | |
| return horizontalSpacing != NO_SPACING; | |
| } | |
| public boolean verticalSpacingSpecified() { | |
| return verticalSpacing != NO_SPACING; | |
| } | |
| public void setPosition(int x, int y) { | |
| this.x = x; | |
| this.y = y; | |
| } | |
| private void readStyleParameters(Context context, AttributeSet attributeSet) { | |
| TypedArray a = context.obtainStyledAttributes(attributeSet, R.styleable.FlowLayout_LayoutParams); | |
| try { | |
| horizontalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_LayoutParams_layout_horizontalSpacing, NO_SPACING); | |
| verticalSpacing = a.getDimensionPixelSize(R.styleable.FlowLayout_LayoutParams_layout_verticalSpacing, NO_SPACING); | |
| newLine = a.getBoolean(R.styleable.FlowLayout_LayoutParams_layout_newLine, false); | |
| } finally { | |
| a.recycle(); | |
| } | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| void initFlowButton(String buttonName){ | |
| final FlowLayout spannablelayout = (FlowLayout) rootView | |
| .findViewById(R.id.spannable); | |
| ImageView clearButton = (ImageView) rootView | |
| .findViewById(R.id.clearSearchresults); | |
| clearButton.setVisibility(View.VISIBLE); | |
| ButtonData userButton = new ButtonData(null, buttonName, "", "", false); | |
| Button button = CreateButton(userButton); | |
| button.setTag(userButton); | |
| MarginLayoutParams marginParams = new MarginLayoutParams( | |
| spannablelayout.getLayoutParams()); | |
| marginParams.setMargins(0, 0, 0, 0); | |
| LinearLayout.LayoutParams layoutParams = new LinearLayout.LayoutParams( | |
| marginParams); | |
| button.setOnClickListener(new OnClickListener() { | |
| @Override | |
| public void onClick(final View v) { | |
| spannablelayout.removeView(v); | |
| Button btn = (Button) v; | |
| UpdateSearchTags((ButtonData) btn.getTag(), false); | |
| } | |
| }); | |
| spannablelayout.addView(button, layoutParams); | |
| UpdateSearchTags(userButton, true); | |
| UpdateRecentList(button.getText().toString()); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment