1

i'm new to android and was looking for a wrappanel(wpf) like control. I found a class named FlowLayout (code of this class is at the bottom of my question). I added this class in this folder: MyApp-src-Layouts-FlowLayout.java

In my mylayout.xml, i want to use this layout in another layout:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <com.myapp.FlowLayout
        android:id="@+id/FlowLayout1"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true" >

    </com.myapp.FlowLayout>


</RelativeLayout>

But i get an error: The following classes could not be found: - com.myapp.FlowLayout (Fix Build Path, Edit XML, Create Class)

This is the FlowLayoutClass:

package Layouts;

import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;

public class FlowLayout extends ViewGroup {

    private int line_height;

    public static class LayoutParams extends ViewGroup.LayoutParams {

        public final int horizontal_spacing;
        public final int vertical_spacing;

        /**
         * @param horizontal_spacing Pixels between items, horizontally
         * @param vertical_spacing Pixels between items, vertically
         */
        public LayoutParams(int horizontal_spacing, int vertical_spacing) {
            super(0, 0);
            this.horizontal_spacing = horizontal_spacing;
            this.vertical_spacing = vertical_spacing;
        }
    }

    public FlowLayout(Context context) {
        super(context);
    }

    public FlowLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        assert (MeasureSpec.getMode(widthMeasureSpec) != MeasureSpec.UNSPECIFIED);

        final int width = MeasureSpec.getSize(widthMeasureSpec) - getPaddingLeft() - getPaddingRight();
        int height = MeasureSpec.getSize(heightMeasureSpec) - getPaddingTop() - getPaddingBottom();
        final int count = getChildCount();
        int line_height = 0;

        int xpos = getPaddingLeft();
        int ypos = getPaddingTop();

        int childHeightMeasureSpec;
        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);
        } else {
            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
        }

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                child.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST), childHeightMeasureSpec);
                final int childw = child.getMeasuredWidth();
                line_height = Math.max(line_height, child.getMeasuredHeight() + lp.vertical_spacing);

                if (xpos + childw > width) {
                    xpos = getPaddingLeft();
                    ypos += line_height;
                }

                xpos += childw + lp.horizontal_spacing;
            }
        }
        this.line_height = line_height;

        if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.UNSPECIFIED) {
            height = ypos + line_height;

        } else if (MeasureSpec.getMode(heightMeasureSpec) == MeasureSpec.AT_MOST) {
            if (ypos + line_height < height) {
                height = ypos + line_height;
            }
        }
        setMeasuredDimension(width, height);
    }

    @Override
    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
        return new LayoutParams(1, 1); // default of 1px spacing
    }

    @Override
    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
        if (p instanceof LayoutParams) {
            return true;
        }
        return false;
    }

    @Override
    protected void onLayout(boolean changed, int l, int t, int r, int b) {
        final int count = getChildCount();
        final int width = r - l;
        int xpos = getPaddingLeft();
        int ypos = getPaddingTop();

        for (int i = 0; i < count; i++) {
            final View child = getChildAt(i);
            if (child.getVisibility() != GONE) {
                final int childw = child.getMeasuredWidth();
                final int childh = child.getMeasuredHeight();
                final LayoutParams lp = (LayoutParams) child.getLayoutParams();
                if (xpos + childw > width) {
                    xpos = getPaddingLeft();
                    ypos += line_height;
                }
                child.layout(xpos, ypos, xpos + childw, ypos + childh);
                xpos += childw + lp.horizontal_spacing;
            }
        }
    }

}

What i'm i doing wrong here?

Thanks in advance,

Bjorn

2 Answers2

0

the layout-folder in resources (res) needs an xml-file. Java-classes belong to the src-folder. Compiler cant process it as it is at the moment.

bofredo
  • 2,348
  • 6
  • 32
  • 51
0

The first line of the FlowLayourClass is: package Layouts; so in your xml you should do:

<Layouts.FlowLayoutClass
    android:id="@+id/FlowLayout1"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true" >

</Layouts.FlowLayoutClass>

You should put here your class name preceded by full package name.

Michał Z.
  • 4,119
  • 1
  • 22
  • 32
  • Ok, thx! I don't get the error anymore. Is it normal that i can't drop any other controls on the layout? I mean, when a select a new button and drop it ont hte flowlayout in my outline it turns gray and i get the error: – Bjorn Vdkerckhove Feb 19 '13 at 15:07
  • "" does not set the required layout_width attribute: (1) Set to "wrap_content" (2) Set to "match_parent" "" does not set the required layout_height attribute: (1) Set to "wrap_content" (2) Set to "match_parent" "textView1" does not set the required layout_width attribute: (1) Set to "wrap_content" (2) Set to "match_parent" "textView1" does not set the required layout_height attribute: (1) Set to "wrap_content" (2) Set to "match_parent" Exception raised during rendering: android.view.ViewGroup$LayoutParams cannot be cast to – Bjorn Vdkerckhove Feb 19 '13 at 15:09